diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-25 22:05:55 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-25 22:05:55 -0400 |
commit | bc84e0a160e383deb56568f4e03bc51b1ce16775 (patch) | |
tree | 3c8cf1ae23c2f9c165bd7ce63a40b1d5c3aee275 /kernel | |
parent | a92910723a5af54f81373875fd95133c88df94bd (diff) | |
parent | f8f95702f0c4529b0f59488f4509608f0c160e77 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6:
[PATCH] sanitize locate_fd()
[PATCH] sanitize unshare_files/reset_files_struct
[PATCH] sanitize handling of shared descriptor tables in failing execve()
[PATCH] close race in unshare_files()
[PATCH] restore sane ->umount_begin() API
cifs: timeout dfs automounts +little fix.
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/exit.c | 6 | ||||
-rw-r--r-- | kernel/fork.c | 58 |
2 files changed, 26 insertions, 38 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index cece89f80ab4..97f609f574b1 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -507,10 +507,9 @@ void put_files_struct(struct files_struct *files) | |||
507 | } | 507 | } |
508 | } | 508 | } |
509 | 509 | ||
510 | EXPORT_SYMBOL(put_files_struct); | 510 | void reset_files_struct(struct files_struct *files) |
511 | |||
512 | void reset_files_struct(struct task_struct *tsk, struct files_struct *files) | ||
513 | { | 511 | { |
512 | struct task_struct *tsk = current; | ||
514 | struct files_struct *old; | 513 | struct files_struct *old; |
515 | 514 | ||
516 | old = tsk->files; | 515 | old = tsk->files; |
@@ -519,7 +518,6 @@ void reset_files_struct(struct task_struct *tsk, struct files_struct *files) | |||
519 | task_unlock(tsk); | 518 | task_unlock(tsk); |
520 | put_files_struct(old); | 519 | put_files_struct(old); |
521 | } | 520 | } |
522 | EXPORT_SYMBOL(reset_files_struct); | ||
523 | 521 | ||
524 | void exit_files(struct task_struct *tsk) | 522 | void exit_files(struct task_struct *tsk) |
525 | { | 523 | { |
diff --git a/kernel/fork.c b/kernel/fork.c index 89fe414645e9..efb618fc8ffe 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) | |||
805 | goto out; | 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 | newf = dup_fd(oldf, &error); | 808 | newf = dup_fd(oldf, &error); |
815 | if (!newf) | 809 | if (!newf) |
816 | goto out; | 810 | goto out; |
@@ -846,34 +840,6 @@ static int copy_io(unsigned long clone_flags, struct task_struct *tsk) | |||
846 | return 0; | 840 | return 0; |
847 | } | 841 | } |
848 | 842 | ||
849 | /* | ||
850 | * Helper to unshare the files of the current task. | ||
851 | * We don't want to expose copy_files internals to | ||
852 | * the exec layer of the kernel. | ||
853 | */ | ||
854 | |||
855 | int unshare_files(void) | ||
856 | { | ||
857 | struct files_struct *files = current->files; | ||
858 | int rc; | ||
859 | |||
860 | BUG_ON(!files); | ||
861 | |||
862 | /* This can race but the race causes us to copy when we don't | ||
863 | need to and drop the copy */ | ||
864 | if(atomic_read(&files->count) == 1) | ||
865 | { | ||
866 | atomic_inc(&files->count); | ||
867 | return 0; | ||
868 | } | ||
869 | rc = copy_files(0, current); | ||
870 | if(rc) | ||
871 | current->files = files; | ||
872 | return rc; | ||
873 | } | ||
874 | |||
875 | EXPORT_SYMBOL(unshare_files); | ||
876 | |||
877 | static int copy_sighand(unsigned long clone_flags, struct task_struct *tsk) | 843 | static int copy_sighand(unsigned long clone_flags, struct task_struct *tsk) |
878 | { | 844 | { |
879 | struct sighand_struct *sig; | 845 | struct sighand_struct *sig; |
@@ -1811,3 +1777,27 @@ bad_unshare_cleanup_thread: | |||
1811 | bad_unshare_out: | 1777 | bad_unshare_out: |
1812 | return err; | 1778 | return err; |
1813 | } | 1779 | } |
1780 | |||
1781 | /* | ||
1782 | * Helper to unshare the files of the current task. | ||
1783 | * We don't want to expose copy_files internals to | ||
1784 | * the exec layer of the kernel. | ||
1785 | */ | ||
1786 | |||
1787 | int unshare_files(struct files_struct **displaced) | ||
1788 | { | ||
1789 | struct task_struct *task = current; | ||
1790 | struct files_struct *copy; | ||
1791 | int error; | ||
1792 | |||
1793 | error = unshare_fd(CLONE_FILES, ©); | ||
1794 | if (error || !copy) { | ||
1795 | *displaced = NULL; | ||
1796 | return error; | ||
1797 | } | ||
1798 | *displaced = task->files; | ||
1799 | task_lock(task); | ||
1800 | task->files = copy; | ||
1801 | task_unlock(task); | ||
1802 | return 0; | ||
1803 | } | ||