Skip to content

Commit

Permalink
Merge branch 'exec-for-v5.11' of git://git.kernel.org/pub/scm/linux/k…
Browse files Browse the repository at this point in the history
…ernel/git/ebiederm/user-namespace

Pull execve updates from Eric Biederman:
 "This set of changes ultimately fixes the interaction of posix file
  lock and exec. Fundamentally most of the change is just moving where
  unshare_files is called during exec, and tweaking the users of
  files_struct so that the count of files_struct is not unnecessarily
  played with.

  Along the way fcheck and related helpers were renamed to more
  accurately reflect what they do.

  There were also many other small changes that fell out, as this is the
  first time in a long time much of this code has been touched.

  Benchmarks haven't turned up any practical issues but Al Viro has
  observed a possibility for a lot of pounding on task_lock. So I have
  some changes in progress to convert put_files_struct to always rcu
  free files_struct. That wasn't ready for the merge window so that will
  have to wait until next time"

* 'exec-for-v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace: (27 commits)
  exec: Move io_uring_task_cancel after the point of no return
  coredump: Document coredump code exclusively used by cell spufs
  file: Remove get_files_struct
  file: Rename __close_fd_get_file close_fd_get_file
  file: Replace ksys_close with close_fd
  file: Rename __close_fd to close_fd and remove the files parameter
  file: Merge __alloc_fd into alloc_fd
  file: In f_dupfd read RLIMIT_NOFILE once.
  file: Merge __fd_install into fd_install
  proc/fd: In fdinfo seq_show don't use get_files_struct
  bpf/task_iter: In task_file_seq_get_next use task_lookup_next_fd_rcu
  proc/fd: In proc_readfd_common use task_lookup_next_fd_rcu
  file: Implement task_lookup_next_fd_rcu
  kcmp: In get_file_raw_ptr use task_lookup_fd_rcu
  proc/fd: In tid_fd_mode use task_lookup_fd_rcu
  file: Implement task_lookup_fd_rcu
  file: Rename fcheck lookup_fd_rcu
  file: Replace fcheck_files with files_lookup_fd_rcu
  file: Factor files_lookup_fd_locked out of fcheck_files
  file: Rename __fcheck_files to files_lookup_fd_raw
  ...
  • Loading branch information
torvalds committed Dec 16, 2020
2 parents 6febd8b + 9ee1206 commit faf145d
Show file tree
Hide file tree
Showing 19 changed files with 158 additions and 244 deletions.
8 changes: 4 additions & 4 deletions Documentation/filesystems/files.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,15 @@ the fdtable structure -
be held.

4. To look up the file structure given an fd, a reader
must use either fcheck() or fcheck_files() APIs. These
must use either lookup_fd_rcu() or files_lookup_fd_rcu() APIs. These
take care of barrier requirements due to lock-free lookup.

An example::

struct file *file;
rcu_read_lock();
file = fcheck(fd);
file = lookup_fd_rcu(fd);
if (file) {
...
}
Expand All @@ -84,7 +84,7 @@ the fdtable structure -
on ->f_count::

rcu_read_lock();
file = fcheck_files(files, fd);
file = files_lookup_fd_rcu(files, fd);
if (file) {
if (atomic_long_inc_not_zero(&file->f_count))
*fput_needed = 1;
Expand All @@ -104,7 +104,7 @@ the fdtable structure -
lock-free, they must be installed using rcu_assign_pointer()
API. If they are looked up lock-free, rcu_dereference()
must be used. However it is advisable to use files_fdtable()
and fcheck()/fcheck_files() which take care of these issues.
and lookup_fd_rcu()/files_lookup_fd_rcu() which take care of these issues.

7. While updating, the fdtable pointer must be looked up while
holding files->file_lock. If ->file_lock is dropped, then
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/platforms/cell/spufs/coredump.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ static struct spu_context *coredump_next_context(int *fd)
*fd = n - 1;

rcu_read_lock();
file = fcheck(*fd);
file = lookup_fd_rcu(*fd);
ctx = SPUFS_I(file_inode(file))->i_ctx;
get_spu_context(ctx);
rcu_read_unlock();
Expand Down
2 changes: 1 addition & 1 deletion drivers/android/binder.c
Original file line number Diff line number Diff line change
Expand Up @@ -1836,7 +1836,7 @@ static void binder_deferred_fd_close(int fd)
if (!twcb)
return;
init_task_work(&twcb->twork, binder_do_fd_close);
__close_fd_get_file(fd, &twcb->file);
close_fd_get_file(fd, &twcb->file);
if (twcb->file) {
filp_close(twcb->file, current->files);
task_work_add(current, &twcb->twork, TWA_RESUME);
Expand Down
5 changes: 3 additions & 2 deletions fs/autofs/dev-ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
* Copyright 2008 Ian Kent <[email protected]>
*/

#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/compat.h>
#include <linux/syscalls.h>
#include <linux/fdtable.h>
#include <linux/magic.h>
#include <linux/nospec.h>

Expand Down Expand Up @@ -289,7 +290,7 @@ static int autofs_dev_ioctl_closemount(struct file *fp,
struct autofs_sb_info *sbi,
struct autofs_dev_ioctl *param)
{
return ksys_close(param->ioctlfd);
return close_fd(param->ioctlfd);
}

/*
Expand Down
2 changes: 2 additions & 0 deletions fs/binfmt_elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -2198,6 +2198,7 @@ static int elf_core_dump(struct coredump_params *cprm)
{
size_t sz = get_note_info_size(&info);

/* For cell spufs */
sz += elf_coredump_extra_notes_size();

phdr4note = kmalloc(sizeof(*phdr4note), GFP_KERNEL);
Expand Down Expand Up @@ -2261,6 +2262,7 @@ static int elf_core_dump(struct coredump_params *cprm)
if (!write_note_info(&info, cprm))
goto end_coredump;

/* For cell spufs */
if (elf_coredump_extra_notes_write(cprm))
goto end_coredump;

Expand Down
6 changes: 2 additions & 4 deletions fs/coredump.c
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,6 @@ void do_coredump(const kernel_siginfo_t *siginfo)
int ispipe;
size_t *argv = NULL;
int argc = 0;
struct files_struct *displaced;
/* require nonrelative corefile path and be extra careful */
bool need_suid_safe = false;
bool core_dumped = false;
Expand Down Expand Up @@ -792,11 +791,10 @@ void do_coredump(const kernel_siginfo_t *siginfo)
}

/* get us an unshared descriptor table; almost always a no-op */
retval = unshare_files(&displaced);
/* The cell spufs coredump code reads the file descriptor tables */
retval = unshare_files();
if (retval)
goto close_fail;
if (displaced)
put_files_struct(displaced);
if (!dump_interrupted()) {
/*
* umh disabled with CONFIG_STATIC_USERMODEHELPER_PATH="" would
Expand Down
39 changes: 18 additions & 21 deletions fs/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1258,6 +1258,16 @@ int begin_new_exec(struct linux_binprm * bprm)
if (retval)
goto out;

/*
* Cancel any io_uring activity across execve
*/
io_uring_task_cancel();

/* Ensure the files table is not shared. */
retval = unshare_files();
if (retval)
goto out;

/*
* Must be called _before_ exec_mmap() as bprm->mm is
* not visibile until then. This also enables the update
Expand Down Expand Up @@ -1779,21 +1789,11 @@ static int bprm_execve(struct linux_binprm *bprm,
int fd, struct filename *filename, int flags)
{
struct file *file;
struct files_struct *displaced;
int retval;

/*
* Cancel any io_uring activity across execve
*/
io_uring_task_cancel();

retval = unshare_files(&displaced);
if (retval)
return retval;

retval = prepare_bprm_creds(bprm);
if (retval)
goto out_files;
return retval;

check_unsafe_exec(bprm);
current->in_execve = 1;
Expand All @@ -1808,11 +1808,14 @@ static int bprm_execve(struct linux_binprm *bprm,
bprm->file = file;
/*
* Record that a name derived from an O_CLOEXEC fd will be
* inaccessible after exec. Relies on having exclusive access to
* current->files (due to unshare_files above).
* inaccessible after exec. This allows the code in exec to
* choose to fail when the executable is not mmaped into the
* interpreter and an open file descriptor is not passed to
* the interpreter. This makes for a better user experience
* than having the interpreter start and then immediately fail
* when it finds the executable is inaccessible.
*/
if (bprm->fdpath &&
close_on_exec(fd, rcu_dereference_raw(current->files->fdt)))
if (bprm->fdpath && get_close_on_exec(fd))
bprm->interp_flags |= BINPRM_FLAGS_PATH_INACCESSIBLE;

/* Set the unchanging part of bprm->cred */
Expand All @@ -1830,8 +1833,6 @@ static int bprm_execve(struct linux_binprm *bprm,
rseq_execve(current);
acct_update_integrals(current);
task_numa_free(current, false);
if (displaced)
put_files_struct(displaced);
return retval;

out:
Expand All @@ -1848,10 +1849,6 @@ static int bprm_execve(struct linux_binprm *bprm,
current->fs->in_exec = 0;
current->in_execve = 0;

out_files:
if (displaced)
reset_files_struct(displaced);

return retval;
}

Expand Down
Loading

0 comments on commit faf145d

Please sign in to comment.