Commit 6b335d9c80d7f3c2a3f6545f664ae9007a0f3821
1 parent
42faad9965
[PATCH] close race in unshare_files()
updating current->files requires task_lock Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Showing 1 changed file with 9 additions and 11 deletions Side-by-side Diff
kernel/fork.c
... | ... | @@ -805,12 +805,6 @@ |
805 | 805 | goto out; |
806 | 806 | } |
807 | 807 | |
808 | - /* | |
809 | - * Note: we may be using current for both targets (See exec.c) | |
810 | - * This works because we cache current->files (old) as oldf. Don't | |
811 | - * break this. | |
812 | - */ | |
813 | - tsk->files = NULL; | |
814 | 808 | newf = dup_fd(oldf, &error); |
815 | 809 | if (!newf) |
816 | 810 | goto out; |
... | ... | @@ -855,7 +849,8 @@ |
855 | 849 | int unshare_files(void) |
856 | 850 | { |
857 | 851 | struct files_struct *files = current->files; |
858 | - int rc; | |
852 | + struct files_struct *newf; | |
853 | + int error = 0; | |
859 | 854 | |
860 | 855 | BUG_ON(!files); |
861 | 856 | |
... | ... | @@ -866,10 +861,13 @@ |
866 | 861 | atomic_inc(&files->count); |
867 | 862 | return 0; |
868 | 863 | } |
869 | - rc = copy_files(0, current); | |
870 | - if(rc) | |
871 | - current->files = files; | |
872 | - return rc; | |
864 | + newf = dup_fd(files, &error); | |
865 | + if (newf) { | |
866 | + task_lock(current); | |
867 | + current->files = newf; | |
868 | + task_unlock(current); | |
869 | + } | |
870 | + return error; | |
873 | 871 | } |
874 | 872 | |
875 | 873 | EXPORT_SYMBOL(unshare_files); |