diff options
author | Alan Cox | 2007-08-22 14:01:28 -0700 |
---|---|---|
committer | Linus Torvalds | 2007-08-22 19:52:45 -0700 |
commit | 34b4e4aa3c470ce8fa2bd78abb1741b4b58baad7 (patch) | |
tree | 91d620288f1aaf63c12dc84ca1015465818601f2 /security | |
parent | afe1ab4d577892822de2c8e803fbfaed6ec44ba3 (diff) |
fix NULL pointer dereference in __vm_enough_memory()
The new exec code inserts an accounted vma into an mm struct which is not
current->mm. The existing memory check code has a hard coded assumption
that this does not happen as does the security code.
As the correct mm is known we pass the mm to the security method and the
helper function. A new security test is added for the case where we need
to pass the mm and the existing one is modified to pass current->mm to
avoid the need to change large amounts of code.
(Thanks to Tobias for fixing rejects and testing)
Signed-off-by: Alan Cox <alan@redhat.com>
Cc: WU Fengguang <wfg@mail.ustc.edu.cn>
Cc: James Morris <jmorris@redhat.com>
Cc: Tobias Diedrich <ranma+kernel@tdiedrich.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'security')
-rw-r--r-- | security/commoncap.c | 4 | ||||
-rw-r--r-- | security/dummy.c | 4 | ||||
-rw-r--r-- | security/selinux/hooks.c | 4 |
3 files changed, 6 insertions, 6 deletions
diff --git a/security/commoncap.c b/security/commoncap.c index 338606eb7238..7520361663e8 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -315,13 +315,13 @@ int cap_syslog (int type) return 0; } -int cap_vm_enough_memory(long pages) +int cap_vm_enough_memory(struct mm_struct *mm, long pages) { int cap_sys_admin = 0; if (cap_capable(current, CAP_SYS_ADMIN) == 0) cap_sys_admin = 1; - return __vm_enough_memory(pages, cap_sys_admin); + return __vm_enough_memory(mm, pages, cap_sys_admin); } EXPORT_SYMBOL(cap_capable); diff --git a/security/dummy.c b/security/dummy.c index 19d813d5e083..853ec2292798 100644 --- a/security/dummy.c +++ b/security/dummy.c @@ -108,13 +108,13 @@ static int dummy_settime(struct timespec *ts, struct timezone *tz) return 0; } -static int dummy_vm_enough_memory(long pages) +static int dummy_vm_enough_memory(struct mm_struct *mm, long pages) { int cap_sys_admin = 0; if (dummy_capable(current, CAP_SYS_ADMIN) == 0) cap_sys_admin = 1; - return __vm_enough_memory(pages, cap_sys_admin); + return __vm_enough_memory(mm, pages, cap_sys_admin); } static int dummy_bprm_alloc_security (struct linux_binprm *bprm) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 6237933f7d82..d8bc4172819c 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -1584,7 +1584,7 @@ static int selinux_syslog(int type) * Do not audit the selinux permission check, as this is applied to all * processes that allocate mappings. */ -static int selinux_vm_enough_memory(long pages) +static int selinux_vm_enough_memory(struct mm_struct *mm, long pages) { int rc, cap_sys_admin = 0; struct task_security_struct *tsec = current->security; @@ -1600,7 +1600,7 @@ static int selinux_vm_enough_memory(long pages) if (rc == 0) cap_sys_admin = 1; - return __vm_enough_memory(pages, cap_sys_admin); + return __vm_enough_memory(mm, pages, cap_sys_admin); } /* binprm security operations */ |