diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2008-04-22 05:11:59 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2008-04-25 09:23:53 -0400 |
commit | fd8328be874f4190a811c58cd4778ec2c74d2c05 (patch) | |
tree | b44ae8e99ce96a1a4739b04d4d1a23c40ab8b163 /fs/binfmt_misc.c | |
parent | 6b335d9c80d7f3c2a3f6545f664ae9007a0f3821 (diff) |
[PATCH] sanitize handling of shared descriptor tables in failing execve()
* unshare_files() can fail; doing it after irreversible actions is wrong
and de_thread() is certainly irreversible.
* since we do it unconditionally anyway, we might as well do it in do_execve()
and save ourselves the PITA in binfmt handlers, etc.
* while we are at it, binfmt_som actually leaked files_struct on failure.
As a side benefit, unshare_files(), put_files_struct() and reset_files_struct()
become unexported.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/binfmt_misc.c')
-rw-r--r-- | fs/binfmt_misc.c | 18 |
1 files changed, 1 insertions, 17 deletions
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index b53c7e5f41bb..dbf0ac0523de 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c | |||
@@ -110,7 +110,6 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
110 | char *iname_addr = iname; | 110 | char *iname_addr = iname; |
111 | int retval; | 111 | int retval; |
112 | int fd_binary = -1; | 112 | int fd_binary = -1; |
113 | struct files_struct *files = NULL; | ||
114 | 113 | ||
115 | retval = -ENOEXEC; | 114 | retval = -ENOEXEC; |
116 | if (!enabled) | 115 | if (!enabled) |
@@ -133,21 +132,13 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
133 | 132 | ||
134 | if (fmt->flags & MISC_FMT_OPEN_BINARY) { | 133 | if (fmt->flags & MISC_FMT_OPEN_BINARY) { |
135 | 134 | ||
136 | files = current->files; | ||
137 | retval = unshare_files(); | ||
138 | if (retval < 0) | ||
139 | goto _ret; | ||
140 | if (files == current->files) { | ||
141 | put_files_struct(files); | ||
142 | files = NULL; | ||
143 | } | ||
144 | /* if the binary should be opened on behalf of the | 135 | /* if the binary should be opened on behalf of the |
145 | * interpreter than keep it open and assign descriptor | 136 | * interpreter than keep it open and assign descriptor |
146 | * to it */ | 137 | * to it */ |
147 | fd_binary = get_unused_fd(); | 138 | fd_binary = get_unused_fd(); |
148 | if (fd_binary < 0) { | 139 | if (fd_binary < 0) { |
149 | retval = fd_binary; | 140 | retval = fd_binary; |
150 | goto _unshare; | 141 | goto _ret; |
151 | } | 142 | } |
152 | fd_install(fd_binary, bprm->file); | 143 | fd_install(fd_binary, bprm->file); |
153 | 144 | ||
@@ -205,10 +196,6 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
205 | if (retval < 0) | 196 | if (retval < 0) |
206 | goto _error; | 197 | goto _error; |
207 | 198 | ||
208 | if (files) { | ||
209 | put_files_struct(files); | ||
210 | files = NULL; | ||
211 | } | ||
212 | _ret: | 199 | _ret: |
213 | return retval; | 200 | return retval; |
214 | _error: | 201 | _error: |
@@ -216,9 +203,6 @@ _error: | |||
216 | sys_close(fd_binary); | 203 | sys_close(fd_binary); |
217 | bprm->interp_flags = 0; | 204 | bprm->interp_flags = 0; |
218 | bprm->interp_data = 0; | 205 | bprm->interp_data = 0; |
219 | _unshare: | ||
220 | if (files) | ||
221 | reset_files_struct(current, files); | ||
222 | goto _ret; | 206 | goto _ret; |
223 | } | 207 | } |
224 | 208 | ||