Andries Brouwer spotted this.  If copy_namespace() returns -EPERM,
copy_process() will then return -ENOMEM by mistake.

Fix all that up by making things return appropriate error codes and
propagating them back correctly.



 25-akpm/kernel/fork.c |   32 +++++++++++++++-----------------
 1 files changed, 15 insertions(+), 17 deletions(-)

diff -puN kernel/fork.c~clone-retval-fix kernel/fork.c
--- 25/kernel/fork.c~clone-retval-fix	Mon Apr 21 15:40:50 2003
+++ 25-akpm/kernel/fork.c	Mon Apr 21 15:40:50 2003
@@ -379,7 +379,6 @@ static struct mm_struct * mm_init(struct
 	free_mm(mm);
 	return NULL;
 }
-	
 
 /*
  * Allocate and initialize an mm_struct.
@@ -543,7 +542,7 @@ static inline struct fs_struct *__copy_f
 		} else {
 			fs->altrootmnt = NULL;
 			fs->altroot = NULL;
-		}	
+		}
 		read_unlock(&old->lock);
 	}
 	return fs;
@@ -562,14 +561,14 @@ static inline int copy_fs(unsigned long 
 	}
 	tsk->fs = __copy_fs_struct(current->fs);
 	if (!tsk->fs)
-		return -1;
+		return -ENOMEM;
 	return 0;
 }
 
 static int count_open_files(struct files_struct *files, int size)
 {
 	int i;
-	
+
 	/* Find the last open fd */
 	for (i = size/(8*sizeof(long)); i > 0; ) {
 		if (files->open_fds->fds_bits[--i])
@@ -669,7 +668,7 @@ static int copy_files(unsigned long clon
 	if (newf->max_fdset > open_files) {
 		int left = (newf->max_fdset-open_files)/8;
 		int start = open_files / (8 * sizeof(unsigned long));
-		
+
 		memset(&newf->open_fds->fds_bits[start], 0, left);
 		memset(&newf->close_on_exec->fds_bits[start], 0, left);
 	}
@@ -697,7 +696,7 @@ static inline int copy_sighand(unsigned 
 	sig = kmem_cache_alloc(sighand_cachep, GFP_KERNEL);
 	tsk->sighand = sig;
 	if (!sig)
-		return -1;
+		return -ENOMEM;
 	spin_lock_init(&sig->siglock);
 	atomic_set(&sig->count, 1);
 	memcpy(sig->action, current->sighand->action, sizeof(sig->action));
@@ -715,7 +714,7 @@ static inline int copy_signal(unsigned l
 	sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL);
 	tsk->signal = sig;
 	if (!sig)
-		return -1;
+		return -ENOMEM;
 	atomic_set(&sig->count, 1);
 	sig->group_exit = 0;
 	sig->group_exit_code = 0;
@@ -800,7 +799,7 @@ static struct task_struct *copy_process(
 	 */
 	if (nr_threads >= max_threads)
 		goto bad_fork_cleanup_count;
-	
+
 	if (!try_module_get(p->thread_info->exec_domain->module))
 		goto bad_fork_cleanup_count;
 
@@ -860,23 +859,22 @@ static struct task_struct *copy_process(
 	p->security = NULL;
 
 	retval = -ENOMEM;
-	if (security_task_alloc(p))
+	if ((retval = security_task_alloc(p)))
 		goto bad_fork_cleanup;
 	/* copy all the process information */
-	if (copy_semundo(clone_flags, p))
+	if ((retval = copy_semundo(clone_flags, p)))
 		goto bad_fork_cleanup_security;
-	if (copy_files(clone_flags, p))
+	if ((retval = copy_files(clone_flags, p)))
 		goto bad_fork_cleanup_semundo;
-	if (copy_fs(clone_flags, p))
+	if ((retval = copy_fs(clone_flags, p)))
 		goto bad_fork_cleanup_files;
-	if (copy_sighand(clone_flags, p))
+	if ((retval = copy_sighand(clone_flags, p)))
 		goto bad_fork_cleanup_fs;
-	if (copy_signal(clone_flags, p))
+	if ((retval = copy_signal(clone_flags, p)))
 		goto bad_fork_cleanup_sighand;
-	if (copy_mm(clone_flags, p))
+	if ((retval = copy_mm(clone_flags, p)))
 		goto bad_fork_cleanup_signal;
-	retval = copy_namespace(clone_flags, p);
-	if (retval)
+	if ((retval = copy_namespace(clone_flags, p)))
 		goto bad_fork_cleanup_mm;
 	retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
 	if (retval)

_