Commit 6b335d9c authored by Al Viro's avatar Al Viro

[PATCH] close race in unshare_files()

updating current->files requires task_lock
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 42faad99
...@@ -805,12 +805,6 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk) ...@@ -805,12 +805,6 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
goto out; 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); newf = dup_fd(oldf, &error);
if (!newf) if (!newf)
goto out; goto out;
...@@ -855,7 +849,8 @@ static int copy_io(unsigned long clone_flags, struct task_struct *tsk) ...@@ -855,7 +849,8 @@ static int copy_io(unsigned long clone_flags, struct task_struct *tsk)
int unshare_files(void) int unshare_files(void)
{ {
struct files_struct *files = current->files; struct files_struct *files = current->files;
int rc; struct files_struct *newf;
int error = 0;
BUG_ON(!files); BUG_ON(!files);
...@@ -866,10 +861,13 @@ int unshare_files(void) ...@@ -866,10 +861,13 @@ int unshare_files(void)
atomic_inc(&files->count); atomic_inc(&files->count);
return 0; return 0;
} }
rc = copy_files(0, current); newf = dup_fd(files, &error);
if(rc) if (newf) {
current->files = files; task_lock(current);
return rc; current->files = newf;
task_unlock(current);
}
return error;
} }
EXPORT_SYMBOL(unshare_files); EXPORT_SYMBOL(unshare_files);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment