aboutsummaryrefslogtreecommitdiffstats
path: root/mm/mmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/mmap.c')
-rw-r--r--mm/mmap.c34
1 files changed, 26 insertions, 8 deletions
diff --git a/mm/mmap.c b/mm/mmap.c
index e780d19aa214..e6ee12344b13 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -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 165error:
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;