From: Al Viro Date: Tue, 22 Apr 2008 08:45:46 +0000 (-0400) Subject: [PATCH] close race in unshare_files() X-Git-Tag: v2.6.26-rc1~1051^2~3 X-Git-Url: http://pilppa.com/gitweb/?a=commitdiff_plain;h=6b335d9c80d7f3c2a3f6545f664ae9007a0f3821;p=linux-2.6-omap-h63xx.git [PATCH] close race in unshare_files() updating current->files requires task_lock Signed-off-by: Al Viro --- diff --git a/kernel/fork.c b/kernel/fork.c index 89fe414645e..76f05a08062 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -805,12 +805,6 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk) goto out; } - /* - * Note: we may be using current for both targets (See exec.c) - * This works because we cache current->files (old) as oldf. Don't - * break this. - */ - tsk->files = NULL; newf = dup_fd(oldf, &error); if (!newf) goto out; @@ -855,7 +849,8 @@ static int copy_io(unsigned long clone_flags, struct task_struct *tsk) int unshare_files(void) { struct files_struct *files = current->files; - int rc; + struct files_struct *newf; + int error = 0; BUG_ON(!files); @@ -866,10 +861,13 @@ int unshare_files(void) atomic_inc(&files->count); return 0; } - rc = copy_files(0, current); - if(rc) - current->files = files; - return rc; + newf = dup_fd(files, &error); + if (newf) { + task_lock(current); + current->files = newf; + task_unlock(current); + } + return error; } EXPORT_SYMBOL(unshare_files);