summaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
authorStephen Smalley <sds@tycho.nsa.gov>2017-02-28 09:35:08 -0500
committerJames Morris <james.l.morris@oracle.com>2017-03-06 10:44:16 +1100
commit84e6885e9e6a818d1ca1eabb9b720b357ab07a8b (patch)
tree41b2481cd1f1f6c4ee2d2305a0f8114115cb0e34 /security/selinux
parent791ec491c372f49cea3ea7a7143454a9023ac9d4 (diff)
downloadlinux-stable-84e6885e9e6a818d1ca1eabb9b720b357ab07a8b.tar.gz
linux-stable-84e6885e9e6a818d1ca1eabb9b720b357ab07a8b.tar.bz2
linux-stable-84e6885e9e6a818d1ca1eabb9b720b357ab07a8b.zip
selinux: fix kernel BUG on prlimit(..., NULL, NULL)
commit 79bcf325e6b32b3c ("prlimit,security,selinux: add a security hook for prlimit") introduced a security hook for prlimit() and implemented it for SELinux. However, if prlimit() is called with NULL arguments for both the new limit and the old limit, then the hook is called with 0 for the read/write flags, since the prlimit() will neither read nor write the process' limits. This would in turn lead to calling avc_has_perm() with 0 for the requested permissions, which triggers a BUG_ON() in avc_has_perm_noaudit() since the kernel should never be invoking avc_has_perm() with no permissions. Fix this in the SELinux hook by returning immediately if the flags are 0. Arguably prlimit64() itself ought to return immediately if both old_rlim and new_rlim are NULL since it is effectively a no-op in that case. Reported by the lkp-robot based on trinity testing. Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> Acked-by: Paul Moore <paul@paul-moore.com> Signed-off-by: James Morris <james.l.morris@oracle.com>
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/hooks.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 870d24ecc2de..3ba5ce1f4e05 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3925,6 +3925,8 @@ int selinux_task_prlimit(const struct cred *cred, const struct cred *tcred,
{
u32 av = 0;
+ if (!flags)
+ return 0;
if (flags & LSM_PRLIMIT_WRITE)
av |= PROCESS__SETRLIMIT;
if (flags & LSM_PRLIMIT_READ)