Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86: Remove a.out support

Commit

eac616557050 ("x86: Deprecate a.out support")

deprecated a.out support with the promise to remove it a couple of
releases later. That commit landed in v5.1.

Now it is more than a couple of releases later, no one has complained so
remove it.

Fold in a hunk removing the reference to arch/x86/ia32/ia32_aout.c in
MAINTAINERS:

https://lore.kernel.org/r/20220316050828.17255-1-lukas.bulwahn@gmail.com

Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Kees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/20220113160115.5375-1-bp@alien8.de

-335
-1
MAINTAINERS
··· 7378 7378 S: Supported 7379 7379 T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/execve 7380 7380 F: arch/alpha/kernel/binfmt_loader.c 7381 - F: arch/x86/ia32/ia32_aout.c 7382 7381 F: fs/*binfmt_*.c 7383 7382 F: fs/exec.c 7384 7383 F: include/linux/binfmts.h
-7
arch/x86/Kconfig
··· 2838 2838 64-bit kernel. You should likely turn this on, unless you're 2839 2839 100% sure that you don't have any 32-bit programs left. 2840 2840 2841 - config IA32_AOUT 2842 - tristate "IA32 a.out support" 2843 - depends on IA32_EMULATION 2844 - depends on BROKEN 2845 - help 2846 - Support old a.out binaries in the 32bit emulation. 2847 - 2848 2841 config X86_X32_ABI 2849 2842 bool "x32 ABI for 64-bit mode" 2850 2843 depends on X86_64
-2
arch/x86/ia32/Makefile
··· 5 5 6 6 obj-$(CONFIG_IA32_EMULATION) := ia32_signal.o 7 7 8 - obj-$(CONFIG_IA32_AOUT) += ia32_aout.o 9 - 10 8 audit-class-$(CONFIG_AUDIT) := audit.o 11 9 obj-$(CONFIG_IA32_EMULATION) += $(audit-class-y)
-325
arch/x86/ia32/ia32_aout.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * a.out loader for x86-64 4 - * 5 - * Copyright (C) 1991, 1992, 1996 Linus Torvalds 6 - * Hacked together by Andi Kleen 7 - */ 8 - 9 - #include <linux/module.h> 10 - 11 - #include <linux/time.h> 12 - #include <linux/kernel.h> 13 - #include <linux/mm.h> 14 - #include <linux/mman.h> 15 - #include <linux/a.out.h> 16 - #include <linux/errno.h> 17 - #include <linux/signal.h> 18 - #include <linux/string.h> 19 - #include <linux/fs.h> 20 - #include <linux/file.h> 21 - #include <linux/stat.h> 22 - #include <linux/fcntl.h> 23 - #include <linux/ptrace.h> 24 - #include <linux/user.h> 25 - #include <linux/binfmts.h> 26 - #include <linux/personality.h> 27 - #include <linux/init.h> 28 - #include <linux/jiffies.h> 29 - #include <linux/perf_event.h> 30 - #include <linux/sched/task_stack.h> 31 - 32 - #include <linux/uaccess.h> 33 - #include <asm/cacheflush.h> 34 - #include <asm/user32.h> 35 - #include <asm/ia32.h> 36 - 37 - #undef WARN_OLD 38 - 39 - static int load_aout_binary(struct linux_binprm *); 40 - static int load_aout_library(struct file *); 41 - 42 - static struct linux_binfmt aout_format = { 43 - .module = THIS_MODULE, 44 - .load_binary = load_aout_binary, 45 - .load_shlib = load_aout_library, 46 - }; 47 - 48 - static int set_brk(unsigned long start, unsigned long end) 49 - { 50 - start = PAGE_ALIGN(start); 51 - end = PAGE_ALIGN(end); 52 - if (end <= start) 53 - return 0; 54 - return vm_brk(start, end - start); 55 - } 56 - 57 - 58 - /* 59 - * create_aout_tables() parses the env- and arg-strings in new user 60 - * memory and creates the pointer tables from them, and puts their 61 - * addresses on the "stack", returning the new stack pointer value. 62 - */ 63 - static u32 __user *create_aout_tables(char __user *p, struct linux_binprm *bprm) 64 - { 65 - u32 __user *argv, *envp, *sp; 66 - int argc = bprm->argc, envc = bprm->envc; 67 - 68 - sp = (u32 __user *) ((-(unsigned long)sizeof(u32)) & (unsigned long) p); 69 - sp -= envc+1; 70 - envp = sp; 71 - sp -= argc+1; 72 - argv = sp; 73 - put_user((unsigned long) envp, --sp); 74 - put_user((unsigned long) argv, --sp); 75 - put_user(argc, --sp); 76 - current->mm->arg_start = (unsigned long) p; 77 - while (argc-- > 0) { 78 - char c; 79 - 80 - put_user((u32)(unsigned long)p, argv++); 81 - do { 82 - get_user(c, p++); 83 - } while (c); 84 - } 85 - put_user(0, argv); 86 - current->mm->arg_end = current->mm->env_start = (unsigned long) p; 87 - while (envc-- > 0) { 88 - char c; 89 - 90 - put_user((u32)(unsigned long)p, envp++); 91 - do { 92 - get_user(c, p++); 93 - } while (c); 94 - } 95 - put_user(0, envp); 96 - current->mm->env_end = (unsigned long) p; 97 - return sp; 98 - } 99 - 100 - /* 101 - * These are the functions used to load a.out style executables and shared 102 - * libraries. There is no binary dependent code anywhere else. 103 - */ 104 - static int load_aout_binary(struct linux_binprm *bprm) 105 - { 106 - unsigned long error, fd_offset, rlim; 107 - struct pt_regs *regs = current_pt_regs(); 108 - struct exec ex; 109 - int retval; 110 - 111 - ex = *((struct exec *) bprm->buf); /* exec-header */ 112 - if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC && 113 - N_MAGIC(ex) != QMAGIC && N_MAGIC(ex) != NMAGIC) || 114 - N_TRSIZE(ex) || N_DRSIZE(ex) || 115 - i_size_read(file_inode(bprm->file)) < 116 - ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) { 117 - return -ENOEXEC; 118 - } 119 - 120 - fd_offset = N_TXTOFF(ex); 121 - 122 - /* Check initial limits. This avoids letting people circumvent 123 - * size limits imposed on them by creating programs with large 124 - * arrays in the data or bss. 125 - */ 126 - rlim = rlimit(RLIMIT_DATA); 127 - if (rlim >= RLIM_INFINITY) 128 - rlim = ~0; 129 - if (ex.a_data + ex.a_bss > rlim) 130 - return -ENOMEM; 131 - 132 - /* Flush all traces of the currently running executable */ 133 - retval = begin_new_exec(bprm); 134 - if (retval) 135 - return retval; 136 - 137 - /* OK, This is the point of no return */ 138 - set_personality(PER_LINUX); 139 - set_personality_ia32(false); 140 - 141 - setup_new_exec(bprm); 142 - 143 - regs->cs = __USER32_CS; 144 - regs->r8 = regs->r9 = regs->r10 = regs->r11 = regs->r12 = 145 - regs->r13 = regs->r14 = regs->r15 = 0; 146 - 147 - current->mm->end_code = ex.a_text + 148 - (current->mm->start_code = N_TXTADDR(ex)); 149 - current->mm->end_data = ex.a_data + 150 - (current->mm->start_data = N_DATADDR(ex)); 151 - current->mm->brk = ex.a_bss + 152 - (current->mm->start_brk = N_BSSADDR(ex)); 153 - 154 - retval = setup_arg_pages(bprm, IA32_STACK_TOP, EXSTACK_DEFAULT); 155 - if (retval < 0) 156 - return retval; 157 - 158 - if (N_MAGIC(ex) == OMAGIC) { 159 - unsigned long text_addr, map_size; 160 - 161 - text_addr = N_TXTADDR(ex); 162 - map_size = ex.a_text+ex.a_data; 163 - 164 - error = vm_brk(text_addr & PAGE_MASK, map_size); 165 - 166 - if (error) 167 - return error; 168 - 169 - error = read_code(bprm->file, text_addr, 32, 170 - ex.a_text + ex.a_data); 171 - if ((signed long)error < 0) 172 - return error; 173 - } else { 174 - #ifdef WARN_OLD 175 - static unsigned long error_time, error_time2; 176 - if ((ex.a_text & 0xfff || ex.a_data & 0xfff) && 177 - (N_MAGIC(ex) != NMAGIC) && 178 - time_after(jiffies, error_time2 + 5*HZ)) { 179 - printk(KERN_NOTICE "executable not page aligned\n"); 180 - error_time2 = jiffies; 181 - } 182 - 183 - if ((fd_offset & ~PAGE_MASK) != 0 && 184 - time_after(jiffies, error_time + 5*HZ)) { 185 - printk(KERN_WARNING 186 - "fd_offset is not page aligned. Please convert " 187 - "program: %pD\n", 188 - bprm->file); 189 - error_time = jiffies; 190 - } 191 - #endif 192 - 193 - if (!bprm->file->f_op->mmap || (fd_offset & ~PAGE_MASK) != 0) { 194 - error = vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); 195 - if (error) 196 - return error; 197 - 198 - read_code(bprm->file, N_TXTADDR(ex), fd_offset, 199 - ex.a_text+ex.a_data); 200 - goto beyond_if; 201 - } 202 - 203 - error = vm_mmap(bprm->file, N_TXTADDR(ex), ex.a_text, 204 - PROT_READ | PROT_EXEC, 205 - MAP_FIXED | MAP_PRIVATE | MAP_32BIT, 206 - fd_offset); 207 - 208 - if (error != N_TXTADDR(ex)) 209 - return error; 210 - 211 - error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data, 212 - PROT_READ | PROT_WRITE | PROT_EXEC, 213 - MAP_FIXED | MAP_PRIVATE | MAP_32BIT, 214 - fd_offset + ex.a_text); 215 - if (error != N_DATADDR(ex)) 216 - return error; 217 - } 218 - 219 - beyond_if: 220 - error = set_brk(current->mm->start_brk, current->mm->brk); 221 - if (error) 222 - return error; 223 - 224 - set_binfmt(&aout_format); 225 - 226 - current->mm->start_stack = 227 - (unsigned long)create_aout_tables((char __user *)bprm->p, bprm); 228 - /* start thread */ 229 - loadsegment(fs, 0); 230 - loadsegment(ds, __USER32_DS); 231 - loadsegment(es, __USER32_DS); 232 - load_gs_index(0); 233 - (regs)->ip = ex.a_entry; 234 - (regs)->sp = current->mm->start_stack; 235 - (regs)->flags = 0x200; 236 - (regs)->cs = __USER32_CS; 237 - (regs)->ss = __USER32_DS; 238 - regs->r8 = regs->r9 = regs->r10 = regs->r11 = 239 - regs->r12 = regs->r13 = regs->r14 = regs->r15 = 0; 240 - return 0; 241 - } 242 - 243 - static int load_aout_library(struct file *file) 244 - { 245 - unsigned long bss, start_addr, len, error; 246 - int retval; 247 - struct exec ex; 248 - loff_t pos = 0; 249 - 250 - retval = -ENOEXEC; 251 - error = kernel_read(file, &ex, sizeof(ex), &pos); 252 - if (error != sizeof(ex)) 253 - goto out; 254 - 255 - /* We come in here for the regular a.out style of shared libraries */ 256 - if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != QMAGIC) || N_TRSIZE(ex) || 257 - N_DRSIZE(ex) || ((ex.a_entry & 0xfff) && N_MAGIC(ex) == ZMAGIC) || 258 - i_size_read(file_inode(file)) < 259 - ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) { 260 - goto out; 261 - } 262 - 263 - if (N_FLAGS(ex)) 264 - goto out; 265 - 266 - /* For QMAGIC, the starting address is 0x20 into the page. We mask 267 - this off to get the starting address for the page */ 268 - 269 - start_addr = ex.a_entry & 0xfffff000; 270 - 271 - if ((N_TXTOFF(ex) & ~PAGE_MASK) != 0) { 272 - #ifdef WARN_OLD 273 - static unsigned long error_time; 274 - if (time_after(jiffies, error_time + 5*HZ)) { 275 - printk(KERN_WARNING 276 - "N_TXTOFF is not page aligned. Please convert " 277 - "library: %pD\n", 278 - file); 279 - error_time = jiffies; 280 - } 281 - #endif 282 - retval = vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); 283 - if (retval) 284 - goto out; 285 - 286 - read_code(file, start_addr, N_TXTOFF(ex), 287 - ex.a_text + ex.a_data); 288 - retval = 0; 289 - goto out; 290 - } 291 - /* Now use mmap to map the library into memory. */ 292 - error = vm_mmap(file, start_addr, ex.a_text + ex.a_data, 293 - PROT_READ | PROT_WRITE | PROT_EXEC, 294 - MAP_FIXED | MAP_PRIVATE | MAP_32BIT, 295 - N_TXTOFF(ex)); 296 - retval = error; 297 - if (error != start_addr) 298 - goto out; 299 - 300 - len = PAGE_ALIGN(ex.a_text + ex.a_data); 301 - bss = ex.a_text + ex.a_data + ex.a_bss; 302 - if (bss > len) { 303 - retval = vm_brk(start_addr + len, bss - len); 304 - if (retval) 305 - goto out; 306 - } 307 - retval = 0; 308 - out: 309 - return retval; 310 - } 311 - 312 - static int __init init_aout_binfmt(void) 313 - { 314 - register_binfmt(&aout_format); 315 - return 0; 316 - } 317 - 318 - static void __exit exit_aout_binfmt(void) 319 - { 320 - unregister_binfmt(&aout_format); 321 - } 322 - 323 - module_init(init_aout_binfmt); 324 - module_exit(exit_aout_binfmt); 325 - MODULE_LICENSE("GPL");