diff options
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 41 |
1 files changed, 37 insertions, 4 deletions
@@ -159,7 +159,26 @@ out: | |||
159 | 159 | ||
160 | #ifdef CONFIG_MMU | 160 | #ifdef CONFIG_MMU |
161 | 161 | ||
162 | static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, | 162 | void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) |
163 | { | ||
164 | struct mm_struct *mm = current->mm; | ||
165 | long diff = (long)(pages - bprm->vma_pages); | ||
166 | |||
167 | if (!mm || !diff) | ||
168 | return; | ||
169 | |||
170 | bprm->vma_pages = pages; | ||
171 | |||
172 | #ifdef SPLIT_RSS_COUNTING | ||
173 | add_mm_counter(mm, MM_ANONPAGES, diff); | ||
174 | #else | ||
175 | spin_lock(&mm->page_table_lock); | ||
176 | add_mm_counter(mm, MM_ANONPAGES, diff); | ||
177 | spin_unlock(&mm->page_table_lock); | ||
178 | #endif | ||
179 | } | ||
180 | |||
181 | struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, | ||
163 | int write) | 182 | int write) |
164 | { | 183 | { |
165 | struct page *page; | 184 | struct page *page; |
@@ -181,6 +200,8 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, | |||
181 | unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start; | 200 | unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start; |
182 | struct rlimit *rlim; | 201 | struct rlimit *rlim; |
183 | 202 | ||
203 | acct_arg_size(bprm, size / PAGE_SIZE); | ||
204 | |||
184 | /* | 205 | /* |
185 | * We've historically supported up to 32 pages (ARG_MAX) | 206 | * We've historically supported up to 32 pages (ARG_MAX) |
186 | * of argument strings even with small stacks | 207 | * of argument strings even with small stacks |
@@ -249,6 +270,11 @@ static int __bprm_mm_init(struct linux_binprm *bprm) | |||
249 | vma->vm_flags = VM_STACK_FLAGS | VM_STACK_INCOMPLETE_SETUP; | 270 | vma->vm_flags = VM_STACK_FLAGS | VM_STACK_INCOMPLETE_SETUP; |
250 | vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); | 271 | vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
251 | INIT_LIST_HEAD(&vma->anon_vma_chain); | 272 | INIT_LIST_HEAD(&vma->anon_vma_chain); |
273 | |||
274 | err = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1); | ||
275 | if (err) | ||
276 | goto err; | ||
277 | |||
252 | err = insert_vm_struct(mm, vma); | 278 | err = insert_vm_struct(mm, vma); |
253 | if (err) | 279 | if (err) |
254 | goto err; | 280 | goto err; |
@@ -271,7 +297,11 @@ static bool valid_arg_len(struct linux_binprm *bprm, long len) | |||
271 | 297 | ||
272 | #else | 298 | #else |
273 | 299 | ||
274 | static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, | 300 | void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) |
301 | { | ||
302 | } | ||
303 | |||
304 | struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, | ||
275 | int write) | 305 | int write) |
276 | { | 306 | { |
277 | struct page *page; | 307 | struct page *page; |
@@ -994,6 +1024,7 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
994 | /* | 1024 | /* |
995 | * Release all of the old mmap stuff | 1025 | * Release all of the old mmap stuff |
996 | */ | 1026 | */ |
1027 | acct_arg_size(bprm, 0); | ||
997 | retval = exec_mmap(bprm->mm); | 1028 | retval = exec_mmap(bprm->mm); |
998 | if (retval) | 1029 | if (retval) |
999 | goto out; | 1030 | goto out; |
@@ -1419,8 +1450,10 @@ int do_execve(const char * filename, | |||
1419 | return retval; | 1450 | return retval; |
1420 | 1451 | ||
1421 | out: | 1452 | out: |
1422 | if (bprm->mm) | 1453 | if (bprm->mm) { |
1423 | mmput (bprm->mm); | 1454 | acct_arg_size(bprm, 0); |
1455 | mmput(bprm->mm); | ||
1456 | } | ||
1424 | 1457 | ||
1425 | out_file: | 1458 | out_file: |
1426 | if (bprm->file) { | 1459 | if (bprm->file) { |