Skip to content

Commit 15a2bc4

Browse files
committed
Merge branch 'exec-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace
Pull execve updates from Eric Biederman: "Last cycle for the Nth time I ran into bugs and quality of implementation issues related to exec that could not be easily be fixed because of the way exec is implemented. So I have been digging into exec and cleanup up what I can. I don't think I have exec sorted out enough to fix the issues I started with but I have made some headway this cycle with 4 sets of changes. - promised cleanups after introducing exec_update_mutex - trivial cleanups for exec - control flow simplifications - remove the recomputation of bprm->cred The net result is code that is a bit easier to understand and work with and a decrease in the number of lines of code (if you don't count the added tests)" * 'exec-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace: (24 commits) exec: Compute file based creds only once exec: Add a per bprm->file version of per_clear binfmt_elf_fdpic: fix execfd build regression selftests/exec: Add binfmt_script regression test exec: Remove recursion from search_binary_handler exec: Generic execfd support exec/binfmt_script: Don't modify bprm->buf and then return -ENOEXEC exec: Move the call of prepare_binprm into search_binary_handler exec: Allow load_misc_binary to call prepare_binprm unconditionally exec: Convert security_bprm_set_creds into security_bprm_repopulate_creds exec: Factor security_bprm_creds_for_exec out of security_bprm_set_creds exec: Teach prepare_exec_creds how exec treats uids & gids exec: Set the point of no return sooner exec: Move handling of the point of no return to the top level exec: Run sync_mm_rss before taking exec_update_mutex exec: Fix spelling of search_binary_handler in a comment exec: Move the comment from above de_thread to above unshare_sighand exec: Rename flush_old_exec begin_new_exec exec: Move most of setup_new_exec into flush_old_exec exec: In setup_new_exec cache current in the local variable me ...
2 parents 9ff7258 + 3977e28 commit 15a2bc4

File tree

27 files changed

+501
-387
lines changed

27 files changed

+501
-387
lines changed

Documentation/trace/ftrace.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1524,7 +1524,7 @@ display-graph option::
15241524
=> remove_vma
15251525
=> exit_mmap
15261526
=> mmput
1527-
=> flush_old_exec
1527+
=> begin_new_exec
15281528
=> load_elf_binary
15291529
=> search_binary_handler
15301530
=> __do_execve_file.isra.32

arch/alpha/kernel/binfmt_loader.c

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,6 @@ static int load_binary(struct linux_binprm *bprm)
1919
if (bprm->loader)
2020
return -ENOEXEC;
2121

22-
allow_write_access(bprm->file);
23-
fput(bprm->file);
24-
bprm->file = NULL;
25-
2622
loader = bprm->vma->vm_end - sizeof(void *);
2723

2824
file = open_exec("/sbin/loader");
@@ -33,12 +29,9 @@ static int load_binary(struct linux_binprm *bprm)
3329
/* Remember if the application is TASO. */
3430
bprm->taso = eh->ah.entry < 0x100000000UL;
3531

36-
bprm->file = file;
32+
bprm->interpreter = file;
3733
bprm->loader = loader;
38-
retval = prepare_binprm(bprm);
39-
if (retval < 0)
40-
return retval;
41-
return search_binary_handler(bprm);
34+
return 0;
4235
}
4336

4437
static struct linux_binfmt loader_format = {

arch/x86/ia32/ia32_aout.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ static int load_aout_binary(struct linux_binprm *bprm)
131131
return -ENOMEM;
132132

133133
/* Flush all traces of the currently running executable */
134-
retval = flush_old_exec(bprm);
134+
retval = begin_new_exec(bprm);
135135
if (retval)
136136
return retval;
137137

@@ -156,8 +156,6 @@ static int load_aout_binary(struct linux_binprm *bprm)
156156
if (retval < 0)
157157
return retval;
158158

159-
install_exec_creds(bprm);
160-
161159
if (N_MAGIC(ex) == OMAGIC) {
162160
unsigned long text_addr, map_size;
163161

fs/binfmt_aout.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ static int load_aout_binary(struct linux_binprm * bprm)
151151
return -ENOMEM;
152152

153153
/* Flush all traces of the currently running executable */
154-
retval = flush_old_exec(bprm);
154+
retval = begin_new_exec(bprm);
155155
if (retval)
156156
return retval;
157157

@@ -174,7 +174,6 @@ static int load_aout_binary(struct linux_binprm * bprm)
174174
if (retval < 0)
175175
return retval;
176176

177-
install_exec_creds(bprm);
178177

179178
if (N_MAGIC(ex) == OMAGIC) {
180179
unsigned long text_addr, map_size;

fs/binfmt_elf.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -279,8 +279,8 @@ create_elf_tables(struct linux_binprm *bprm, const struct elfhdr *exec,
279279
NEW_AUX_ENT(AT_BASE_PLATFORM,
280280
(elf_addr_t)(unsigned long)u_base_platform);
281281
}
282-
if (bprm->interp_flags & BINPRM_FLAGS_EXECFD) {
283-
NEW_AUX_ENT(AT_EXECFD, bprm->interp_data);
282+
if (bprm->have_execfd) {
283+
NEW_AUX_ENT(AT_EXECFD, bprm->execfd);
284284
}
285285
#undef NEW_AUX_ENT
286286
/* AT_NULL is zero; clear the rest too */
@@ -975,7 +975,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
975975
goto out_free_dentry;
976976

977977
/* Flush all traces of the currently running executable */
978-
retval = flush_old_exec(bprm);
978+
retval = begin_new_exec(bprm);
979979
if (retval)
980980
goto out_free_dentry;
981981

@@ -989,7 +989,6 @@ static int load_elf_binary(struct linux_binprm *bprm)
989989
current->flags |= PF_RANDOMIZE;
990990

991991
setup_new_exec(bprm);
992-
install_exec_creds(bprm);
993992

994993
/* Do this so that we can load the interpreter, if need be. We will
995994
change some of these later */

fs/binfmt_elf_fdpic.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm)
338338
interp_params.flags |= ELF_FDPIC_FLAG_CONSTDISP;
339339

340340
/* flush all traces of the currently running executable */
341-
retval = flush_old_exec(bprm);
341+
retval = begin_new_exec(bprm);
342342
if (retval)
343343
goto error;
344344

@@ -434,7 +434,6 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm)
434434
current->mm->start_stack = current->mm->start_brk + stack_size;
435435
#endif
436436

437-
install_exec_creds(bprm);
438437
if (create_elf_fdpic_tables(bprm, current->mm,
439438
&exec_params, &interp_params) < 0)
440439
goto error;
@@ -589,7 +588,7 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
589588
nitems = 1 + DLINFO_ITEMS + (k_platform ? 1 : 0) +
590589
(k_base_platform ? 1 : 0) + AT_VECTOR_SIZE_ARCH;
591590

592-
if (bprm->interp_flags & BINPRM_FLAGS_EXECFD)
591+
if (bprm->have_execfd)
593592
nitems++;
594593

595594
csp = sp;
@@ -629,10 +628,10 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
629628
(elf_addr_t) (unsigned long) u_base_platform);
630629
}
631630

632-
if (bprm->interp_flags & BINPRM_FLAGS_EXECFD) {
631+
if (bprm->have_execfd) {
633632
nr = 0;
634633
csp -= 2 * sizeof(unsigned long);
635-
NEW_AUX_ENT(AT_EXECFD, bprm->interp_data);
634+
NEW_AUX_ENT(AT_EXECFD, bprm->execfd);
636635
}
637636

638637
nr = 0;

fs/binfmt_em86.c

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,6 @@ static int load_em86(struct linux_binprm *bprm)
4848
if (bprm->interp_flags & BINPRM_FLAGS_PATH_INACCESSIBLE)
4949
return -ENOENT;
5050

51-
allow_write_access(bprm->file);
52-
fput(bprm->file);
53-
bprm->file = NULL;
54-
5551
/* Unlike in the script case, we don't have to do any hairy
5652
* parsing to find our interpreter... it's hardcoded!
5753
*/
@@ -89,13 +85,8 @@ static int load_em86(struct linux_binprm *bprm)
8985
if (IS_ERR(file))
9086
return PTR_ERR(file);
9187

92-
bprm->file = file;
93-
94-
retval = prepare_binprm(bprm);
95-
if (retval < 0)
96-
return retval;
97-
98-
return search_binary_handler(bprm);
88+
bprm->interpreter = file;
89+
return 0;
9990
}
10091

10192
static struct linux_binfmt em86_format = {

fs/binfmt_flat.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ static int load_flat_file(struct linux_binprm *bprm,
534534

535535
/* Flush all traces of the currently running executable */
536536
if (id == 0) {
537-
ret = flush_old_exec(bprm);
537+
ret = begin_new_exec(bprm);
538538
if (ret)
539539
goto err;
540540

@@ -963,8 +963,6 @@ static int load_flat_binary(struct linux_binprm *bprm)
963963
}
964964
}
965965

966-
install_exec_creds(bprm);
967-
968966
set_binfmt(&flat_format);
969967

970968
#ifdef CONFIG_MMU

fs/binfmt_misc.c

Lines changed: 10 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,6 @@ static int load_misc_binary(struct linux_binprm *bprm)
134134
Node *fmt;
135135
struct file *interp_file = NULL;
136136
int retval;
137-
int fd_binary = -1;
138137

139138
retval = -ENOEXEC;
140139
if (!enabled)
@@ -160,51 +159,25 @@ static int load_misc_binary(struct linux_binprm *bprm)
160159
goto ret;
161160
}
162161

163-
if (fmt->flags & MISC_FMT_OPEN_BINARY) {
162+
if (fmt->flags & MISC_FMT_OPEN_BINARY)
163+
bprm->have_execfd = 1;
164164

165-
/* if the binary should be opened on behalf of the
166-
* interpreter than keep it open and assign descriptor
167-
* to it
168-
*/
169-
fd_binary = get_unused_fd_flags(0);
170-
if (fd_binary < 0) {
171-
retval = fd_binary;
172-
goto ret;
173-
}
174-
fd_install(fd_binary, bprm->file);
175-
176-
/* if the binary is not readable than enforce mm->dumpable=0
177-
regardless of the interpreter's permissions */
178-
would_dump(bprm, bprm->file);
179-
180-
allow_write_access(bprm->file);
181-
bprm->file = NULL;
182-
183-
/* mark the bprm that fd should be passed to interp */
184-
bprm->interp_flags |= BINPRM_FLAGS_EXECFD;
185-
bprm->interp_data = fd_binary;
186-
187-
} else {
188-
allow_write_access(bprm->file);
189-
fput(bprm->file);
190-
bprm->file = NULL;
191-
}
192165
/* make argv[1] be the path to the binary */
193166
retval = copy_strings_kernel(1, &bprm->interp, bprm);
194167
if (retval < 0)
195-
goto error;
168+
goto ret;
196169
bprm->argc++;
197170

198171
/* add the interp as argv[0] */
199172
retval = copy_strings_kernel(1, &fmt->interpreter, bprm);
200173
if (retval < 0)
201-
goto error;
174+
goto ret;
202175
bprm->argc++;
203176

204177
/* Update interp in case binfmt_script needs it. */
205178
retval = bprm_change_interp(fmt->interpreter, bprm);
206179
if (retval < 0)
207-
goto error;
180+
goto ret;
208181

209182
if (fmt->flags & MISC_FMT_OPEN_FILE) {
210183
interp_file = file_clone_open(fmt->interp_file);
@@ -215,38 +188,16 @@ static int load_misc_binary(struct linux_binprm *bprm)
215188
}
216189
retval = PTR_ERR(interp_file);
217190
if (IS_ERR(interp_file))
218-
goto error;
219-
220-
bprm->file = interp_file;
221-
if (fmt->flags & MISC_FMT_CREDENTIALS) {
222-
loff_t pos = 0;
223-
224-
/*
225-
* No need to call prepare_binprm(), it's already been
226-
* done. bprm->buf is stale, update from interp_file.
227-
*/
228-
memset(bprm->buf, 0, BINPRM_BUF_SIZE);
229-
retval = kernel_read(bprm->file, bprm->buf, BINPRM_BUF_SIZE,
230-
&pos);
231-
} else
232-
retval = prepare_binprm(bprm);
233-
234-
if (retval < 0)
235-
goto error;
191+
goto ret;
236192

237-
retval = search_binary_handler(bprm);
238-
if (retval < 0)
239-
goto error;
193+
bprm->interpreter = interp_file;
194+
if (fmt->flags & MISC_FMT_CREDENTIALS)
195+
bprm->execfd_creds = 1;
240196

197+
retval = 0;
241198
ret:
242199
dput(fmt->dentry);
243200
return retval;
244-
error:
245-
if (fd_binary > 0)
246-
ksys_close(fd_binary);
247-
bprm->interp_flags = 0;
248-
bprm->interp_data = 0;
249-
goto ret;
250201
}
251202

252203
/* Command parsers */

0 commit comments

Comments
 (0)