--- /dev/null
+From 1b79cd04fab80be61dcd2732e2423aafde9a4c1c Mon Sep 17 00:00:00 2001
+From: Junjiro R. Okajima <hooanon05@yahoo.co.jp>
+Date: Tue, 2 Dec 2008 10:31:46 -0800
+Subject: nfsd: fix vm overcommit crash fix #2
+
+From: Junjiro R. Okajima <hooanon05@yahoo.co.jp>
+
+commit 1b79cd04fab80be61dcd2732e2423aafde9a4c1c upstream.
+
+The previous patch from Alan Cox ("nfsd: fix vm overcommit crash",
+commit 731572d39fcd3498702eda4600db4c43d51e0b26) fixed the problem where
+knfsd crashes on exported shmemfs objects and strict overcommit is set.
+
+But the patch forgot supporting the case when CONFIG_SECURITY is
+disabled.
+
+This patch copies a part of his fix which is mainly for detecting a bug
+earlier.
+
+Acked-by: James Morris <jmorris@namei.org>
+Signed-off-by: Alan Cox <alan@redhat.com>
+Signed-off-by: Junjiro R. Okajima <hooanon05@yahoo.co.jp>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/linux/security.h | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/include/linux/security.h
++++ b/include/linux/security.h
+@@ -1823,17 +1823,21 @@ static inline int security_settime(struc
+
+ static inline int security_vm_enough_memory(long pages)
+ {
++ WARN_ON(current->mm == NULL);
+ return cap_vm_enough_memory(current->mm, pages);
+ }
+
+-static inline int security_vm_enough_memory_kern(long pages)
++static inline int security_vm_enough_memory_mm(struct mm_struct *mm, long pages)
+ {
+- return cap_vm_enough_memory(current->mm, pages);
++ WARN_ON(mm == NULL);
++ return cap_vm_enough_memory(mm, pages);
+ }
+
+-static inline int security_vm_enough_memory_mm(struct mm_struct *mm, long pages)
++static inline int security_vm_enough_memory_kern(long pages)
+ {
+- return cap_vm_enough_memory(mm, pages);
++ /* If current->mm is a kernel thread then we will pass NULL,
++ for this specific case that is fine */
++ return cap_vm_enough_memory(current->mm, pages);
+ }
+
+ static inline int security_bprm_alloc(struct linux_binprm *bprm)
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ include/linux/security.h | 6 ++++++
+ mm/mmap.c | 3 ++-
+ mm/nommu.c | 3 ++-
+ mm/shmem.c | 8 ++++----
+ security/security.c | 9 +++++++++
+ 5 files changed, 23 insertions(+), 6 deletions(-)
+
--- a/include/linux/security.h
+++ b/include/linux/security.h
-@@ -1585,6 +1585,7 @@ int security_syslog(int type);
+@@ -1590,6 +1590,7 @@ int security_syslog(int type);
int security_settime(struct timespec *ts, struct timezone *tz);
int security_vm_enough_memory(long pages);
int security_vm_enough_memory_mm(struct mm_struct *mm, long pages);
int security_bprm_alloc(struct linux_binprm *bprm);
void security_bprm_free(struct linux_binprm *bprm);
void security_bprm_apply_creds(struct linux_binprm *bprm, int unsafe);
-@@ -1820,6 +1821,11 @@ static inline int security_vm_enough_memory(long pages)
+@@ -1824,6 +1825,11 @@ static inline int security_vm_enough_mem
+ {
return cap_vm_enough_memory(current->mm, pages);
}
-
++
+static inline int security_vm_enough_memory_kern(long pages)
+{
+ return cap_vm_enough_memory(current->mm, pages);
+}
-+
+
static inline int security_vm_enough_memory_mm(struct mm_struct *mm, long pages)
{
- return cap_vm_enough_memory(mm, pages);
-diff --git a/mm/mmap.c b/mm/mmap.c
-index 74f4d15..de14ac2 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
-@@ -175,7 +175,8 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin)
+@@ -178,7 +178,8 @@ int __vm_enough_memory(struct mm_struct
/* Don't let a single process grow too big:
leave 3% of the size of this process for other processes */
/*
* cast `allowed' as a signed long because vm_committed_space
-diff --git a/mm/nommu.c b/mm/nommu.c
-index 2696b24..7695dc8 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
-@@ -1454,7 +1454,8 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin)
+@@ -1432,7 +1432,8 @@ int __vm_enough_memory(struct mm_struct
/* Don't let a single process grow too big:
leave 3% of the size of this process for other processes */
/*
* cast `allowed' as a signed long because vm_committed_space
-diff --git a/mm/shmem.c b/mm/shmem.c
-index d38d7e6..0ed0752 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
-@@ -161,8 +161,8 @@ static inline struct shmem_sb_info *SHMEM_SB(struct super_block *sb)
+@@ -163,8 +163,8 @@ static inline struct shmem_sb_info *SHME
*/
static inline int shmem_acct_size(unsigned long flags, loff_t size)
{
}
static inline void shmem_unacct_size(unsigned long flags, loff_t size)
-@@ -179,8 +179,8 @@ static inline void shmem_unacct_size(unsigned long flags, loff_t size)
+@@ -181,8 +181,8 @@ static inline void shmem_unacct_size(uns
*/
static inline int shmem_acct_block(unsigned long flags)
{
}
static inline void shmem_unacct_blocks(unsigned long flags, long pages)
-diff --git a/security/security.c b/security/security.c
-index 255b085..c0acfa7 100644
--- a/security/security.c
+++ b/security/security.c
-@@ -198,14 +198,23 @@ int security_settime(struct timespec *ts, struct timezone *tz)
+@@ -195,14 +195,23 @@ int security_settime(struct timespec *ts
int security_vm_enough_memory(long pages)
{