execve fixes for v6.8-rc2
- 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) -----BEGIN PGP SIGNATURE----- iQJKBAABCgA0FiEEpcP2jyKd1g9yPm4TiXL039xtwCYFAmWxbGsWHGtlZXNjb29r QGNocm9taXVtLm9yZwAKCRCJcvTf3G3AJiQZD/9Lxd6ntRORthvCGk07g12fGZhQ OstFdbHyk5/Z+6/uKxSMvkoPZwJkXF2n3D/AvlfMFgyDBvLCFUu08jZOV31YFbeQ OFXVGcbY7nexkAmC6eN2k3SX8E+jzLdbcHeVk/iJomNUYBNTpExXhGMEyqZ53Pzo fo1uaRNGreCdSP04aHU1LE0vx7p16553oBeBZFT+iLd4glLte+E1TOZh4cIaSZbK 5h0e+vG1XSBd9uP3fbYEyf+1JzKuhmm1RrVVaDkds1CLgJzUxh0cE1U9otKfnrwf xyBu556wTb001vYAIIcLlOJq+ROdiuA12RSyyHbKZmYAWTkQnBgKPV8BGDbshtzN zykJEsbRnWV3vN1n6+UzCEknE/xjvywEEdJgghZh46zk2NjnbtULOonLq8aMw7SA O+kcr4rqPLuRnxnkBw7QqA1y09QD9+M/iRQdgahsBIaDM3mMXGQsqeJAo9tFxO2M oJ1gJ9A7IdeULMBQ7zKVxTvC5c5fF2/CA5jpHUjASiUOTqcfHkPRYX2GINE62Heb xfsc3c1RhDrknMA/O01c8ziEBzZqhHUq4vGgWn0VjwIspYyfOOJYneeIx6/pJyTY OXbgaK+NetDCOKcv91Jjj0xfxrP0WogzvDbT9j2NuViqX24aQR1oZrredWPCTt5S wKouTaLVsM10EwR/Rw== =oOcx -----END PGP SIGNATURE----- Merge tag 'execve-v6.8-rc2' of git://git.kernel.org/pub/scm/linux/kernel/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
This commit is contained in:
commit
cf10015a24
@ -7955,12 +7955,13 @@ L: rust-for-linux@vger.kernel.org
|
||||
S: Maintained
|
||||
F: rust/kernel/net/phy.rs
|
||||
|
||||
EXEC & BINFMT API
|
||||
EXEC & BINFMT API, ELF
|
||||
R: Eric Biederman <ebiederm@xmission.com>
|
||||
R: Kees Cook <keescook@chromium.org>
|
||||
L: linux-mm@kvack.org
|
||||
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
|
||||
|
39
fs/exec.c
39
fs/exec.c
@ -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;
|
||||
@ -948,6 +952,17 @@ exit:
|
||||
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);
|
||||
@ -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;
|
||||
}
|
||||
@ -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) {
|
||||
@ -1495,10 +1522,7 @@ static void free_bprm(struct linux_binprm *bprm)
|
||||
mutex_unlock(¤t->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. */
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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
|
||||
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user