|
@@ -164,6 +164,25 @@ out:
|
|
|
|
|
|
#ifdef CONFIG_MMU
|
|
|
|
|
|
+static void acct_arg_size(struct linux_binprm *bprm, unsigned long pages)
|
|
|
+{
|
|
|
+ struct mm_struct *mm = current->mm;
|
|
|
+ long diff = (long)(pages - bprm->vma_pages);
|
|
|
+
|
|
|
+ if (!mm || !diff)
|
|
|
+ return;
|
|
|
+
|
|
|
+ bprm->vma_pages = pages;
|
|
|
+
|
|
|
+#ifdef SPLIT_RSS_COUNTING
|
|
|
+ add_mm_counter(mm, MM_ANONPAGES, diff);
|
|
|
+#else
|
|
|
+ spin_lock(&mm->page_table_lock);
|
|
|
+ add_mm_counter(mm, MM_ANONPAGES, diff);
|
|
|
+ spin_unlock(&mm->page_table_lock);
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
|
|
|
int write)
|
|
|
{
|
|
@@ -186,6 +205,8 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
|
|
|
unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start;
|
|
|
struct rlimit *rlim;
|
|
|
|
|
|
+ acct_arg_size(bprm, size / PAGE_SIZE);
|
|
|
+
|
|
|
/*
|
|
|
* We've historically supported up to 32 pages (ARG_MAX)
|
|
|
* of argument strings even with small stacks
|
|
@@ -276,6 +297,10 @@ static bool valid_arg_len(struct linux_binprm *bprm, long len)
|
|
|
|
|
|
#else
|
|
|
|
|
|
+static inline void acct_arg_size(struct linux_binprm *bprm, unsigned long pages)
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
|
|
|
int write)
|
|
|
{
|
|
@@ -1003,6 +1028,7 @@ int flush_old_exec(struct linux_binprm * bprm)
|
|
|
/*
|
|
|
* Release all of the old mmap stuff
|
|
|
*/
|
|
|
+ acct_arg_size(bprm, 0);
|
|
|
retval = exec_mmap(bprm->mm);
|
|
|
if (retval)
|
|
|
goto out;
|
|
@@ -1426,8 +1452,10 @@ int do_execve(const char * filename,
|
|
|
return retval;
|
|
|
|
|
|
out:
|
|
|
- if (bprm->mm)
|
|
|
- mmput (bprm->mm);
|
|
|
+ if (bprm->mm) {
|
|
|
+ acct_arg_size(bprm, 0);
|
|
|
+ mmput(bprm->mm);
|
|
|
+ }
|
|
|
|
|
|
out_file:
|
|
|
if (bprm->file) {
|