Skip to content

Commit

Permalink
Merge tag 'execve-v6.8-rc2' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/kees/linux

Pull execve fixes from Kees Cook:

 - Fix error handling in begin_new_exec() (Bernd Edlinger)

 - MAINTAINERS: specifically mention ELF (Alexey Dobriyan)

 - Various cleanups related to earlier open() (Askar Safin, Kees Cook)

* tag 'execve-v6.8-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
  exec: Distinguish in_execve from in_exec
  exec: Fix error handling in begin_new_exec()
  exec: Add do_close_execat() helper
  exec: remove useless comment
  ELF, MAINTAINERS: specifically mention ELF
  • Loading branch information
torvalds committed Jan 24, 2024
2 parents 3eab830 + 90383cc commit cf10015
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 11 deletions.
3 changes: 2 additions & 1 deletion MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -7955,12 +7955,13 @@ L: [email protected]
S: Maintained
F: rust/kernel/net/phy.rs

EXEC & BINFMT API
EXEC & BINFMT API, ELF
R: Eric Biederman <[email protected]>
R: Kees Cook <[email protected]>
L: [email protected]
S: Supported
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/execve
F: Documentation/userspace-api/ELF.rst
F: fs/*binfmt_*.c
F: fs/exec.c
F: include/linux/binfmts.h
Expand Down
39 changes: 30 additions & 9 deletions fs/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -904,6 +904,10 @@ EXPORT_SYMBOL(transfer_args_to_stack);

#endif /* CONFIG_MMU */

/*
* On success, caller must call do_close_execat() on the returned
* struct file to close it.
*/
static struct file *do_open_execat(int fd, struct filename *name, int flags)
{
struct file *file;
Expand Down Expand Up @@ -948,6 +952,17 @@ static struct file *do_open_execat(int fd, struct filename *name, int flags)
return ERR_PTR(err);
}

/**
* open_exec - Open a path name for execution
*
* @name: path name to open with the intent of executing it.
*
* Returns ERR_PTR on failure or allocated struct file on success.
*
* As this is a wrapper for the internal do_open_execat(), callers
* must call allow_write_access() before fput() on release. Also see
* do_close_execat().
*/
struct file *open_exec(const char *name)
{
struct filename *filename = getname_kernel(name);
Expand Down Expand Up @@ -1409,6 +1424,9 @@ int begin_new_exec(struct linux_binprm * bprm)

out_unlock:
up_write(&me->signal->exec_update_lock);
if (!bprm->cred)
mutex_unlock(&me->signal->cred_guard_mutex);

out:
return retval;
}
Expand Down Expand Up @@ -1484,6 +1502,15 @@ static int prepare_bprm_creds(struct linux_binprm *bprm)
return -ENOMEM;
}

/* Matches do_open_execat() */
static void do_close_execat(struct file *file)
{
if (!file)
return;
allow_write_access(file);
fput(file);
}

static void free_bprm(struct linux_binprm *bprm)
{
if (bprm->mm) {
Expand All @@ -1495,10 +1522,7 @@ static void free_bprm(struct linux_binprm *bprm)
mutex_unlock(&current->signal->cred_guard_mutex);
abort_creds(bprm->cred);
}
if (bprm->file) {
allow_write_access(bprm->file);
fput(bprm->file);
}
do_close_execat(bprm->file);
if (bprm->executable)
fput(bprm->executable);
/* If a binfmt changed the interp, free it. */
Expand All @@ -1520,8 +1544,7 @@ static struct linux_binprm *alloc_bprm(int fd, struct filename *filename, int fl

bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
if (!bprm) {
allow_write_access(file);
fput(file);
do_close_execat(file);
return ERR_PTR(-ENOMEM);
}

Expand Down Expand Up @@ -1610,6 +1633,7 @@ static void check_unsafe_exec(struct linux_binprm *bprm)
}
rcu_read_unlock();

/* "users" and "in_exec" locked for copy_fs() */
if (p->fs->users > n_fs)
bprm->unsafe |= LSM_UNSAFE_SHARE;
else
Expand Down Expand Up @@ -1826,9 +1850,6 @@ static int exec_binprm(struct linux_binprm *bprm)
return 0;
}

/*
* sys_execve() executes a new program.
*/
static int bprm_execve(struct linux_binprm *bprm)
{
int retval;
Expand Down
2 changes: 1 addition & 1 deletion include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -920,7 +920,7 @@ struct task_struct {
unsigned sched_rt_mutex:1;
#endif

/* Bit to tell LSMs we're in execve(): */
/* Bit to tell TOMOYO we're in execve(): */
unsigned in_execve:1;
unsigned in_iowait:1;
#ifndef TIF_RESTORE_SIGMASK
Expand Down
1 change: 1 addition & 0 deletions kernel/fork.c
Original file line number Diff line number Diff line change
Expand Up @@ -1748,6 +1748,7 @@ static int copy_fs(unsigned long clone_flags, struct task_struct *tsk)
if (clone_flags & CLONE_FS) {
/* tsk->fs is already what we want */
spin_lock(&fs->lock);
/* "users" and "in_exec" locked for check_unsafe_exec() */
if (fs->in_exec) {
spin_unlock(&fs->lock);
return -EAGAIN;
Expand Down

0 comments on commit cf10015

Please sign in to comment.