diff options
Diffstat (limited to 'mm/mmap.c')
-rw-r--r-- | mm/mmap.c | 34 |
1 files changed, 26 insertions, 8 deletions
@@ -121,14 +121,26 @@ int __vm_enough_memory(long pages, int cap_sys_admin) | |||
121 | * only call if we're about to fail. | 121 | * only call if we're about to fail. |
122 | */ | 122 | */ |
123 | n = nr_free_pages(); | 123 | n = nr_free_pages(); |
124 | |||
125 | /* | ||
126 | * Leave reserved pages. The pages are not for anonymous pages. | ||
127 | */ | ||
128 | if (n <= totalreserve_pages) | ||
129 | goto error; | ||
130 | else | ||
131 | n -= totalreserve_pages; | ||
132 | |||
133 | /* | ||
134 | * Leave the last 3% for root | ||
135 | */ | ||
124 | if (!cap_sys_admin) | 136 | if (!cap_sys_admin) |
125 | n -= n / 32; | 137 | n -= n / 32; |
126 | free += n; | 138 | free += n; |
127 | 139 | ||
128 | if (free > pages) | 140 | if (free > pages) |
129 | return 0; | 141 | return 0; |
130 | vm_unacct_memory(pages); | 142 | |
131 | return -ENOMEM; | 143 | goto error; |
132 | } | 144 | } |
133 | 145 | ||
134 | allowed = (totalram_pages - hugetlb_total_pages()) | 146 | allowed = (totalram_pages - hugetlb_total_pages()) |
@@ -150,7 +162,7 @@ int __vm_enough_memory(long pages, int cap_sys_admin) | |||
150 | */ | 162 | */ |
151 | if (atomic_read(&vm_committed_space) < (long)allowed) | 163 | if (atomic_read(&vm_committed_space) < (long)allowed) |
152 | return 0; | 164 | return 0; |
153 | 165 | error: | |
154 | vm_unacct_memory(pages); | 166 | vm_unacct_memory(pages); |
155 | 167 | ||
156 | return -ENOMEM; | 168 | return -ENOMEM; |
@@ -220,6 +232,17 @@ asmlinkage unsigned long sys_brk(unsigned long brk) | |||
220 | 232 | ||
221 | if (brk < mm->end_code) | 233 | if (brk < mm->end_code) |
222 | goto out; | 234 | goto out; |
235 | |||
236 | /* | ||
237 | * Check against rlimit here. If this check is done later after the test | ||
238 | * of oldbrk with newbrk then it can escape the test and let the data | ||
239 | * segment grow beyond its set limit the in case where the limit is | ||
240 | * not page aligned -Ram Gupta | ||
241 | */ | ||
242 | rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; | ||
243 | if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim) | ||
244 | goto out; | ||
245 | |||
223 | newbrk = PAGE_ALIGN(brk); | 246 | newbrk = PAGE_ALIGN(brk); |
224 | oldbrk = PAGE_ALIGN(mm->brk); | 247 | oldbrk = PAGE_ALIGN(mm->brk); |
225 | if (oldbrk == newbrk) | 248 | if (oldbrk == newbrk) |
@@ -232,11 +255,6 @@ asmlinkage unsigned long sys_brk(unsigned long brk) | |||
232 | goto out; | 255 | goto out; |
233 | } | 256 | } |
234 | 257 | ||
235 | /* Check against rlimit.. */ | ||
236 | rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; | ||
237 | if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim) | ||
238 | goto out; | ||
239 | |||
240 | /* Check against existing mmap mappings. */ | 258 | /* Check against existing mmap mappings. */ |
241 | if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE)) | 259 | if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE)) |
242 | goto out; | 260 | goto out; |