18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * linux/fs/binfmt_aout.c 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 1991, 1992, 1996 Linus Torvalds 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/module.h> 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/time.h> 118c2ecf20Sopenharmony_ci#include <linux/kernel.h> 128c2ecf20Sopenharmony_ci#include <linux/mm.h> 138c2ecf20Sopenharmony_ci#include <linux/mman.h> 148c2ecf20Sopenharmony_ci#include <linux/a.out.h> 158c2ecf20Sopenharmony_ci#include <linux/errno.h> 168c2ecf20Sopenharmony_ci#include <linux/signal.h> 178c2ecf20Sopenharmony_ci#include <linux/string.h> 188c2ecf20Sopenharmony_ci#include <linux/fs.h> 198c2ecf20Sopenharmony_ci#include <linux/file.h> 208c2ecf20Sopenharmony_ci#include <linux/stat.h> 218c2ecf20Sopenharmony_ci#include <linux/fcntl.h> 228c2ecf20Sopenharmony_ci#include <linux/ptrace.h> 238c2ecf20Sopenharmony_ci#include <linux/user.h> 248c2ecf20Sopenharmony_ci#include <linux/binfmts.h> 258c2ecf20Sopenharmony_ci#include <linux/personality.h> 268c2ecf20Sopenharmony_ci#include <linux/init.h> 278c2ecf20Sopenharmony_ci#include <linux/coredump.h> 288c2ecf20Sopenharmony_ci#include <linux/slab.h> 298c2ecf20Sopenharmony_ci#include <linux/sched/task_stack.h> 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci#include <linux/uaccess.h> 328c2ecf20Sopenharmony_ci#include <asm/cacheflush.h> 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_cistatic int load_aout_binary(struct linux_binprm *); 358c2ecf20Sopenharmony_cistatic int load_aout_library(struct file*); 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_cistatic struct linux_binfmt aout_format = { 388c2ecf20Sopenharmony_ci .module = THIS_MODULE, 398c2ecf20Sopenharmony_ci .load_binary = load_aout_binary, 408c2ecf20Sopenharmony_ci .load_shlib = load_aout_library, 418c2ecf20Sopenharmony_ci}; 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci#define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE) 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_cistatic int set_brk(unsigned long start, unsigned long end) 468c2ecf20Sopenharmony_ci{ 478c2ecf20Sopenharmony_ci start = PAGE_ALIGN(start); 488c2ecf20Sopenharmony_ci end = PAGE_ALIGN(end); 498c2ecf20Sopenharmony_ci if (end > start) 508c2ecf20Sopenharmony_ci return vm_brk(start, end - start); 518c2ecf20Sopenharmony_ci return 0; 528c2ecf20Sopenharmony_ci} 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci/* 558c2ecf20Sopenharmony_ci * create_aout_tables() parses the env- and arg-strings in new user 568c2ecf20Sopenharmony_ci * memory and creates the pointer tables from them, and puts their 578c2ecf20Sopenharmony_ci * addresses on the "stack", returning the new stack pointer value. 588c2ecf20Sopenharmony_ci */ 598c2ecf20Sopenharmony_cistatic unsigned long __user *create_aout_tables(char __user *p, struct linux_binprm * bprm) 608c2ecf20Sopenharmony_ci{ 618c2ecf20Sopenharmony_ci char __user * __user *argv; 628c2ecf20Sopenharmony_ci char __user * __user *envp; 638c2ecf20Sopenharmony_ci unsigned long __user *sp; 648c2ecf20Sopenharmony_ci int argc = bprm->argc; 658c2ecf20Sopenharmony_ci int envc = bprm->envc; 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci sp = (void __user *)((-(unsigned long)sizeof(char *)) & (unsigned long) p); 688c2ecf20Sopenharmony_ci#ifdef __alpha__ 698c2ecf20Sopenharmony_ci/* whee.. test-programs are so much fun. */ 708c2ecf20Sopenharmony_ci put_user(0, --sp); 718c2ecf20Sopenharmony_ci put_user(0, --sp); 728c2ecf20Sopenharmony_ci if (bprm->loader) { 738c2ecf20Sopenharmony_ci put_user(0, --sp); 748c2ecf20Sopenharmony_ci put_user(1003, --sp); 758c2ecf20Sopenharmony_ci put_user(bprm->loader, --sp); 768c2ecf20Sopenharmony_ci put_user(1002, --sp); 778c2ecf20Sopenharmony_ci } 788c2ecf20Sopenharmony_ci put_user(bprm->exec, --sp); 798c2ecf20Sopenharmony_ci put_user(1001, --sp); 808c2ecf20Sopenharmony_ci#endif 818c2ecf20Sopenharmony_ci sp -= envc+1; 828c2ecf20Sopenharmony_ci envp = (char __user * __user *) sp; 838c2ecf20Sopenharmony_ci sp -= argc+1; 848c2ecf20Sopenharmony_ci argv = (char __user * __user *) sp; 858c2ecf20Sopenharmony_ci#ifndef __alpha__ 868c2ecf20Sopenharmony_ci put_user((unsigned long) envp,--sp); 878c2ecf20Sopenharmony_ci put_user((unsigned long) argv,--sp); 888c2ecf20Sopenharmony_ci#endif 898c2ecf20Sopenharmony_ci put_user(argc,--sp); 908c2ecf20Sopenharmony_ci current->mm->arg_start = (unsigned long) p; 918c2ecf20Sopenharmony_ci while (argc-->0) { 928c2ecf20Sopenharmony_ci char c; 938c2ecf20Sopenharmony_ci put_user(p,argv++); 948c2ecf20Sopenharmony_ci do { 958c2ecf20Sopenharmony_ci get_user(c,p++); 968c2ecf20Sopenharmony_ci } while (c); 978c2ecf20Sopenharmony_ci } 988c2ecf20Sopenharmony_ci put_user(NULL,argv); 998c2ecf20Sopenharmony_ci current->mm->arg_end = current->mm->env_start = (unsigned long) p; 1008c2ecf20Sopenharmony_ci while (envc-->0) { 1018c2ecf20Sopenharmony_ci char c; 1028c2ecf20Sopenharmony_ci put_user(p,envp++); 1038c2ecf20Sopenharmony_ci do { 1048c2ecf20Sopenharmony_ci get_user(c,p++); 1058c2ecf20Sopenharmony_ci } while (c); 1068c2ecf20Sopenharmony_ci } 1078c2ecf20Sopenharmony_ci put_user(NULL,envp); 1088c2ecf20Sopenharmony_ci current->mm->env_end = (unsigned long) p; 1098c2ecf20Sopenharmony_ci return sp; 1108c2ecf20Sopenharmony_ci} 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci/* 1138c2ecf20Sopenharmony_ci * These are the functions used to load a.out style executables and shared 1148c2ecf20Sopenharmony_ci * libraries. There is no binary dependent code anywhere else. 1158c2ecf20Sopenharmony_ci */ 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_cistatic int load_aout_binary(struct linux_binprm * bprm) 1188c2ecf20Sopenharmony_ci{ 1198c2ecf20Sopenharmony_ci struct pt_regs *regs = current_pt_regs(); 1208c2ecf20Sopenharmony_ci struct exec ex; 1218c2ecf20Sopenharmony_ci unsigned long error; 1228c2ecf20Sopenharmony_ci unsigned long fd_offset; 1238c2ecf20Sopenharmony_ci unsigned long rlim; 1248c2ecf20Sopenharmony_ci int retval; 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci ex = *((struct exec *) bprm->buf); /* exec-header */ 1278c2ecf20Sopenharmony_ci if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC && 1288c2ecf20Sopenharmony_ci N_MAGIC(ex) != QMAGIC && N_MAGIC(ex) != NMAGIC) || 1298c2ecf20Sopenharmony_ci N_TRSIZE(ex) || N_DRSIZE(ex) || 1308c2ecf20Sopenharmony_ci i_size_read(file_inode(bprm->file)) < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) { 1318c2ecf20Sopenharmony_ci return -ENOEXEC; 1328c2ecf20Sopenharmony_ci } 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci /* 1358c2ecf20Sopenharmony_ci * Requires a mmap handler. This prevents people from using a.out 1368c2ecf20Sopenharmony_ci * as part of an exploit attack against /proc-related vulnerabilities. 1378c2ecf20Sopenharmony_ci */ 1388c2ecf20Sopenharmony_ci if (!bprm->file->f_op->mmap) 1398c2ecf20Sopenharmony_ci return -ENOEXEC; 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci fd_offset = N_TXTOFF(ex); 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci /* Check initial limits. This avoids letting people circumvent 1448c2ecf20Sopenharmony_ci * size limits imposed on them by creating programs with large 1458c2ecf20Sopenharmony_ci * arrays in the data or bss. 1468c2ecf20Sopenharmony_ci */ 1478c2ecf20Sopenharmony_ci rlim = rlimit(RLIMIT_DATA); 1488c2ecf20Sopenharmony_ci if (rlim >= RLIM_INFINITY) 1498c2ecf20Sopenharmony_ci rlim = ~0; 1508c2ecf20Sopenharmony_ci if (ex.a_data + ex.a_bss > rlim) 1518c2ecf20Sopenharmony_ci return -ENOMEM; 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci /* Flush all traces of the currently running executable */ 1548c2ecf20Sopenharmony_ci retval = begin_new_exec(bprm); 1558c2ecf20Sopenharmony_ci if (retval) 1568c2ecf20Sopenharmony_ci return retval; 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci /* OK, This is the point of no return */ 1598c2ecf20Sopenharmony_ci#ifdef __alpha__ 1608c2ecf20Sopenharmony_ci SET_AOUT_PERSONALITY(bprm, ex); 1618c2ecf20Sopenharmony_ci#else 1628c2ecf20Sopenharmony_ci set_personality(PER_LINUX); 1638c2ecf20Sopenharmony_ci#endif 1648c2ecf20Sopenharmony_ci setup_new_exec(bprm); 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci current->mm->end_code = ex.a_text + 1678c2ecf20Sopenharmony_ci (current->mm->start_code = N_TXTADDR(ex)); 1688c2ecf20Sopenharmony_ci current->mm->end_data = ex.a_data + 1698c2ecf20Sopenharmony_ci (current->mm->start_data = N_DATADDR(ex)); 1708c2ecf20Sopenharmony_ci current->mm->brk = ex.a_bss + 1718c2ecf20Sopenharmony_ci (current->mm->start_brk = N_BSSADDR(ex)); 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci retval = setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT); 1748c2ecf20Sopenharmony_ci if (retval < 0) 1758c2ecf20Sopenharmony_ci return retval; 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ci if (N_MAGIC(ex) == OMAGIC) { 1798c2ecf20Sopenharmony_ci unsigned long text_addr, map_size; 1808c2ecf20Sopenharmony_ci loff_t pos; 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci text_addr = N_TXTADDR(ex); 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci#ifdef __alpha__ 1858c2ecf20Sopenharmony_ci pos = fd_offset; 1868c2ecf20Sopenharmony_ci map_size = ex.a_text+ex.a_data + PAGE_SIZE - 1; 1878c2ecf20Sopenharmony_ci#else 1888c2ecf20Sopenharmony_ci pos = 32; 1898c2ecf20Sopenharmony_ci map_size = ex.a_text+ex.a_data; 1908c2ecf20Sopenharmony_ci#endif 1918c2ecf20Sopenharmony_ci error = vm_brk(text_addr & PAGE_MASK, map_size); 1928c2ecf20Sopenharmony_ci if (error) 1938c2ecf20Sopenharmony_ci return error; 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci error = read_code(bprm->file, text_addr, pos, 1968c2ecf20Sopenharmony_ci ex.a_text+ex.a_data); 1978c2ecf20Sopenharmony_ci if ((signed long)error < 0) 1988c2ecf20Sopenharmony_ci return error; 1998c2ecf20Sopenharmony_ci } else { 2008c2ecf20Sopenharmony_ci if ((ex.a_text & 0xfff || ex.a_data & 0xfff) && 2018c2ecf20Sopenharmony_ci (N_MAGIC(ex) != NMAGIC) && printk_ratelimit()) 2028c2ecf20Sopenharmony_ci { 2038c2ecf20Sopenharmony_ci printk(KERN_NOTICE "executable not page aligned\n"); 2048c2ecf20Sopenharmony_ci } 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci if ((fd_offset & ~PAGE_MASK) != 0 && printk_ratelimit()) 2078c2ecf20Sopenharmony_ci { 2088c2ecf20Sopenharmony_ci printk(KERN_WARNING 2098c2ecf20Sopenharmony_ci "fd_offset is not page aligned. Please convert program: %pD\n", 2108c2ecf20Sopenharmony_ci bprm->file); 2118c2ecf20Sopenharmony_ci } 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) { 2148c2ecf20Sopenharmony_ci error = vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); 2158c2ecf20Sopenharmony_ci if (error) 2168c2ecf20Sopenharmony_ci return error; 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci read_code(bprm->file, N_TXTADDR(ex), fd_offset, 2198c2ecf20Sopenharmony_ci ex.a_text + ex.a_data); 2208c2ecf20Sopenharmony_ci goto beyond_if; 2218c2ecf20Sopenharmony_ci } 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci error = vm_mmap(bprm->file, N_TXTADDR(ex), ex.a_text, 2248c2ecf20Sopenharmony_ci PROT_READ | PROT_EXEC, 2258c2ecf20Sopenharmony_ci MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, 2268c2ecf20Sopenharmony_ci fd_offset); 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci if (error != N_TXTADDR(ex)) 2298c2ecf20Sopenharmony_ci return error; 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_ci error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data, 2328c2ecf20Sopenharmony_ci PROT_READ | PROT_WRITE | PROT_EXEC, 2338c2ecf20Sopenharmony_ci MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, 2348c2ecf20Sopenharmony_ci fd_offset + ex.a_text); 2358c2ecf20Sopenharmony_ci if (error != N_DATADDR(ex)) 2368c2ecf20Sopenharmony_ci return error; 2378c2ecf20Sopenharmony_ci } 2388c2ecf20Sopenharmony_cibeyond_if: 2398c2ecf20Sopenharmony_ci set_binfmt(&aout_format); 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci retval = set_brk(current->mm->start_brk, current->mm->brk); 2428c2ecf20Sopenharmony_ci if (retval < 0) 2438c2ecf20Sopenharmony_ci return retval; 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci current->mm->start_stack = 2468c2ecf20Sopenharmony_ci (unsigned long) create_aout_tables((char __user *) bprm->p, bprm); 2478c2ecf20Sopenharmony_ci#ifdef __alpha__ 2488c2ecf20Sopenharmony_ci regs->gp = ex.a_gpvalue; 2498c2ecf20Sopenharmony_ci#endif 2508c2ecf20Sopenharmony_ci finalize_exec(bprm); 2518c2ecf20Sopenharmony_ci start_thread(regs, ex.a_entry, current->mm->start_stack); 2528c2ecf20Sopenharmony_ci return 0; 2538c2ecf20Sopenharmony_ci} 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_cistatic int load_aout_library(struct file *file) 2568c2ecf20Sopenharmony_ci{ 2578c2ecf20Sopenharmony_ci struct inode * inode; 2588c2ecf20Sopenharmony_ci unsigned long bss, start_addr, len; 2598c2ecf20Sopenharmony_ci unsigned long error; 2608c2ecf20Sopenharmony_ci int retval; 2618c2ecf20Sopenharmony_ci struct exec ex; 2628c2ecf20Sopenharmony_ci loff_t pos = 0; 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci inode = file_inode(file); 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci retval = -ENOEXEC; 2678c2ecf20Sopenharmony_ci error = kernel_read(file, &ex, sizeof(ex), &pos); 2688c2ecf20Sopenharmony_ci if (error != sizeof(ex)) 2698c2ecf20Sopenharmony_ci goto out; 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci /* We come in here for the regular a.out style of shared libraries */ 2728c2ecf20Sopenharmony_ci if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != QMAGIC) || N_TRSIZE(ex) || 2738c2ecf20Sopenharmony_ci N_DRSIZE(ex) || ((ex.a_entry & 0xfff) && N_MAGIC(ex) == ZMAGIC) || 2748c2ecf20Sopenharmony_ci i_size_read(inode) < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) { 2758c2ecf20Sopenharmony_ci goto out; 2768c2ecf20Sopenharmony_ci } 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci /* 2798c2ecf20Sopenharmony_ci * Requires a mmap handler. This prevents people from using a.out 2808c2ecf20Sopenharmony_ci * as part of an exploit attack against /proc-related vulnerabilities. 2818c2ecf20Sopenharmony_ci */ 2828c2ecf20Sopenharmony_ci if (!file->f_op->mmap) 2838c2ecf20Sopenharmony_ci goto out; 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci if (N_FLAGS(ex)) 2868c2ecf20Sopenharmony_ci goto out; 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_ci /* For QMAGIC, the starting address is 0x20 into the page. We mask 2898c2ecf20Sopenharmony_ci this off to get the starting address for the page */ 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ci start_addr = ex.a_entry & 0xfffff000; 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci if ((N_TXTOFF(ex) & ~PAGE_MASK) != 0) { 2948c2ecf20Sopenharmony_ci if (printk_ratelimit()) 2958c2ecf20Sopenharmony_ci { 2968c2ecf20Sopenharmony_ci printk(KERN_WARNING 2978c2ecf20Sopenharmony_ci "N_TXTOFF is not page aligned. Please convert library: %pD\n", 2988c2ecf20Sopenharmony_ci file); 2998c2ecf20Sopenharmony_ci } 3008c2ecf20Sopenharmony_ci retval = vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); 3018c2ecf20Sopenharmony_ci if (retval) 3028c2ecf20Sopenharmony_ci goto out; 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci read_code(file, start_addr, N_TXTOFF(ex), 3058c2ecf20Sopenharmony_ci ex.a_text + ex.a_data); 3068c2ecf20Sopenharmony_ci retval = 0; 3078c2ecf20Sopenharmony_ci goto out; 3088c2ecf20Sopenharmony_ci } 3098c2ecf20Sopenharmony_ci /* Now use mmap to map the library into memory. */ 3108c2ecf20Sopenharmony_ci error = vm_mmap(file, start_addr, ex.a_text + ex.a_data, 3118c2ecf20Sopenharmony_ci PROT_READ | PROT_WRITE | PROT_EXEC, 3128c2ecf20Sopenharmony_ci MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE, 3138c2ecf20Sopenharmony_ci N_TXTOFF(ex)); 3148c2ecf20Sopenharmony_ci retval = error; 3158c2ecf20Sopenharmony_ci if (error != start_addr) 3168c2ecf20Sopenharmony_ci goto out; 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_ci len = PAGE_ALIGN(ex.a_text + ex.a_data); 3198c2ecf20Sopenharmony_ci bss = ex.a_text + ex.a_data + ex.a_bss; 3208c2ecf20Sopenharmony_ci if (bss > len) { 3218c2ecf20Sopenharmony_ci retval = vm_brk(start_addr + len, bss - len); 3228c2ecf20Sopenharmony_ci if (retval) 3238c2ecf20Sopenharmony_ci goto out; 3248c2ecf20Sopenharmony_ci } 3258c2ecf20Sopenharmony_ci retval = 0; 3268c2ecf20Sopenharmony_ciout: 3278c2ecf20Sopenharmony_ci return retval; 3288c2ecf20Sopenharmony_ci} 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_cistatic int __init init_aout_binfmt(void) 3318c2ecf20Sopenharmony_ci{ 3328c2ecf20Sopenharmony_ci register_binfmt(&aout_format); 3338c2ecf20Sopenharmony_ci return 0; 3348c2ecf20Sopenharmony_ci} 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_cistatic void __exit exit_aout_binfmt(void) 3378c2ecf20Sopenharmony_ci{ 3388c2ecf20Sopenharmony_ci unregister_binfmt(&aout_format); 3398c2ecf20Sopenharmony_ci} 3408c2ecf20Sopenharmony_ci 3418c2ecf20Sopenharmony_cicore_initcall(init_aout_binfmt); 3428c2ecf20Sopenharmony_cimodule_exit(exit_aout_binfmt); 3438c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 344