diff options
author | Konstantin Khlebnikov <koct9i@gmail.com> | 2016-02-02 19:57:43 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-02-03 11:28:43 -0500 |
commit | d977d56ce5b3e8842236f2f9e7483d4914c9592e (patch) | |
tree | 179e5850a0567927d38e34a96747d53415b535b3 /mm | |
parent | 4758e198ad3bcbc1c468e0632c53a63a7d201649 (diff) |
mm: warn about VmData over RLIMIT_DATA
This patch provides a way of working around a slight regression
introduced by commit 84638335900f ("mm: rework virtual memory
accounting").
Before that commit RLIMIT_DATA have control only over size of the brk
region. But that change have caused problems with all existing versions
of valgrind, because it set RLIMIT_DATA to zero.
This patch fixes rlimit check (limit actually in bytes, not pages) and
by default turns it into warning which prints at first VmData misuse:
"mmap: top (795): VmData 516096 exceed data ulimit 512000. Will be forbidden soon."
Behavior is controlled by boot param ignore_rlimit_data=y/n and by sysfs
/sys/module/kernel/parameters/ignore_rlimit_data. For now it set to "y".
[akpm@linux-foundation.org: tweak kernel-parameters.txt text[
Signed-off-by: Konstantin Khlebnikov <koct9i@gmail.com>
Link: http://lkml.kernel.org/r/20151228211015.GL2194@uranus
Reported-by: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Cyrill Gorcunov <gorcunov@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Vegard Nossum <vegard.nossum@oracle.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Vladimir Davydov <vdavydov@virtuozzo.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Quentin Casasnovas <quentin.casasnovas@oracle.com>
Cc: Kees Cook <keescook@google.com>
Cc: Willy Tarreau <w@1wt.eu>
Cc: Pavel Emelyanov <xemul@virtuozzo.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/internal.h | 16 | ||||
-rw-r--r-- | mm/mmap.c | 23 |
2 files changed, 33 insertions, 6 deletions
diff --git a/mm/internal.h b/mm/internal.h index ed8b5ffcf9b1..6e976302ddd8 100644 --- a/mm/internal.h +++ b/mm/internal.h | |||
@@ -216,6 +216,22 @@ static inline bool is_cow_mapping(vm_flags_t flags) | |||
216 | return (flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE; | 216 | return (flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE; |
217 | } | 217 | } |
218 | 218 | ||
219 | static inline bool is_exec_mapping(vm_flags_t flags) | ||
220 | { | ||
221 | return (flags & (VM_EXEC | VM_WRITE)) == VM_EXEC; | ||
222 | } | ||
223 | |||
224 | static inline bool is_stack_mapping(vm_flags_t flags) | ||
225 | { | ||
226 | return (flags & (VM_STACK_FLAGS & (VM_GROWSUP | VM_GROWSDOWN))) != 0; | ||
227 | } | ||
228 | |||
229 | static inline bool is_data_mapping(vm_flags_t flags) | ||
230 | { | ||
231 | return (flags & ((VM_STACK_FLAGS & (VM_GROWSUP | VM_GROWSDOWN)) | | ||
232 | VM_WRITE | VM_SHARED)) == VM_WRITE; | ||
233 | } | ||
234 | |||
219 | /* mm/util.c */ | 235 | /* mm/util.c */ |
220 | void __vma_link_list(struct mm_struct *mm, struct vm_area_struct *vma, | 236 | void __vma_link_list(struct mm_struct *mm, struct vm_area_struct *vma, |
221 | struct vm_area_struct *prev, struct rb_node *rb_parent); | 237 | struct vm_area_struct *prev, struct rb_node *rb_parent); |
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/memory.h> | 42 | #include <linux/memory.h> |
43 | #include <linux/printk.h> | 43 | #include <linux/printk.h> |
44 | #include <linux/userfaultfd_k.h> | 44 | #include <linux/userfaultfd_k.h> |
45 | #include <linux/moduleparam.h> | ||
45 | 46 | ||
46 | #include <asm/uaccess.h> | 47 | #include <asm/uaccess.h> |
47 | #include <asm/cacheflush.h> | 48 | #include <asm/cacheflush.h> |
@@ -69,6 +70,8 @@ const int mmap_rnd_compat_bits_max = CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX; | |||
69 | int mmap_rnd_compat_bits __read_mostly = CONFIG_ARCH_MMAP_RND_COMPAT_BITS; | 70 | int mmap_rnd_compat_bits __read_mostly = CONFIG_ARCH_MMAP_RND_COMPAT_BITS; |
70 | #endif | 71 | #endif |
71 | 72 | ||
73 | static bool ignore_rlimit_data = true; | ||
74 | core_param(ignore_rlimit_data, ignore_rlimit_data, bool, 0644); | ||
72 | 75 | ||
73 | static void unmap_region(struct mm_struct *mm, | 76 | static void unmap_region(struct mm_struct *mm, |
74 | struct vm_area_struct *vma, struct vm_area_struct *prev, | 77 | struct vm_area_struct *vma, struct vm_area_struct *prev, |
@@ -2982,9 +2985,17 @@ bool may_expand_vm(struct mm_struct *mm, vm_flags_t flags, unsigned long npages) | |||
2982 | if (mm->total_vm + npages > rlimit(RLIMIT_AS) >> PAGE_SHIFT) | 2985 | if (mm->total_vm + npages > rlimit(RLIMIT_AS) >> PAGE_SHIFT) |
2983 | return false; | 2986 | return false; |
2984 | 2987 | ||
2985 | if ((flags & (VM_WRITE | VM_SHARED | (VM_STACK_FLAGS & | 2988 | if (is_data_mapping(flags) && |
2986 | (VM_GROWSUP | VM_GROWSDOWN)))) == VM_WRITE) | 2989 | mm->data_vm + npages > rlimit(RLIMIT_DATA) >> PAGE_SHIFT) { |
2987 | return mm->data_vm + npages <= rlimit(RLIMIT_DATA); | 2990 | if (ignore_rlimit_data) |
2991 | pr_warn_once("%s (%d): VmData %lu exceed data ulimit " | ||
2992 | "%lu. Will be forbidden soon.\n", | ||
2993 | current->comm, current->pid, | ||
2994 | (mm->data_vm + npages) << PAGE_SHIFT, | ||
2995 | rlimit(RLIMIT_DATA)); | ||
2996 | else | ||
2997 | return false; | ||
2998 | } | ||
2988 | 2999 | ||
2989 | return true; | 3000 | return true; |
2990 | } | 3001 | } |
@@ -2993,11 +3004,11 @@ void vm_stat_account(struct mm_struct *mm, vm_flags_t flags, long npages) | |||
2993 | { | 3004 | { |
2994 | mm->total_vm += npages; | 3005 | mm->total_vm += npages; |
2995 | 3006 | ||
2996 | if ((flags & (VM_EXEC | VM_WRITE)) == VM_EXEC) | 3007 | if (is_exec_mapping(flags)) |
2997 | mm->exec_vm += npages; | 3008 | mm->exec_vm += npages; |
2998 | else if (flags & (VM_STACK_FLAGS & (VM_GROWSUP | VM_GROWSDOWN))) | 3009 | else if (is_stack_mapping(flags)) |
2999 | mm->stack_vm += npages; | 3010 | mm->stack_vm += npages; |
3000 | else if ((flags & (VM_WRITE | VM_SHARED)) == VM_WRITE) | 3011 | else if (is_data_mapping(flags)) |
3001 | mm->data_vm += npages; | 3012 | mm->data_vm += npages; |
3002 | } | 3013 | } |
3003 | 3014 | ||