Skip to content

Commit df9e4d2

Browse files
committed
exec: Move most of setup_new_exec into flush_old_exec
The current idiom for the callers is: flush_old_exec(bprm); set_personality(...); setup_new_exec(bprm); In 2010 Linus split flush_old_exec into flush_old_exec and setup_new_exec. With the intention that setup_new_exec be what is called after the processes new personality is set. Move the code that doesn't depend upon the personality from setup_new_exec into flush_old_exec. This is to facilitate future changes by having as much code together in one function as possible. To see why it is safe to move this code please note that effectively this change moves the personality setting in the binfmt and the following three lines of code after everything except unlocking the mutexes: arch_pick_mmap_layout arch_setup_new_exec mm->task_size = TASK_SIZE The function arch_pick_mmap_layout at most sets: mm->get_unmapped_area mm->mmap_base mm->mmap_legacy_base mm->mmap_compat_base mm->mmap_compat_legacy_base which nothing in flush_old_exec or setup_new_exec depends on. The function arch_setup_new_exec only sets architecture specific state and the rest of the functions only deal in state that applies to all architectures. The last line just sets mm->task_size and again nothing in flush_old_exec or setup_new_exec depend on task_size. Ref: 221af7f ("Split 'flush_old_exec' into two functions") Reviewed-by: Kees Cook <[email protected]> Reviewed-by: Greg Ungerer <[email protected]> Signed-off-by: "Eric W. Biederman" <[email protected]>
1 parent 7d503fe commit df9e4d2

File tree

1 file changed

+44
-41
lines changed

1 file changed

+44
-41
lines changed

fs/exec.c

Lines changed: 44 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,39 +1359,7 @@ int flush_old_exec(struct linux_binprm * bprm)
13591359
* undergoing exec(2).
13601360
*/
13611361
do_close_on_exec(me->files);
1362-
return 0;
1363-
1364-
out_unlock:
1365-
mutex_unlock(&me->signal->exec_update_mutex);
1366-
out:
1367-
return retval;
1368-
}
1369-
EXPORT_SYMBOL(flush_old_exec);
1370-
1371-
void would_dump(struct linux_binprm *bprm, struct file *file)
1372-
{
1373-
struct inode *inode = file_inode(file);
1374-
if (inode_permission(inode, MAY_READ) < 0) {
1375-
struct user_namespace *old, *user_ns;
1376-
bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
1377-
1378-
/* Ensure mm->user_ns contains the executable */
1379-
user_ns = old = bprm->mm->user_ns;
1380-
while ((user_ns != &init_user_ns) &&
1381-
!privileged_wrt_inode_uidgid(user_ns, inode))
1382-
user_ns = user_ns->parent;
13831362

1384-
if (old != user_ns) {
1385-
bprm->mm->user_ns = get_user_ns(user_ns);
1386-
put_user_ns(old);
1387-
}
1388-
}
1389-
}
1390-
EXPORT_SYMBOL(would_dump);
1391-
1392-
void setup_new_exec(struct linux_binprm * bprm)
1393-
{
1394-
struct task_struct *me = current;
13951363
/*
13961364
* Once here, prepare_binrpm() will not be called any more, so
13971365
* the final state of setuid/setgid/fscaps can be merged into the
@@ -1414,8 +1382,6 @@ void setup_new_exec(struct linux_binprm * bprm)
14141382
bprm->rlim_stack.rlim_cur = _STK_LIM;
14151383
}
14161384

1417-
arch_pick_mmap_layout(me->mm, &bprm->rlim_stack);
1418-
14191385
me->sas_ss_sp = me->sas_ss_size = 0;
14201386

14211387
/*
@@ -1430,16 +1396,9 @@ void setup_new_exec(struct linux_binprm * bprm)
14301396
else
14311397
set_dumpable(current->mm, SUID_DUMP_USER);
14321398

1433-
arch_setup_new_exec();
14341399
perf_event_exec();
14351400
__set_task_comm(me, kbasename(bprm->filename), true);
14361401

1437-
/* Set the new mm task size. We have to do that late because it may
1438-
* depend on TIF_32BIT which is only updated in flush_thread() on
1439-
* some architectures like powerpc
1440-
*/
1441-
me->mm->task_size = TASK_SIZE;
1442-
14431402
/* An exec changes our domain. We are no longer part of the thread
14441403
group */
14451404
WRITE_ONCE(me->self_exec_id, me->self_exec_id + 1);
@@ -1467,6 +1426,50 @@ void setup_new_exec(struct linux_binprm * bprm)
14671426
* credentials; any time after this it may be unlocked.
14681427
*/
14691428
security_bprm_committed_creds(bprm);
1429+
return 0;
1430+
1431+
out_unlock:
1432+
mutex_unlock(&me->signal->exec_update_mutex);
1433+
out:
1434+
return retval;
1435+
}
1436+
EXPORT_SYMBOL(flush_old_exec);
1437+
1438+
void would_dump(struct linux_binprm *bprm, struct file *file)
1439+
{
1440+
struct inode *inode = file_inode(file);
1441+
if (inode_permission(inode, MAY_READ) < 0) {
1442+
struct user_namespace *old, *user_ns;
1443+
bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
1444+
1445+
/* Ensure mm->user_ns contains the executable */
1446+
user_ns = old = bprm->mm->user_ns;
1447+
while ((user_ns != &init_user_ns) &&
1448+
!privileged_wrt_inode_uidgid(user_ns, inode))
1449+
user_ns = user_ns->parent;
1450+
1451+
if (old != user_ns) {
1452+
bprm->mm->user_ns = get_user_ns(user_ns);
1453+
put_user_ns(old);
1454+
}
1455+
}
1456+
}
1457+
EXPORT_SYMBOL(would_dump);
1458+
1459+
void setup_new_exec(struct linux_binprm * bprm)
1460+
{
1461+
/* Setup things that can depend upon the personality */
1462+
struct task_struct *me = current;
1463+
1464+
arch_pick_mmap_layout(me->mm, &bprm->rlim_stack);
1465+
1466+
arch_setup_new_exec();
1467+
1468+
/* Set the new mm task size. We have to do that late because it may
1469+
* depend on TIF_32BIT which is only updated in flush_thread() on
1470+
* some architectures like powerpc
1471+
*/
1472+
me->mm->task_size = TASK_SIZE;
14701473
mutex_unlock(&me->signal->exec_update_mutex);
14711474
mutex_unlock(&me->signal->cred_guard_mutex);
14721475
}

0 commit comments

Comments
 (0)