patch-2.1.116 linux/fs/exec.c

Next file: linux/fs/ext2/namei.c
Previous file: linux/fs/dcache.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.115/linux/fs/exec.c linux/fs/exec.c
@@ -392,9 +392,9 @@
 static int exec_mmap(void)
 {
 	struct mm_struct * mm, * old_mm;
-	int retval;
+	int retval, nr;
 
-	if (current->mm->count == 1) {
+	if (atomic_read(&current->mm->count) == 1) {
 		flush_cache_mm(current->mm);
 		exit_mmap(current->mm);
 		clear_page_tables(current);
@@ -411,9 +411,16 @@
 	mm = mm_alloc();
 	if (!mm)
 		goto fail_nomem;
+
 	mm->cpu_vm_mask = (1UL << smp_processor_id());
 	mm->total_vm = 0;
 	mm->rss = 0;
+	/*
+	 * Make sure we have a private ldt if needed ...
+	 */
+	nr = current->tarray_ptr - &task[0]; 
+	copy_segments(nr, current, mm);
+
 	old_mm = current->mm;
 	current->mm = mm;
 	retval = new_page_tables(current);
@@ -431,6 +438,8 @@
 	/* The pgd belongs to the parent ... don't free it! */
 	mm->pgd = NULL;
 	current->mm = old_mm;
+	/* restore the ldt for this task */
+	copy_segments(nr, current, NULL);
 	mmput(mm);
 
 fail_nomem:
@@ -657,9 +666,9 @@
 		/* (current->mm->count > 1 is ok, as we'll get a new mm anyway)   */
 		if (IS_NOSUID(inode)
 		    || (current->flags & PF_PTRACED)
-		    || (current->fs->count > 1)
+		    || (atomic_read(&current->fs->count) > 1)
 		    || (atomic_read(&current->sig->count) > 1)
-		    || (current->files->count > 1)) {
+		    || (atomic_read(&current->files->count) > 1)) {
  			if (id_change && !capable(CAP_SETUID))
  				return -EPERM;
  			if (cap_raised && !capable(CAP_SETPCAP))

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov