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) { |