@@ -1277,6 +1277,31 @@ int cred_task_has_perm(const struct cred *cred, const struct task_struct *p,
return 0;
}
+int cred_has_extended_perms(const struct cred *cred, u32 tsid, u16 tclass,
+ u32 requested, u8 driver, u8 xperm,
+ struct common_audit_data *ad)
+{
+ struct task_security_struct *tsec;
+ struct selinux_state *state;
+ u32 ssid;
+ int rc;
+
+ do {
+ tsec = selinux_cred(cred);
+ ssid = tsec->sid;
+ state = tsec->state;
+
+ rc = avc_has_extended_perms(state, ssid, tsid, tclass,
+ requested, driver, xperm, ad);
+ if (rc)
+ return rc;
+
+ cred = tsec->parent_cred;
+ } while (cred);
+
+ return 0;
+}
+
u32 avc_policy_seqno(struct selinux_state *state)
{
return state->avc->avc_cache.latest_notif;
@@ -3768,9 +3768,8 @@ static int ioctl_has_perm(const struct cred *cred, struct file *file,
return 0;
isec = inode_security(inode);
- rc = avc_has_extended_perms(cred_selinux_state(cred),
- ssid, isec->sid, isec->sclass,
- requested, driver, xperm, &ad);
+ rc = cred_has_extended_perms(cred, isec->sid, isec->sclass,
+ requested, driver, xperm, &ad);
out:
return rc;
}
@@ -148,6 +148,10 @@ int cred_task_has_perm(const struct cred *cred, const struct task_struct *p,
u16 tclass, u32 requested,
struct common_audit_data *auditdata);
+int cred_has_extended_perms(const struct cred *cred, u32 tsid, u16 tclass,
+ u32 requested, u8 driver, u8 xperm,
+ struct common_audit_data *ad);
+
u32 avc_policy_seqno(struct selinux_state *state);
#define AVC_CALLBACK_GRANT 1
Introduce cred_has_extended_perms() to check extended permissions against the current SELinux namespace and all ancestor namespaces. Update the caller of avc_has_extended_perms() to use this function instead. Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com> --- security/selinux/avc.c | 25 +++++++++++++++++++++++++ security/selinux/hooks.c | 5 ++--- security/selinux/include/avc.h | 4 ++++ 3 files changed, 31 insertions(+), 3 deletions(-)