[kernel] r19801 - in dists/squeeze/linux-2.6/debian: . patches/debian patches/features/all/openvz patches/features/all/vserver patches/series

Ben Hutchings benh at alioth.debian.org
Thu Feb 14 03:55:06 UTC 2013


Author: benh
Date: Thu Feb 14 03:55:04 2013
New Revision: 19801

Log:
exec: Fix accounting of execv*() memory after vfork() (Closes: #700486)

Added:
   dists/squeeze/linux-2.6/debian/patches/debian/exec-Fix-accounting-of-execv-memory-after-vfork.patch
Modified:
   dists/squeeze/linux-2.6/debian/changelog
   dists/squeeze/linux-2.6/debian/patches/features/all/openvz/openvz.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/vserver/vs2.3.0.36.29.8.patch
   dists/squeeze/linux-2.6/debian/patches/series/48

Modified: dists/squeeze/linux-2.6/debian/changelog
==============================================================================
--- dists/squeeze/linux-2.6/debian/changelog	Mon Feb 11 04:00:47 2013	(r19800)
+++ dists/squeeze/linux-2.6/debian/changelog	Thu Feb 14 03:55:04 2013	(r19801)
@@ -4,6 +4,7 @@
   * [s390] s390/time: fix sched_clock() overflow (Closes: #698382) 
   * Revert "time: Avoid making adjustments if we haven't accumulated
     anything" (Closes: #699112, regression in 2.6.32.60)
+  * exec: Fix accounting of execv*() memory after vfork() (Closes: #700486)
 
  -- Ben Hutchings <ben at decadent.org.uk>  Sat, 19 Jan 2013 19:57:27 +0000
 

Added: dists/squeeze/linux-2.6/debian/patches/debian/exec-Fix-accounting-of-execv-memory-after-vfork.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/debian/exec-Fix-accounting-of-execv-memory-after-vfork.patch	Thu Feb 14 03:55:04 2013	(r19801)
@@ -0,0 +1,119 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Date: Wed, 13 Feb 2013 13:06:38 +0000
+Subject: exec: Fix accounting of execv*() memory after vfork()
+Bug-Debian: http://bugs.debian.org/700486
+
+The patch 'exec: Get rid of linux_binprm::vma_pages' made the incorrect
+assumption that:
+
+> - The calls to acct_arg_size(bprm, 0) are redundant, since
+>   neither the cache nor the dead mm need to be updated
+
+This is not true in case execve() was called after vfork(); in that
+case the mm is borrowed from the parent process and will continue
+to exist.
+
+All calls to acct_arg_size(bprm, 0) (in the upstream version) come
+before current->mm is changed and before the vma holding argv/envp has
+been expanded to become a stack.  So vma_pages() will tell us exactly
+how many pages to un-account.  (This also means that there is a brief
+window between flush_old_exec() and setup_arg_pages() where the vma is
+again not accounted anywhere...!)
+
+Also change get_arg_page() to use vma_pages() rather than effectively
+open-coding it, to make what we're doing (relatively) clear and
+consistent.
+
+Finally, account for the first page allocated in __bprm_mm_init() by
+calling acct_arg_size() there too.
+
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+---
+--- a/fs/compat.c
++++ b/fs/compat.c
+@@ -1549,6 +1549,7 @@ int compat_do_execve(char * filename,
+ 
+ out:
+ 	if (bprm->mm) {
++		acct_arg_size(bprm, 0, vma_pages(bprm->vma));
+ 		mmput(bprm->mm);
+ 	}
+ 
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -159,8 +159,8 @@ out:
+ 
+ #ifdef CONFIG_MMU
+ 
+-static void acct_arg_size(struct linux_binprm *bprm, unsigned long pages,
+-			  unsigned long old_pages)
++void acct_arg_size(struct linux_binprm *bprm, unsigned long pages,
++		   unsigned long old_pages)
+ {
+ 	struct mm_struct *mm = current->mm;
+ 	long diff = (long)(pages - old_pages);
+@@ -176,8 +176,7 @@ void acct_arg_size(struct linux_binprm *bprm, unsigned long pages)
+ struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
+ 		int write)
+ {
+-	unsigned long old_vma_pages =
+-		(bprm->vma->vm_end - bprm->vma->vm_start) / PAGE_SIZE;
++	unsigned long old_vma_pages = vma_pages(bprm->vma);
+ 	struct page *page;
+ 	int ret;
+ 
+@@ -197,7 +198,7 @@
+ 		unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start;
+ 		struct rlimit *rlim;
+ 
+-		acct_arg_size(bprm, size / PAGE_SIZE, old_vma_pages);
++		acct_arg_size(bprm, vma_pages(bprm->vma), old_vma_pages);
+ 
+ 		/*
+ 		 * We've historically supported up to 32 pages (ARG_MAX)
+@@ -276,6 +277,7 @@
+ 
+ 	mm->stack_vm = mm->total_vm = 1;
+ 	up_write(&mm->mmap_sem);
++	acct_arg_size(bprm, 1, 0);
+ 	bprm->p = vma->vm_end - sizeof(void *);
+ 	return 0;
+ err:
+@@ -290,8 +292,8 @@ static bool valid_arg_len(struct linux_binprm *bprm, long len)
+ 
+ #else
+ 
+-static void acct_arg_size(struct linux_binprm *bprm, unsigned long pages,
+-			  unsigned long old_pages)
++void acct_arg_size(struct linux_binprm *bprm, unsigned long pages,
++		   unsigned long old_pages)
+ {
+ }
+ 
+@@ -1004,6 +1006,7 @@ int flush_old_exec(struct linux_binprm * bprm)
+ 	/*
+ 	 * Release all of the old mmap stuff
+ 	 */
++	acct_arg_size(bprm, 0, vma_pages(bprm->vma));
+ 	retval = exec_mmap(bprm->mm);
+ 	if (retval)
+ 		goto out;
+@@ -1429,6 +1431,7 @@ int do_execve(char * filename,
+ 
+ out:
+ 	if (bprm->mm) {
++		acct_arg_size(bprm, 0, vma_pages(bprm->vma));
+ 		mmput(bprm->mm);
+ 	}
+ 
+--- a/include/linux/binfmts.h
++++ b/include/linux/binfmts.h
+@@ -59,6 +59,8 @@ struct linux_binprm{
+ 	unsigned long loader, exec;
+ };
+ 
++extern void acct_arg_size(struct linux_binprm *bprm, unsigned long pages,
++			  unsigned long old_pages);
+ extern struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
+ 					int write);
+ 

Modified: dists/squeeze/linux-2.6/debian/patches/features/all/openvz/openvz.patch
==============================================================================
--- dists/squeeze/linux-2.6/debian/patches/features/all/openvz/openvz.patch	Mon Feb 11 04:00:47 2013	(r19800)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/openvz/openvz.patch	Thu Feb 14 03:55:04 2013	(r19801)
@@ -16865,9 +16865,9 @@
  		tsk->group_leader = tsk;
  		leader->group_leader = tsk;
 @@ -981,12 +1013,10 @@ int flush_old_exec(struct linux_binprm * bprm)
- 	/*
  	 * Release all of the old mmap stuff
  	 */
+ 	acct_arg_size(bprm, 0, vma_pages(bprm->vma));
 -	retval = exec_mmap(bprm->mm);
 +	retval = exec_mmap(bprm);
  	if (retval)

Modified: dists/squeeze/linux-2.6/debian/patches/features/all/vserver/vs2.3.0.36.29.8.patch
==============================================================================
--- dists/squeeze/linux-2.6/debian/patches/features/all/vserver/vs2.3.0.36.29.8.patch	Mon Feb 11 04:00:47 2013	(r19800)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/vserver/vs2.3.0.36.29.8.patch	Thu Feb 14 03:55:04 2013	(r19801)
@@ -1,6 +1,8 @@
 [bwh: Adjust context in drivers/block/Kconfig changed by drbd backport]
 [bwh: Adjust context in fs/ext3/inode.c and kernel/fork.c changed by
  2.6.32.60]
+[bwh: Adjust context in fs/exec.c, changed by
+ 'exec: Fix accounting of execv*() memory after vfork()']
 
 --- a/Documentation/scheduler/sched-cfs-hard-limits.txt	1970-01-01 01:00:00.000000000 +0100
 +++ a/Documentation/scheduler/sched-cfs-hard-limits.txt	2011-06-10 13:03:02.000000000 +0200
@@ -2614,8 +2616,8 @@
 +	vx_vmpages_inc(mm);
 +	mm->stack_vm = 1;
  	up_write(&mm->mmap_sem);
+ 	acct_arg_size(bprm, 1, 0);
  	bprm->p = vma->vm_end - sizeof(void *);
- 	return 0;
 @@ -1534,7 +1536,7 @@ static int format_corename(char *corenam
  			/* UNIX time of coredump */
  			case 't': {

Modified: dists/squeeze/linux-2.6/debian/patches/series/48
==============================================================================
--- dists/squeeze/linux-2.6/debian/patches/series/48	Mon Feb 11 04:00:47 2013	(r19800)
+++ dists/squeeze/linux-2.6/debian/patches/series/48	Thu Feb 14 03:55:04 2013	(r19801)
@@ -1,2 +1,3 @@
 + bugfix/s390/s390-time-fix-sched_clock-overflow.patch
 + bugfix/all/revert-time-avoid-making-adjustments-if-we-haven-t.patch
++ debian/exec-Fix-accounting-of-execv-memory-after-vfork.patch



More information about the Kernel-svn-changes mailing list