execve updates for v6.1-rc1
- Remove a.out implementation globally (Eric W. Biederman) - Remove unused linux_binprm::taso member (Lukas Bulwahn) -----BEGIN PGP SIGNATURE----- iQJKBAABCgA0FiEEpcP2jyKd1g9yPm4TiXL039xtwCYFAmM4bQsWHGtlZXNjb29r QGNocm9taXVtLm9yZwAKCRCJcvTf3G3AJkftD/4gTcnAd3BCUgerhiQfq64kYNPt l47p0BM6GzXvl1Mf4Q0TDV35WJ/JD5Yd3ij3V7J2XJWSHANUAlHbxm9yfChVLACU 99YRVhuWSdohJkF7p0b8dkAQO551aeodj/JUKGiNrJyNR4L336r+YG5aqEjOSPji jQH5I4SonDeaGdLy8nYO/aRhEryIF1FqvLH6egNp6Tt8Q69UqDYIojdCgZ/MS5lb dldrFsDb3ZjoXET0NdeIzZEZVS6zDM2iehb2W8dtRFoNsjMXz4jSiy7AEoprETBz wAKZ16t0dj2sARLLVGL8i3m2k6tzD6zzkIIoc9X3VOyeOADa6aghagDMyDpRo6ZB 2ML7wMNCHCboCVVfG3n2rWTIFmrqeycAiny0hZxU4bjBBYSxTK4qD9lFQtlXk0cD BESZhnM6gg87vVFgLV/8aefCvwRd5eb8Pugtwb3qF4NsSvgosZtIXhWnIeU3cjg2 425+4XOPbLsBv/u8NVkG8yIHaHZbtXH78JDIcNFMgSvw9iBwn2NH9184EpHI4qRx 9aBjHPz+VOqzPTnNR6ISP5J4VXaOvHeocb/ckbrS+xhY8zQmbWX9QHaAZ+XnDYby PVY0HjmYTFSlijHSRhqLqNMHwtOAeiSZwJNk4wh+39H0ynpTzThGjQ9NlGYQ5cUE TVF5ukO5QRa5GbmhIQ== =Ns31 -----END PGP SIGNATURE----- Merge tag 'execve-v6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux Pull execve updates from Kees Cook: "This removes a.out support globally; it has been disabled for a while now. - Remove a.out implementation globally (Eric W. Biederman) - Remove unused linux_binprm::taso member (Lukas Bulwahn)" * tag 'execve-v6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: binfmt: remove taso from linux_binprm struct a.out: Remove the a.out implementation
This commit is contained in:
commit
12ed00ba01
@ -7685,7 +7685,6 @@ 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: arch/alpha/kernel/binfmt_loader.c
|
||||
F: fs/*binfmt_*.c
|
||||
F: fs/exec.c
|
||||
F: include/linux/binfmts.h
|
||||
|
@ -1,16 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ALPHA_A_OUT_H__
|
||||
#define __ALPHA_A_OUT_H__
|
||||
|
||||
#include <uapi/asm/a.out.h>
|
||||
|
||||
|
||||
/* Assume that start addresses below 4G belong to a TASO application.
|
||||
Unfortunately, there is no proper bit in the exec header to check.
|
||||
Worse, we have to notice the start address before swapping to use
|
||||
/sbin/loader, which of course is _not_ a TASO application. */
|
||||
#define SET_AOUT_PERSONALITY(BFPM, EX) \
|
||||
set_personality (((BFPM->taso || EX.ah.entry < 0x100000000L \
|
||||
? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
|
||||
|
||||
#endif /* __A_OUT_GNU_H__ */
|
@ -47,10 +47,6 @@ else
|
||||
# Misc support
|
||||
obj-$(CONFIG_ALPHA_SRM) += srmcons.o
|
||||
|
||||
ifdef CONFIG_BINFMT_AOUT
|
||||
obj-y += binfmt_loader.o
|
||||
endif
|
||||
|
||||
# Core logic support
|
||||
obj-$(CONFIG_ALPHA_APECS) += core_apecs.o
|
||||
obj-$(CONFIG_ALPHA_CIA) += core_cia.o
|
||||
|
@ -1,46 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/init.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/mm_types.h>
|
||||
#include <linux/binfmts.h>
|
||||
#include <linux/a.out.h>
|
||||
|
||||
static int load_binary(struct linux_binprm *bprm)
|
||||
{
|
||||
struct exec *eh = (struct exec *)bprm->buf;
|
||||
unsigned long loader;
|
||||
struct file *file;
|
||||
int retval;
|
||||
|
||||
if (eh->fh.f_magic != 0x183 || (eh->fh.f_flags & 0x3000) != 0x3000)
|
||||
return -ENOEXEC;
|
||||
|
||||
if (bprm->loader)
|
||||
return -ENOEXEC;
|
||||
|
||||
loader = bprm->vma->vm_end - sizeof(void *);
|
||||
|
||||
file = open_exec("/sbin/loader");
|
||||
retval = PTR_ERR(file);
|
||||
if (IS_ERR(file))
|
||||
return retval;
|
||||
|
||||
/* Remember if the application is TASO. */
|
||||
bprm->taso = eh->ah.entry < 0x100000000UL;
|
||||
|
||||
bprm->interpreter = file;
|
||||
bprm->loader = loader;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct linux_binfmt loader_format = {
|
||||
.load_binary = load_binary,
|
||||
};
|
||||
|
||||
static int __init init_loader_binfmt(void)
|
||||
{
|
||||
insert_binfmt(&loader_format);
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(init_loader_binfmt);
|
@ -1278,45 +1278,15 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
|
||||
return addr;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OSF4_COMPAT
|
||||
/* Clear top 32 bits of iov_len in the user's buffer for
|
||||
compatibility with old versions of OSF/1 where iov_len
|
||||
was defined as int. */
|
||||
static int
|
||||
osf_fix_iov_len(const struct iovec __user *iov, unsigned long count)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
for (i = 0 ; i < count ; i++) {
|
||||
int __user *iov_len_high = (int __user *)&iov[i].iov_len + 1;
|
||||
|
||||
if (put_user(0, iov_len_high))
|
||||
return -EFAULT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
SYSCALL_DEFINE3(osf_readv, unsigned long, fd,
|
||||
const struct iovec __user *, vector, unsigned long, count)
|
||||
{
|
||||
#ifdef CONFIG_OSF4_COMPAT
|
||||
if (unlikely(personality(current->personality) == PER_OSF4))
|
||||
if (osf_fix_iov_len(vector, count))
|
||||
return -EFAULT;
|
||||
#endif
|
||||
|
||||
return sys_readv(fd, vector, count);
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE3(osf_writev, unsigned long, fd,
|
||||
const struct iovec __user *, vector, unsigned long, count)
|
||||
{
|
||||
#ifdef CONFIG_OSF4_COMPAT
|
||||
if (unlikely(personality(current->personality) == PER_OSF4))
|
||||
if (osf_fix_iov_len(vector, count))
|
||||
return -EFAULT;
|
||||
#endif
|
||||
return sys_writev(fd, vector, count);
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,6 @@ CONFIG_UNUSED_BOARD_FILES=y
|
||||
CONFIG_CMDLINE="init=/linuxrc root=/dev/mtdblock3"
|
||||
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
|
||||
CONFIG_FPE_NWFPE=y
|
||||
CONFIG_BINFMT_AOUT=m
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODVERSIONS=y
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
|
@ -16,7 +16,6 @@ CONFIG_MACH_HUSKY=y
|
||||
CONFIG_UNUSED_BOARD_FILES=y
|
||||
CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/mtdblock2 rootfstype=jffs2 debug"
|
||||
CONFIG_FPE_NWFPE=y
|
||||
CONFIG_BINFMT_AOUT=m
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_MODULE_FORCE_UNLOAD=y
|
||||
|
@ -25,7 +25,6 @@ CONFIG_CPU_FREQ_GOV_ONDEMAND=m
|
||||
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
|
||||
CONFIG_CPU_IDLE=y
|
||||
CONFIG_FPE_NWFPE=y
|
||||
CONFIG_BINFMT_AOUT=m
|
||||
CONFIG_PM=y
|
||||
CONFIG_APM_EMULATION=y
|
||||
CONFIG_MODULES=y
|
||||
|
@ -9,7 +9,6 @@ CONFIG_ARCH_EBSA285_HOST=y
|
||||
CONFIG_ARCH_NETWINDER=y
|
||||
CONFIG_FPE_NWFPE=y
|
||||
CONFIG_FPE_NWFPE_XP=y
|
||||
CONFIG_BINFMT_AOUT=y
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
CONFIG_ACORN_PARTITION=y
|
||||
|
@ -7,7 +7,6 @@ CONFIG_UNUSED_BOARD_FILES=y
|
||||
CONFIG_CMDLINE="console=ttySA0,115200 root=/dev/ram0 initrd=0xc0400000,8M init=/rootshell"
|
||||
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
|
||||
CONFIG_FPE_NWFPE=y
|
||||
CONFIG_BINFMT_AOUT=y
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
|
@ -12,7 +12,6 @@ CONFIG_MACH_N2100=y
|
||||
CONFIG_UNUSED_BOARD_FILES=y
|
||||
CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp cachepolicy=writealloc"
|
||||
CONFIG_FPE_NWFPE=y
|
||||
CONFIG_BINFMT_AOUT=y
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
|
@ -6,7 +6,6 @@ CONFIG_SA1100_JORNADA720=y
|
||||
CONFIG_SA1100_JORNADA720_SSP=y
|
||||
CONFIG_UNUSED_BOARD_FILES=y
|
||||
CONFIG_FPE_NWFPE=y
|
||||
CONFIG_BINFMT_AOUT=y
|
||||
CONFIG_PM=y
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_NET=y
|
||||
|
@ -8,7 +8,6 @@ CONFIG_CMDLINE="console=ttySA0,9600 root=/dev/ram"
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
|
||||
CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
CONFIG_FPE_NWFPE=y
|
||||
CONFIG_BINFMT_AOUT=y
|
||||
CONFIG_PM=y
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_NET=y
|
||||
|
@ -9,7 +9,6 @@ CONFIG_ZBOOT_ROM_BSS=0xc1000000
|
||||
CONFIG_ZBOOT_ROM=y
|
||||
CONFIG_CMDLINE="console=ttySA0,38400n8 cpufreq=221200 rw root=/dev/mtdblock2 mtdparts=sa1100:512K(boot),1M(kernel),2560K(initrd),4M(root) load_ramdisk=1 prompt_ramdisk=0 mem=32M noinitrd initrd=0xc0800000,3M"
|
||||
CONFIG_FPE_NWFPE=y
|
||||
CONFIG_BINFMT_AOUT=y
|
||||
CONFIG_PM=y
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
|
@ -5,7 +5,6 @@ CONFIG_ARCH_NETWINDER=y
|
||||
CONFIG_DEPRECATED_PARAM_STRUCT=y
|
||||
CONFIG_CMDLINE="root=0x801"
|
||||
CONFIG_FPE_NWFPE=y
|
||||
CONFIG_BINFMT_AOUT=y
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
|
@ -7,7 +7,6 @@ CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_ARCH_RPC=y
|
||||
CONFIG_CPU_SA110=y
|
||||
CONFIG_FPE_NWFPE=y
|
||||
CONFIG_BINFMT_AOUT=y
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
CONFIG_BSD_DISKLABEL=y
|
||||
CONFIG_SLAB=y
|
||||
|
@ -13,7 +13,6 @@ CONFIG_MACH_AKITA=y
|
||||
CONFIG_MACH_BORZOI=y
|
||||
CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/mtdblock2 rootfstype=jffs2 debug"
|
||||
CONFIG_FPE_NWFPE=y
|
||||
CONFIG_BINFMT_AOUT=m
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_MODULE_FORCE_UNLOAD=y
|
||||
|
@ -142,39 +142,6 @@ config BINFMT_ZFLAT
|
||||
help
|
||||
Support FLAT format compressed binaries
|
||||
|
||||
config HAVE_AOUT
|
||||
def_bool n
|
||||
|
||||
config BINFMT_AOUT
|
||||
tristate "Kernel support for a.out and ECOFF binaries"
|
||||
depends on HAVE_AOUT
|
||||
help
|
||||
A.out (Assembler.OUTput) is a set of formats for libraries and
|
||||
executables used in the earliest versions of UNIX. Linux used
|
||||
the a.out formats QMAGIC and ZMAGIC until they were replaced
|
||||
with the ELF format.
|
||||
|
||||
The conversion to ELF started in 1995. This option is primarily
|
||||
provided for historical interest and for the benefit of those
|
||||
who need to run binaries from that era.
|
||||
|
||||
Most people should answer N here. If you think you may have
|
||||
occasional use for this format, enable module support above
|
||||
and answer M here to compile this support as a module called
|
||||
binfmt_aout.
|
||||
|
||||
If any crucial components of your system (such as /sbin/init
|
||||
or /lib/ld.so) are still in a.out format, you will have to
|
||||
say Y here.
|
||||
|
||||
config OSF4_COMPAT
|
||||
bool "OSF/1 v4 readv/writev compatibility"
|
||||
depends on ALPHA && BINFMT_AOUT
|
||||
help
|
||||
Say Y if you are using OSF/1 binaries (like Netscape and Acrobat)
|
||||
with v4 shared libraries freely available from Compaq. If you're
|
||||
going to use shared libraries from Tru64 version 5.0 or later, say N.
|
||||
|
||||
config BINFMT_MISC
|
||||
tristate "Kernel support for MISC binaries"
|
||||
help
|
||||
|
@ -38,7 +38,6 @@ obj-$(CONFIG_FS_DAX) += dax.o
|
||||
obj-$(CONFIG_FS_ENCRYPTION) += crypto/
|
||||
obj-$(CONFIG_FS_VERITY) += verity/
|
||||
obj-$(CONFIG_FILE_LOCKING) += locks.o
|
||||
obj-$(CONFIG_BINFMT_AOUT) += binfmt_aout.o
|
||||
obj-$(CONFIG_BINFMT_MISC) += binfmt_misc.o
|
||||
obj-$(CONFIG_BINFMT_SCRIPT) += binfmt_script.o
|
||||
obj-$(CONFIG_BINFMT_ELF) += binfmt_elf.o
|
||||
|
342
fs/binfmt_aout.c
342
fs/binfmt_aout.c
@ -1,342 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* linux/fs/binfmt_aout.c
|
||||
*
|
||||
* Copyright (C) 1991, 1992, 1996 Linus Torvalds
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <linux/time.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/mman.h>
|
||||
#include <linux/a.out.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/user.h>
|
||||
#include <linux/binfmts.h>
|
||||
#include <linux/personality.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/coredump.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sched/task_stack.h>
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
static int load_aout_binary(struct linux_binprm *);
|
||||
static int load_aout_library(struct file*);
|
||||
|
||||
static struct linux_binfmt aout_format = {
|
||||
.module = THIS_MODULE,
|
||||
.load_binary = load_aout_binary,
|
||||
.load_shlib = load_aout_library,
|
||||
};
|
||||
|
||||
#define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE)
|
||||
|
||||
static int set_brk(unsigned long start, unsigned long end)
|
||||
{
|
||||
start = PAGE_ALIGN(start);
|
||||
end = PAGE_ALIGN(end);
|
||||
if (end > start)
|
||||
return vm_brk(start, end - start);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* create_aout_tables() parses the env- and arg-strings in new user
|
||||
* memory and creates the pointer tables from them, and puts their
|
||||
* addresses on the "stack", returning the new stack pointer value.
|
||||
*/
|
||||
static unsigned long __user *create_aout_tables(char __user *p, struct linux_binprm * bprm)
|
||||
{
|
||||
char __user * __user *argv;
|
||||
char __user * __user *envp;
|
||||
unsigned long __user *sp;
|
||||
int argc = bprm->argc;
|
||||
int envc = bprm->envc;
|
||||
|
||||
sp = (void __user *)((-(unsigned long)sizeof(char *)) & (unsigned long) p);
|
||||
#ifdef __alpha__
|
||||
/* whee.. test-programs are so much fun. */
|
||||
put_user(0, --sp);
|
||||
put_user(0, --sp);
|
||||
if (bprm->loader) {
|
||||
put_user(0, --sp);
|
||||
put_user(1003, --sp);
|
||||
put_user(bprm->loader, --sp);
|
||||
put_user(1002, --sp);
|
||||
}
|
||||
put_user(bprm->exec, --sp);
|
||||
put_user(1001, --sp);
|
||||
#endif
|
||||
sp -= envc+1;
|
||||
envp = (char __user * __user *) sp;
|
||||
sp -= argc+1;
|
||||
argv = (char __user * __user *) sp;
|
||||
#ifndef __alpha__
|
||||
put_user((unsigned long) envp,--sp);
|
||||
put_user((unsigned long) argv,--sp);
|
||||
#endif
|
||||
put_user(argc,--sp);
|
||||
current->mm->arg_start = (unsigned long) p;
|
||||
while (argc-->0) {
|
||||
char c;
|
||||
put_user(p,argv++);
|
||||
do {
|
||||
get_user(c,p++);
|
||||
} while (c);
|
||||
}
|
||||
put_user(NULL,argv);
|
||||
current->mm->arg_end = current->mm->env_start = (unsigned long) p;
|
||||
while (envc-->0) {
|
||||
char c;
|
||||
put_user(p,envp++);
|
||||
do {
|
||||
get_user(c,p++);
|
||||
} while (c);
|
||||
}
|
||||
put_user(NULL,envp);
|
||||
current->mm->env_end = (unsigned long) p;
|
||||
return sp;
|
||||
}
|
||||
|
||||
/*
|
||||
* These are the functions used to load a.out style executables and shared
|
||||
* libraries. There is no binary dependent code anywhere else.
|
||||
*/
|
||||
|
||||
static int load_aout_binary(struct linux_binprm * bprm)
|
||||
{
|
||||
struct pt_regs *regs = current_pt_regs();
|
||||
struct exec ex;
|
||||
unsigned long error;
|
||||
unsigned long fd_offset;
|
||||
unsigned long rlim;
|
||||
int retval;
|
||||
|
||||
ex = *((struct exec *) bprm->buf); /* exec-header */
|
||||
if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC &&
|
||||
N_MAGIC(ex) != QMAGIC && N_MAGIC(ex) != NMAGIC) ||
|
||||
N_TRSIZE(ex) || N_DRSIZE(ex) ||
|
||||
i_size_read(file_inode(bprm->file)) < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) {
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
/*
|
||||
* Requires a mmap handler. This prevents people from using a.out
|
||||
* as part of an exploit attack against /proc-related vulnerabilities.
|
||||
*/
|
||||
if (!bprm->file->f_op->mmap)
|
||||
return -ENOEXEC;
|
||||
|
||||
fd_offset = N_TXTOFF(ex);
|
||||
|
||||
/* Check initial limits. This avoids letting people circumvent
|
||||
* size limits imposed on them by creating programs with large
|
||||
* arrays in the data or bss.
|
||||
*/
|
||||
rlim = rlimit(RLIMIT_DATA);
|
||||
if (rlim >= RLIM_INFINITY)
|
||||
rlim = ~0;
|
||||
if (ex.a_data + ex.a_bss > rlim)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Flush all traces of the currently running executable */
|
||||
retval = begin_new_exec(bprm);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
/* OK, This is the point of no return */
|
||||
#ifdef __alpha__
|
||||
SET_AOUT_PERSONALITY(bprm, ex);
|
||||
#else
|
||||
set_personality(PER_LINUX);
|
||||
#endif
|
||||
setup_new_exec(bprm);
|
||||
|
||||
current->mm->end_code = ex.a_text +
|
||||
(current->mm->start_code = N_TXTADDR(ex));
|
||||
current->mm->end_data = ex.a_data +
|
||||
(current->mm->start_data = N_DATADDR(ex));
|
||||
current->mm->brk = ex.a_bss +
|
||||
(current->mm->start_brk = N_BSSADDR(ex));
|
||||
|
||||
retval = setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
|
||||
|
||||
if (N_MAGIC(ex) == OMAGIC) {
|
||||
unsigned long text_addr, map_size;
|
||||
loff_t pos;
|
||||
|
||||
text_addr = N_TXTADDR(ex);
|
||||
|
||||
#ifdef __alpha__
|
||||
pos = fd_offset;
|
||||
map_size = ex.a_text+ex.a_data + PAGE_SIZE - 1;
|
||||
#else
|
||||
pos = 32;
|
||||
map_size = ex.a_text+ex.a_data;
|
||||
#endif
|
||||
error = vm_brk(text_addr & PAGE_MASK, map_size);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = read_code(bprm->file, text_addr, pos,
|
||||
ex.a_text+ex.a_data);
|
||||
if ((signed long)error < 0)
|
||||
return error;
|
||||
} else {
|
||||
if ((ex.a_text & 0xfff || ex.a_data & 0xfff) &&
|
||||
(N_MAGIC(ex) != NMAGIC) && printk_ratelimit())
|
||||
{
|
||||
printk(KERN_NOTICE "executable not page aligned\n");
|
||||
}
|
||||
|
||||
if ((fd_offset & ~PAGE_MASK) != 0 && printk_ratelimit())
|
||||
{
|
||||
printk(KERN_WARNING
|
||||
"fd_offset is not page aligned. Please convert program: %pD\n",
|
||||
bprm->file);
|
||||
}
|
||||
|
||||
if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) {
|
||||
error = vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
read_code(bprm->file, N_TXTADDR(ex), fd_offset,
|
||||
ex.a_text + ex.a_data);
|
||||
goto beyond_if;
|
||||
}
|
||||
|
||||
error = vm_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
|
||||
PROT_READ | PROT_EXEC, MAP_FIXED | MAP_PRIVATE,
|
||||
fd_offset);
|
||||
|
||||
if (error != N_TXTADDR(ex))
|
||||
return error;
|
||||
|
||||
error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
|
||||
PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||
MAP_FIXED | MAP_PRIVATE,
|
||||
fd_offset + ex.a_text);
|
||||
if (error != N_DATADDR(ex))
|
||||
return error;
|
||||
}
|
||||
beyond_if:
|
||||
set_binfmt(&aout_format);
|
||||
|
||||
retval = set_brk(current->mm->start_brk, current->mm->brk);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
|
||||
current->mm->start_stack =
|
||||
(unsigned long) create_aout_tables((char __user *) bprm->p, bprm);
|
||||
#ifdef __alpha__
|
||||
regs->gp = ex.a_gpvalue;
|
||||
#endif
|
||||
finalize_exec(bprm);
|
||||
start_thread(regs, ex.a_entry, current->mm->start_stack);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int load_aout_library(struct file *file)
|
||||
{
|
||||
struct inode * inode;
|
||||
unsigned long bss, start_addr, len;
|
||||
unsigned long error;
|
||||
int retval;
|
||||
struct exec ex;
|
||||
loff_t pos = 0;
|
||||
|
||||
inode = file_inode(file);
|
||||
|
||||
retval = -ENOEXEC;
|
||||
error = kernel_read(file, &ex, sizeof(ex), &pos);
|
||||
if (error != sizeof(ex))
|
||||
goto out;
|
||||
|
||||
/* We come in here for the regular a.out style of shared libraries */
|
||||
if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != QMAGIC) || N_TRSIZE(ex) ||
|
||||
N_DRSIZE(ex) || ((ex.a_entry & 0xfff) && N_MAGIC(ex) == ZMAGIC) ||
|
||||
i_size_read(inode) < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Requires a mmap handler. This prevents people from using a.out
|
||||
* as part of an exploit attack against /proc-related vulnerabilities.
|
||||
*/
|
||||
if (!file->f_op->mmap)
|
||||
goto out;
|
||||
|
||||
if (N_FLAGS(ex))
|
||||
goto out;
|
||||
|
||||
/* For QMAGIC, the starting address is 0x20 into the page. We mask
|
||||
this off to get the starting address for the page */
|
||||
|
||||
start_addr = ex.a_entry & 0xfffff000;
|
||||
|
||||
if ((N_TXTOFF(ex) & ~PAGE_MASK) != 0) {
|
||||
if (printk_ratelimit())
|
||||
{
|
||||
printk(KERN_WARNING
|
||||
"N_TXTOFF is not page aligned. Please convert library: %pD\n",
|
||||
file);
|
||||
}
|
||||
retval = vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
|
||||
if (retval)
|
||||
goto out;
|
||||
|
||||
read_code(file, start_addr, N_TXTOFF(ex),
|
||||
ex.a_text + ex.a_data);
|
||||
retval = 0;
|
||||
goto out;
|
||||
}
|
||||
/* Now use mmap to map the library into memory. */
|
||||
error = vm_mmap(file, start_addr, ex.a_text + ex.a_data,
|
||||
PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||
MAP_FIXED | MAP_PRIVATE,
|
||||
N_TXTOFF(ex));
|
||||
retval = error;
|
||||
if (error != start_addr)
|
||||
goto out;
|
||||
|
||||
len = PAGE_ALIGN(ex.a_text + ex.a_data);
|
||||
bss = ex.a_text + ex.a_data + ex.a_bss;
|
||||
if (bss > len) {
|
||||
retval = vm_brk(start_addr + len, bss - len);
|
||||
if (retval)
|
||||
goto out;
|
||||
}
|
||||
retval = 0;
|
||||
out:
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int __init init_aout_binfmt(void)
|
||||
{
|
||||
register_binfmt(&aout_format);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit exit_aout_binfmt(void)
|
||||
{
|
||||
unregister_binfmt(&aout_format);
|
||||
}
|
||||
|
||||
core_initcall(init_aout_binfmt);
|
||||
module_exit(exit_aout_binfmt);
|
||||
MODULE_LICENSE("GPL");
|
@ -957,8 +957,7 @@ struct file *open_exec(const char *name)
|
||||
}
|
||||
EXPORT_SYMBOL(open_exec);
|
||||
|
||||
#if defined(CONFIG_HAVE_AOUT) || defined(CONFIG_BINFMT_FLAT) || \
|
||||
defined(CONFIG_BINFMT_ELF_FDPIC)
|
||||
#if defined(CONFIG_BINFMT_FLAT) || defined(CONFIG_BINFMT_ELF_FDPIC)
|
||||
ssize_t read_code(struct file *file, unsigned long addr, loff_t pos, size_t len)
|
||||
{
|
||||
ssize_t res = vfs_read(file, (void __user *)addr, len, &pos);
|
||||
|
@ -1,18 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __A_OUT_GNU_H__
|
||||
#define __A_OUT_GNU_H__
|
||||
|
||||
#include <uapi/linux/a.out.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#ifdef linux
|
||||
#include <asm/page.h>
|
||||
#if defined(__i386__) || defined(__mc68000__)
|
||||
#else
|
||||
#ifndef SEGMENT_SIZE
|
||||
#define SEGMENT_SIZE PAGE_SIZE
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif /*__ASSEMBLY__ */
|
||||
#endif /* __A_OUT_GNU_H__ */
|
@ -43,9 +43,6 @@ struct linux_binprm {
|
||||
* 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;
|
||||
|
Loading…
Reference in New Issue
Block a user