Switch the selinux_lsm_setattr() checks to only check against the current SELinux namespace because this operation only changes the SID in the current namespace. Signed-off-by: Stephen Smalley <stephen.smalley.work@xxxxxxxxx> --- security/selinux/hooks.c | 44 ++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 5730138d4eb8..d9a1d2e075a8 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6560,35 +6560,41 @@ static int selinux_lsm_getattr(unsigned int attr, struct task_struct *p, static int selinux_lsm_setattr(u64 attr, void *value, size_t size) { const struct cred *cred = current_cred(); + struct selinux_state *state = current_selinux_state; struct task_security_struct *tsec; struct cred *new; - u32 sid = 0, ptsid; + u32 mysid = current_sid(), sid = 0, ptsid; int error; char *str = value; /* * Basic control over ability to set these attributes at all. */ + /* + * Only check against the current SELinux namespace + * because only the SID in the current namespace + * is changed by this operation. + */ switch (attr) { case LSM_ATTR_EXEC: - error = cred_self_has_perm(cred, SECCLASS_PROCESS, - PROCESS__SETEXEC, NULL); + error = avc_has_perm(state, mysid, mysid, SECCLASS_PROCESS, + PROCESS__SETEXEC, NULL); break; case LSM_ATTR_FSCREATE: - error = cred_self_has_perm(cred, SECCLASS_PROCESS, - PROCESS__SETFSCREATE, NULL); + error = avc_has_perm(state, mysid, mysid, SECCLASS_PROCESS, + PROCESS__SETFSCREATE, NULL); break; case LSM_ATTR_KEYCREATE: - error = cred_self_has_perm(cred, SECCLASS_PROCESS, - PROCESS__SETKEYCREATE, NULL); + error = avc_has_perm(state, mysid, mysid, SECCLASS_PROCESS, + PROCESS__SETKEYCREATE, NULL); break; case LSM_ATTR_SOCKCREATE: - error = cred_self_has_perm(cred, SECCLASS_PROCESS, - PROCESS__SETSOCKCREATE, NULL); + error = avc_has_perm(state, mysid, mysid, SECCLASS_PROCESS, + PROCESS__SETSOCKCREATE, NULL); break; case LSM_ATTR_CURRENT: - error = cred_self_has_perm(cred, SECCLASS_PROCESS, - PROCESS__SETCURRENT, NULL); + error = avc_has_perm(state, mysid, mysid, SECCLASS_PROCESS, + PROCESS__SETCURRENT, NULL); break; default: error = -EOPNOTSUPP; @@ -6603,7 +6609,7 @@ static int selinux_lsm_setattr(u64 attr, void *value, size_t size) str[size-1] = 0; size--; } - error = security_context_to_sid(current_selinux_state, value, size, + error = security_context_to_sid(state, value, size, &sid, GFP_KERNEL); if (error == -EINVAL && attr == LSM_ATTR_FSCREATE) { if (!has_cap_mac_admin(true)) { @@ -6629,9 +6635,8 @@ static int selinux_lsm_setattr(u64 attr, void *value, size_t size) return error; } - error = security_context_to_sid_force( - current_selinux_state, - value, size, &sid); + error = security_context_to_sid_force(state, value, + size, &sid); } if (error) return error; @@ -6668,7 +6673,7 @@ static int selinux_lsm_setattr(u64 attr, void *value, size_t size) goto abort_change; if (!current_is_single_threaded()) { - error = security_bounded_transition(current_selinux_state, + error = security_bounded_transition(state, tsec->sid, sid); if (error) goto abort_change; @@ -6680,8 +6685,7 @@ static int selinux_lsm_setattr(u64 attr, void *value, size_t size) * because only the SID in the current namespace * is changed by a transition. */ - error = avc_has_perm(current_selinux_state, - tsec->sid, sid, SECCLASS_PROCESS, + error = avc_has_perm(state, tsec->sid, sid, SECCLASS_PROCESS, PROCESS__DYNTRANSITION, NULL); if (error) goto abort_change; @@ -6695,8 +6699,8 @@ static int selinux_lsm_setattr(u64 attr, void *value, size_t size) * because only the SID in the current namespace * is changed by a transition. */ - error = avc_has_perm(current_selinux_state, - ptsid, sid, SECCLASS_PROCESS, + error = avc_has_perm(state, ptsid, sid, + SECCLASS_PROCESS, PROCESS__PTRACE, NULL); if (error) goto abort_change; -- 2.47.1