Messages in this thread Patch in this message | | | Subject | [PATCH 1/4] exec: Pass unshared files_struct to load_binary() | From | Kirill Tkhai <> | Date | Thu, 11 Jan 2018 18:50:03 +0300 |
| |
This patch adds pointer to new unshared files_struct to struct linux_binprm and makes load_misc_binary() method to use __alloc_fd() and __fd_install(), instead of alloc_fd() and fd_install(), which are related to current task. It's a preparation for next patch, that stops assigning of current->files before load_binary call. Since bprm->new_files == current->files now, this patch is just a preparation, and it don't change functionality. The only difference is export of two functions, that I pointed above.
load_misc_binary() is the only load_binary method modifying fd table, so other methods are not modified.
Note, that I don't replace sys_close(fd_binary) with __close_fd() in load_misc_binary(), because of next patch will kill this close completely, while __close_fd() requires to be exported too. It's pointless to export it and then to unexport it, so we skip this.
Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com> --- fs/binfmt_misc.c | 6 ++++-- fs/exec.c | 1 + fs/file.c | 2 ++ include/linux/binfmts.h | 1 + 4 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index a7c5a9861bef..13c1fae45717 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c @@ -19,6 +19,7 @@ #include <linux/ctype.h> #include <linux/string_helpers.h> #include <linux/file.h> +#include <linux/fdtable.h> #include <linux/pagemap.h> #include <linux/namei.h> #include <linux/mount.h> @@ -164,12 +165,13 @@ static int load_misc_binary(struct linux_binprm *bprm) * interpreter than keep it open and assign descriptor * to it */ - fd_binary = get_unused_fd_flags(0); + fd_binary = __alloc_fd(bprm->new_files, 0, + rlimit(RLIMIT_NOFILE), 0); if (fd_binary < 0) { retval = fd_binary; goto ret; } - fd_install(fd_binary, bprm->file); + __fd_install(bprm->new_files, fd_binary, bprm->file); /* if the binary is not readable than enforce mm->dumpable=0 regardless of the interpreter's permissions */ diff --git a/fs/exec.c b/fs/exec.c index 7eb8d21bcab9..4c3b924ae103 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1729,6 +1729,7 @@ static int do_execveat_common(int fd, struct filename *filename, bprm = kzalloc(sizeof(*bprm), GFP_KERNEL); if (!bprm) goto out_files; + bprm->new_files = current->files; retval = prepare_bprm_creds(bprm); if (retval) diff --git a/fs/file.c b/fs/file.c index fc0eeb812e2c..e578e5537c32 100644 --- a/fs/file.c +++ b/fs/file.c @@ -538,6 +538,7 @@ int __alloc_fd(struct files_struct *files, spin_unlock(&files->file_lock); return error; } +EXPORT_SYMBOL_GPL(__alloc_fd); static int alloc_fd(unsigned start, unsigned flags) { @@ -611,6 +612,7 @@ void __fd_install(struct files_struct *files, unsigned int fd, rcu_assign_pointer(fdt->fd[fd], file); rcu_read_unlock_sched(); } +EXPORT_SYMBOL_GPL(__fd_install); void fd_install(unsigned int fd, struct file *file) { diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index b0abe21d6cc9..1470be496ad2 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h @@ -24,6 +24,7 @@ struct linux_binprm { struct page *page[MAX_ARG_PAGES]; #endif struct mm_struct *mm; + struct files_struct *new_files; unsigned long p; /* current top of mem */ unsigned int /*
| |