Commit 6b335d9c80d7f3c2a3f6545f664ae9007a0f3821

Authored by Al Viro
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

... ... @@ -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);