diff options
Diffstat (limited to 'fs/exec.c')
| -rw-r--r-- | fs/exec.c | 41 |
1 files changed, 37 insertions, 4 deletions
| @@ -164,7 +164,26 @@ out: | |||
| 164 | 164 | ||
| 165 | #ifdef CONFIG_MMU | 165 | #ifdef CONFIG_MMU |
| 166 | 166 | ||
| 167 | static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, | 167 | void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) |
| 168 | { | ||
| 169 | struct mm_struct *mm = current->mm; | ||
| 170 | long diff = (long)(pages - bprm->vma_pages); | ||
| 171 | |||
| 172 | if (!mm || !diff) | ||
| 173 | return; | ||
| 174 | |||
| 175 | bprm->vma_pages = pages; | ||
| 176 | |||
| 177 | #ifdef SPLIT_RSS_COUNTING | ||
| 178 | add_mm_counter(mm, MM_ANONPAGES, diff); | ||
| 179 | #else | ||
| 180 | spin_lock(&mm->page_table_lock); | ||
| 181 | add_mm_counter(mm, MM_ANONPAGES, diff); | ||
| 182 | spin_unlock(&mm->page_table_lock); | ||
| 183 | #endif | ||
| 184 | } | ||
| 185 | |||
| 186 | struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, | ||
| 168 | int write) | 187 | int write) |
| 169 | { | 188 | { |
| 170 | struct page *page; | 189 | struct page *page; |
| @@ -186,6 +205,8 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, | |||
| 186 | unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start; | 205 | unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start; |
| 187 | struct rlimit *rlim; | 206 | struct rlimit *rlim; |
| 188 | 207 | ||
| 208 | acct_arg_size(bprm, size / PAGE_SIZE); | ||
| 209 | |||
| 189 | /* | 210 | /* |
| 190 | * We've historically supported up to 32 pages (ARG_MAX) | 211 | * We've historically supported up to 32 pages (ARG_MAX) |
| 191 | * of argument strings even with small stacks | 212 | * of argument strings even with small stacks |
| @@ -254,6 +275,11 @@ static int __bprm_mm_init(struct linux_binprm *bprm) | |||
| 254 | vma->vm_flags = VM_STACK_FLAGS | VM_STACK_INCOMPLETE_SETUP; | 275 | vma->vm_flags = VM_STACK_FLAGS | VM_STACK_INCOMPLETE_SETUP; |
| 255 | vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); | 276 | vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
| 256 | INIT_LIST_HEAD(&vma->anon_vma_chain); | 277 | INIT_LIST_HEAD(&vma->anon_vma_chain); |
| 278 | |||
| 279 | err = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1); | ||
| 280 | if (err) | ||
| 281 | goto err; | ||
| 282 | |||
| 257 | err = insert_vm_struct(mm, vma); | 283 | err = insert_vm_struct(mm, vma); |
| 258 | if (err) | 284 | if (err) |
| 259 | goto err; | 285 | goto err; |
| @@ -276,7 +302,11 @@ static bool valid_arg_len(struct linux_binprm *bprm, long len) | |||
| 276 | 302 | ||
| 277 | #else | 303 | #else |
| 278 | 304 | ||
| 279 | static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, | 305 | void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) |
| 306 | { | ||
| 307 | } | ||
| 308 | |||
| 309 | struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, | ||
| 280 | int write) | 310 | int write) |
| 281 | { | 311 | { |
| 282 | struct page *page; | 312 | struct page *page; |
| @@ -1003,6 +1033,7 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
| 1003 | /* | 1033 | /* |
| 1004 | * Release all of the old mmap stuff | 1034 | * Release all of the old mmap stuff |
| 1005 | */ | 1035 | */ |
| 1036 | acct_arg_size(bprm, 0); | ||
| 1006 | retval = exec_mmap(bprm->mm); | 1037 | retval = exec_mmap(bprm->mm); |
| 1007 | if (retval) | 1038 | if (retval) |
| 1008 | goto out; | 1039 | goto out; |
| @@ -1426,8 +1457,10 @@ int do_execve(const char * filename, | |||
| 1426 | return retval; | 1457 | return retval; |
| 1427 | 1458 | ||
| 1428 | out: | 1459 | out: |
| 1429 | if (bprm->mm) | 1460 | if (bprm->mm) { |
| 1430 | mmput (bprm->mm); | 1461 | acct_arg_size(bprm, 0); |
| 1462 | mmput(bprm->mm); | ||
| 1463 | } | ||
| 1431 | 1464 | ||
| 1432 | out_file: | 1465 | out_file: |
| 1433 | if (bprm->file) { | 1466 | if (bprm->file) { |
