forked from luck/tmp_suning_uos_patched
25cf336de5
Now that the last callser has been removed remove this code from exec. For anyone thinking of resurrecing do_execve_file please note that the code was buggy in several fundamental ways. - It did not ensure the file it was passed was read-only and that deny_write_access had been called on it. Which subtlely breaks invaniants in exec. - The caller of do_execve_file was expected to hold and put a reference to the file, but an extra reference for use by exec was not taken so that when exec put it's reference to the file an underflow occured on the file reference count. - The point of the interface was so that a pathname did not need to exist. Which breaks pathname based LSMs. Tetsuo Handa originally reported these issues[1]. While it was clear that deny_write_access was missing the fundamental incompatibility with the passed in O_RDWR filehandle was not immediately recognized. All of these issues were fixed by modifying the usermode driver code to have a path, so it did not need this hack. Reported-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> [1] https://lore.kernel.org/linux-fsdevel/2a8775b4-1dd5-9d5c-aa42-9872445e0942@i-love.sakura.ne.jp/ v1: https://lkml.kernel.org/r/871rm2f0hi.fsf_-_@x220.int.ebiederm.org v2: https://lkml.kernel.org/r/87lfk54p0m.fsf_-_@x220.int.ebiederm.org Link: https://lkml.kernel.org/r/20200702164140.4468-10-ebiederm@xmission.com Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Acked-by: Alexei Starovoitov <ast@kernel.org> Tested-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
146 lines
4.4 KiB
C
146 lines
4.4 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _LINUX_BINFMTS_H
|
|
#define _LINUX_BINFMTS_H
|
|
|
|
#include <linux/sched.h>
|
|
#include <linux/unistd.h>
|
|
#include <asm/exec.h>
|
|
#include <uapi/linux/binfmts.h>
|
|
|
|
struct filename;
|
|
|
|
#define CORENAME_MAX_SIZE 128
|
|
|
|
/*
|
|
* This structure is used to hold the arguments that are used when loading binaries.
|
|
*/
|
|
struct linux_binprm {
|
|
#ifdef CONFIG_MMU
|
|
struct vm_area_struct *vma;
|
|
unsigned long vma_pages;
|
|
#else
|
|
# define MAX_ARG_PAGES 32
|
|
struct page *page[MAX_ARG_PAGES];
|
|
#endif
|
|
struct mm_struct *mm;
|
|
unsigned long p; /* current top of mem */
|
|
unsigned long argmin; /* rlimit marker for copy_strings() */
|
|
unsigned int
|
|
/* Should an execfd be passed to userspace? */
|
|
have_execfd:1,
|
|
|
|
/* Use the creds of a script (see binfmt_misc) */
|
|
execfd_creds:1,
|
|
/*
|
|
* Set by bprm_creds_for_exec hook to indicate a
|
|
* privilege-gaining exec has happened. Used to set
|
|
* AT_SECURE auxv for glibc.
|
|
*/
|
|
secureexec:1,
|
|
/*
|
|
* Set when errors can no longer be returned to the
|
|
* original userspace.
|
|
*/
|
|
point_of_no_return:1;
|
|
#ifdef __alpha__
|
|
unsigned int taso:1;
|
|
#endif
|
|
struct file * executable; /* Executable to pass to the interpreter */
|
|
struct file * interpreter;
|
|
struct file * file;
|
|
struct cred *cred; /* new credentials */
|
|
int unsafe; /* how unsafe this exec is (mask of LSM_UNSAFE_*) */
|
|
unsigned int per_clear; /* bits to clear in current->personality */
|
|
int argc, envc;
|
|
const char * filename; /* Name of binary as seen by procps */
|
|
const char * interp; /* Name of the binary really executed. Most
|
|
of the time same as filename, but could be
|
|
different for binfmt_{misc,script} */
|
|
unsigned interp_flags;
|
|
int execfd; /* File descriptor of the executable */
|
|
unsigned long loader, exec;
|
|
|
|
struct rlimit rlim_stack; /* Saved RLIMIT_STACK used during exec. */
|
|
|
|
char buf[BINPRM_BUF_SIZE];
|
|
} __randomize_layout;
|
|
|
|
#define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
|
|
#define BINPRM_FLAGS_ENFORCE_NONDUMP (1 << BINPRM_FLAGS_ENFORCE_NONDUMP_BIT)
|
|
|
|
/* filename of the binary will be inaccessible after exec */
|
|
#define BINPRM_FLAGS_PATH_INACCESSIBLE_BIT 2
|
|
#define BINPRM_FLAGS_PATH_INACCESSIBLE (1 << BINPRM_FLAGS_PATH_INACCESSIBLE_BIT)
|
|
|
|
/* Function parameter for binfmt->coredump */
|
|
struct coredump_params {
|
|
const kernel_siginfo_t *siginfo;
|
|
struct pt_regs *regs;
|
|
struct file *file;
|
|
unsigned long limit;
|
|
unsigned long mm_flags;
|
|
loff_t written;
|
|
loff_t pos;
|
|
};
|
|
|
|
/*
|
|
* This structure defines the functions that are used to load the binary formats that
|
|
* linux accepts.
|
|
*/
|
|
struct linux_binfmt {
|
|
struct list_head lh;
|
|
struct module *module;
|
|
int (*load_binary)(struct linux_binprm *);
|
|
int (*load_shlib)(struct file *);
|
|
int (*core_dump)(struct coredump_params *cprm);
|
|
unsigned long min_coredump; /* minimal dump size */
|
|
} __randomize_layout;
|
|
|
|
extern void __register_binfmt(struct linux_binfmt *fmt, int insert);
|
|
|
|
/* Registration of default binfmt handlers */
|
|
static inline void register_binfmt(struct linux_binfmt *fmt)
|
|
{
|
|
__register_binfmt(fmt, 0);
|
|
}
|
|
/* Same as above, but adds a new binfmt at the top of the list */
|
|
static inline void insert_binfmt(struct linux_binfmt *fmt)
|
|
{
|
|
__register_binfmt(fmt, 1);
|
|
}
|
|
|
|
extern void unregister_binfmt(struct linux_binfmt *);
|
|
|
|
extern int __must_check remove_arg_zero(struct linux_binprm *);
|
|
extern int begin_new_exec(struct linux_binprm * bprm);
|
|
extern void setup_new_exec(struct linux_binprm * bprm);
|
|
extern void finalize_exec(struct linux_binprm *bprm);
|
|
extern void would_dump(struct linux_binprm *, struct file *);
|
|
|
|
extern int suid_dumpable;
|
|
|
|
/* Stack area protections */
|
|
#define EXSTACK_DEFAULT 0 /* Whatever the arch defaults to */
|
|
#define EXSTACK_DISABLE_X 1 /* Disable executable stacks */
|
|
#define EXSTACK_ENABLE_X 2 /* Enable executable stacks */
|
|
|
|
extern int setup_arg_pages(struct linux_binprm * bprm,
|
|
unsigned long stack_top,
|
|
int executable_stack);
|
|
extern int transfer_args_to_stack(struct linux_binprm *bprm,
|
|
unsigned long *sp_location);
|
|
extern int bprm_change_interp(const char *interp, struct linux_binprm *bprm);
|
|
int copy_string_kernel(const char *arg, struct linux_binprm *bprm);
|
|
extern void set_binfmt(struct linux_binfmt *new);
|
|
extern ssize_t read_code(struct file *, unsigned long, loff_t, size_t);
|
|
|
|
extern int do_execve(struct filename *,
|
|
const char __user * const __user *,
|
|
const char __user * const __user *);
|
|
extern int do_execveat(int, struct filename *,
|
|
const char __user * const __user *,
|
|
const char __user * const __user *,
|
|
int);
|
|
|
|
#endif /* _LINUX_BINFMTS_H */
|