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; |
