Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /****************************************************************************/
0003 /*
0004  *  linux/fs/binfmt_flat.c
0005  *
0006  *  Copyright (C) 2000-2003 David McCullough <davidm@snapgear.com>
0007  *  Copyright (C) 2002 Greg Ungerer <gerg@snapgear.com>
0008  *  Copyright (C) 2002 SnapGear, by Paul Dale <pauli@snapgear.com>
0009  *  Copyright (C) 2000, 2001 Lineo, by David McCullough <davidm@lineo.com>
0010  *  based heavily on:
0011  *
0012  *  linux/fs/binfmt_aout.c:
0013  *      Copyright (C) 1991, 1992, 1996  Linus Torvalds
0014  *  linux/fs/binfmt_flat.c for 2.0 kernel
0015  *      Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>
0016  *  JAN/99 -- coded full program relocation (gerg@snapgear.com)
0017  */
0018 
0019 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0020 
0021 #include <linux/kernel.h>
0022 #include <linux/sched.h>
0023 #include <linux/sched/task_stack.h>
0024 #include <linux/mm.h>
0025 #include <linux/mman.h>
0026 #include <linux/errno.h>
0027 #include <linux/signal.h>
0028 #include <linux/string.h>
0029 #include <linux/fs.h>
0030 #include <linux/file.h>
0031 #include <linux/ptrace.h>
0032 #include <linux/user.h>
0033 #include <linux/slab.h>
0034 #include <linux/binfmts.h>
0035 #include <linux/personality.h>
0036 #include <linux/init.h>
0037 #include <linux/flat.h>
0038 #include <linux/uaccess.h>
0039 #include <linux/vmalloc.h>
0040 
0041 #include <asm/byteorder.h>
0042 #include <asm/unaligned.h>
0043 #include <asm/cacheflush.h>
0044 #include <asm/page.h>
0045 #include <asm/flat.h>
0046 
0047 #ifndef flat_get_relocate_addr
0048 #define flat_get_relocate_addr(rel) (rel)
0049 #endif
0050 
0051 /****************************************************************************/
0052 
0053 /*
0054  * User data (data section and bss) needs to be aligned.
0055  * We pick 0x20 here because it is the max value elf2flt has always
0056  * used in producing FLAT files, and because it seems to be large
0057  * enough to make all the gcc alignment related tests happy.
0058  */
0059 #define FLAT_DATA_ALIGN (0x20)
0060 
0061 /*
0062  * User data (stack) also needs to be aligned.
0063  * Here we can be a bit looser than the data sections since this
0064  * needs to only meet arch ABI requirements.
0065  */
0066 #define FLAT_STACK_ALIGN    max_t(unsigned long, sizeof(void *), ARCH_SLAB_MINALIGN)
0067 
0068 #define RELOC_FAILED 0xff00ff01     /* Relocation incorrect somewhere */
0069 #define UNLOADED_LIB 0x7ff000ff     /* Placeholder for unused library */
0070 
0071 #define MAX_SHARED_LIBS         (1)
0072 
0073 #ifdef CONFIG_BINFMT_FLAT_NO_DATA_START_OFFSET
0074 #define DATA_START_OFFSET_WORDS     (0)
0075 #else
0076 #define DATA_START_OFFSET_WORDS     (MAX_SHARED_LIBS)
0077 #endif
0078 
0079 struct lib_info {
0080     struct {
0081         unsigned long start_code;       /* Start of text segment */
0082         unsigned long start_data;       /* Start of data segment */
0083         unsigned long start_brk;        /* End of data segment */
0084         unsigned long text_len;         /* Length of text segment */
0085         unsigned long entry;            /* Start address for this module */
0086         unsigned long build_date;       /* When this one was compiled */
0087         bool loaded;                /* Has this library been loaded? */
0088     } lib_list[MAX_SHARED_LIBS];
0089 };
0090 
0091 static int load_flat_binary(struct linux_binprm *);
0092 
0093 static struct linux_binfmt flat_format = {
0094     .module     = THIS_MODULE,
0095     .load_binary    = load_flat_binary,
0096 };
0097 
0098 
0099 /****************************************************************************/
0100 /*
0101  * create_flat_tables() parses the env- and arg-strings in new user
0102  * memory and creates the pointer tables from them, and puts their
0103  * addresses on the "stack", recording the new stack pointer value.
0104  */
0105 
0106 static int create_flat_tables(struct linux_binprm *bprm, unsigned long arg_start)
0107 {
0108     char __user *p;
0109     unsigned long __user *sp;
0110     long i, len;
0111 
0112     p = (char __user *)arg_start;
0113     sp = (unsigned long __user *)current->mm->start_stack;
0114 
0115     sp -= bprm->envc + 1;
0116     sp -= bprm->argc + 1;
0117     if (IS_ENABLED(CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK))
0118         sp -= 2; /* argvp + envp */
0119     sp -= 1;  /* &argc */
0120 
0121     current->mm->start_stack = (unsigned long)sp & -FLAT_STACK_ALIGN;
0122     sp = (unsigned long __user *)current->mm->start_stack;
0123 
0124     if (put_user(bprm->argc, sp++))
0125         return -EFAULT;
0126     if (IS_ENABLED(CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK)) {
0127         unsigned long argv, envp;
0128         argv = (unsigned long)(sp + 2);
0129         envp = (unsigned long)(sp + 2 + bprm->argc + 1);
0130         if (put_user(argv, sp++) || put_user(envp, sp++))
0131             return -EFAULT;
0132     }
0133 
0134     current->mm->arg_start = (unsigned long)p;
0135     for (i = bprm->argc; i > 0; i--) {
0136         if (put_user((unsigned long)p, sp++))
0137             return -EFAULT;
0138         len = strnlen_user(p, MAX_ARG_STRLEN);
0139         if (!len || len > MAX_ARG_STRLEN)
0140             return -EINVAL;
0141         p += len;
0142     }
0143     if (put_user(0, sp++))
0144         return -EFAULT;
0145     current->mm->arg_end = (unsigned long)p;
0146 
0147     current->mm->env_start = (unsigned long) p;
0148     for (i = bprm->envc; i > 0; i--) {
0149         if (put_user((unsigned long)p, sp++))
0150             return -EFAULT;
0151         len = strnlen_user(p, MAX_ARG_STRLEN);
0152         if (!len || len > MAX_ARG_STRLEN)
0153             return -EINVAL;
0154         p += len;
0155     }
0156     if (put_user(0, sp++))
0157         return -EFAULT;
0158     current->mm->env_end = (unsigned long)p;
0159 
0160     return 0;
0161 }
0162 
0163 /****************************************************************************/
0164 
0165 #ifdef CONFIG_BINFMT_ZFLAT
0166 
0167 #include <linux/zlib.h>
0168 
0169 #define LBUFSIZE    4000
0170 
0171 /* gzip flag byte */
0172 #define ASCII_FLAG   0x01 /* bit 0 set: file probably ASCII text */
0173 #define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
0174 #define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
0175 #define ORIG_NAME    0x08 /* bit 3 set: original file name present */
0176 #define COMMENT      0x10 /* bit 4 set: file comment present */
0177 #define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
0178 #define RESERVED     0xC0 /* bit 6,7:   reserved */
0179 
0180 static int decompress_exec(struct linux_binprm *bprm, loff_t fpos, char *dst,
0181         long len, int fd)
0182 {
0183     unsigned char *buf;
0184     z_stream strm;
0185     int ret, retval;
0186 
0187     pr_debug("decompress_exec(offset=%llx,buf=%p,len=%lx)\n", fpos, dst, len);
0188 
0189     memset(&strm, 0, sizeof(strm));
0190     strm.workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
0191     if (!strm.workspace)
0192         return -ENOMEM;
0193 
0194     buf = kmalloc(LBUFSIZE, GFP_KERNEL);
0195     if (!buf) {
0196         retval = -ENOMEM;
0197         goto out_free;
0198     }
0199 
0200     /* Read in first chunk of data and parse gzip header. */
0201     ret = kernel_read(bprm->file, buf, LBUFSIZE, &fpos);
0202 
0203     strm.next_in = buf;
0204     strm.avail_in = ret;
0205     strm.total_in = 0;
0206 
0207     retval = -ENOEXEC;
0208 
0209     /* Check minimum size -- gzip header */
0210     if (ret < 10) {
0211         pr_debug("file too small?\n");
0212         goto out_free_buf;
0213     }
0214 
0215     /* Check gzip magic number */
0216     if ((buf[0] != 037) || ((buf[1] != 0213) && (buf[1] != 0236))) {
0217         pr_debug("unknown compression magic?\n");
0218         goto out_free_buf;
0219     }
0220 
0221     /* Check gzip method */
0222     if (buf[2] != 8) {
0223         pr_debug("unknown compression method?\n");
0224         goto out_free_buf;
0225     }
0226     /* Check gzip flags */
0227     if ((buf[3] & ENCRYPTED) || (buf[3] & CONTINUATION) ||
0228         (buf[3] & RESERVED)) {
0229         pr_debug("unknown flags?\n");
0230         goto out_free_buf;
0231     }
0232 
0233     ret = 10;
0234     if (buf[3] & EXTRA_FIELD) {
0235         ret += 2 + buf[10] + (buf[11] << 8);
0236         if (unlikely(ret >= LBUFSIZE)) {
0237             pr_debug("buffer overflow (EXTRA)?\n");
0238             goto out_free_buf;
0239         }
0240     }
0241     if (buf[3] & ORIG_NAME) {
0242         while (ret < LBUFSIZE && buf[ret++] != 0)
0243             ;
0244         if (unlikely(ret == LBUFSIZE)) {
0245             pr_debug("buffer overflow (ORIG_NAME)?\n");
0246             goto out_free_buf;
0247         }
0248     }
0249     if (buf[3] & COMMENT) {
0250         while (ret < LBUFSIZE && buf[ret++] != 0)
0251             ;
0252         if (unlikely(ret == LBUFSIZE)) {
0253             pr_debug("buffer overflow (COMMENT)?\n");
0254             goto out_free_buf;
0255         }
0256     }
0257 
0258     strm.next_in += ret;
0259     strm.avail_in -= ret;
0260 
0261     strm.next_out = dst;
0262     strm.avail_out = len;
0263     strm.total_out = 0;
0264 
0265     if (zlib_inflateInit2(&strm, -MAX_WBITS) != Z_OK) {
0266         pr_debug("zlib init failed?\n");
0267         goto out_free_buf;
0268     }
0269 
0270     while ((ret = zlib_inflate(&strm, Z_NO_FLUSH)) == Z_OK) {
0271         ret = kernel_read(bprm->file, buf, LBUFSIZE, &fpos);
0272         if (ret <= 0)
0273             break;
0274         len -= ret;
0275 
0276         strm.next_in = buf;
0277         strm.avail_in = ret;
0278         strm.total_in = 0;
0279     }
0280 
0281     if (ret < 0) {
0282         pr_debug("decompression failed (%d), %s\n",
0283             ret, strm.msg);
0284         goto out_zlib;
0285     }
0286 
0287     retval = 0;
0288 out_zlib:
0289     zlib_inflateEnd(&strm);
0290 out_free_buf:
0291     kfree(buf);
0292 out_free:
0293     kfree(strm.workspace);
0294     return retval;
0295 }
0296 
0297 #endif /* CONFIG_BINFMT_ZFLAT */
0298 
0299 /****************************************************************************/
0300 
0301 static unsigned long
0302 calc_reloc(unsigned long r, struct lib_info *p)
0303 {
0304     unsigned long addr;
0305     unsigned long start_brk;
0306     unsigned long start_data;
0307     unsigned long text_len;
0308     unsigned long start_code;
0309 
0310     start_brk = p->lib_list[0].start_brk;
0311     start_data = p->lib_list[0].start_data;
0312     start_code = p->lib_list[0].start_code;
0313     text_len = p->lib_list[0].text_len;
0314 
0315     if (r > start_brk - start_data + text_len) {
0316         pr_err("reloc outside program 0x%lx (0 - 0x%lx/0x%lx)",
0317                r, start_brk-start_data+text_len, text_len);
0318         goto failed;
0319     }
0320 
0321     if (r < text_len)           /* In text segment */
0322         addr = r + start_code;
0323     else                    /* In data segment */
0324         addr = r - text_len + start_data;
0325 
0326     /* Range checked already above so doing the range tests is redundant...*/
0327     return addr;
0328 
0329 failed:
0330     pr_cont(", killing %s!\n", current->comm);
0331     send_sig(SIGSEGV, current, 0);
0332 
0333     return RELOC_FAILED;
0334 }
0335 
0336 /****************************************************************************/
0337 
0338 #ifdef CONFIG_BINFMT_FLAT_OLD
0339 static void old_reloc(unsigned long rl)
0340 {
0341     static const char *segment[] = { "TEXT", "DATA", "BSS", "*UNKNOWN*" };
0342     flat_v2_reloc_t r;
0343     unsigned long __user *ptr;
0344     unsigned long val;
0345 
0346     r.value = rl;
0347 #if defined(CONFIG_COLDFIRE)
0348     ptr = (unsigned long __user *)(current->mm->start_code + r.reloc.offset);
0349 #else
0350     ptr = (unsigned long __user *)(current->mm->start_data + r.reloc.offset);
0351 #endif
0352     get_user(val, ptr);
0353 
0354     pr_debug("Relocation of variable at DATASEG+%x "
0355          "(address %p, currently %lx) into segment %s\n",
0356          r.reloc.offset, ptr, val, segment[r.reloc.type]);
0357 
0358     switch (r.reloc.type) {
0359     case OLD_FLAT_RELOC_TYPE_TEXT:
0360         val += current->mm->start_code;
0361         break;
0362     case OLD_FLAT_RELOC_TYPE_DATA:
0363         val += current->mm->start_data;
0364         break;
0365     case OLD_FLAT_RELOC_TYPE_BSS:
0366         val += current->mm->end_data;
0367         break;
0368     default:
0369         pr_err("Unknown relocation type=%x\n", r.reloc.type);
0370         break;
0371     }
0372     put_user(val, ptr);
0373 
0374     pr_debug("Relocation became %lx\n", val);
0375 }
0376 #endif /* CONFIG_BINFMT_FLAT_OLD */
0377 
0378 /****************************************************************************/
0379 
0380 static inline u32 __user *skip_got_header(u32 __user *rp)
0381 {
0382     if (IS_ENABLED(CONFIG_RISCV)) {
0383         /*
0384          * RISC-V has a 16 byte GOT PLT header for elf64-riscv
0385          * and 8 byte GOT PLT header for elf32-riscv.
0386          * Skip the whole GOT PLT header, since it is reserved
0387          * for the dynamic linker (ld.so).
0388          */
0389         u32 rp_val0, rp_val1;
0390 
0391         if (get_user(rp_val0, rp))
0392             return rp;
0393         if (get_user(rp_val1, rp + 1))
0394             return rp;
0395 
0396         if (rp_val0 == 0xffffffff && rp_val1 == 0xffffffff)
0397             rp += 4;
0398         else if (rp_val0 == 0xffffffff)
0399             rp += 2;
0400     }
0401     return rp;
0402 }
0403 
0404 static int load_flat_file(struct linux_binprm *bprm,
0405         struct lib_info *libinfo, unsigned long *extra_stack)
0406 {
0407     struct flat_hdr *hdr;
0408     unsigned long textpos, datapos, realdatastart;
0409     u32 text_len, data_len, bss_len, stack_len, full_data, flags;
0410     unsigned long len, memp, memp_size, extra, rlim;
0411     __be32 __user *reloc;
0412     u32 __user *rp;
0413     int i, rev, relocs;
0414     loff_t fpos;
0415     unsigned long start_code, end_code;
0416     ssize_t result;
0417     int ret;
0418 
0419     hdr = ((struct flat_hdr *) bprm->buf);      /* exec-header */
0420 
0421     text_len  = ntohl(hdr->data_start);
0422     data_len  = ntohl(hdr->data_end) - ntohl(hdr->data_start);
0423     bss_len   = ntohl(hdr->bss_end) - ntohl(hdr->data_end);
0424     stack_len = ntohl(hdr->stack_size);
0425     if (extra_stack) {
0426         stack_len += *extra_stack;
0427         *extra_stack = stack_len;
0428     }
0429     relocs    = ntohl(hdr->reloc_count);
0430     flags     = ntohl(hdr->flags);
0431     rev       = ntohl(hdr->rev);
0432     full_data = data_len + relocs * sizeof(unsigned long);
0433 
0434     if (strncmp(hdr->magic, "bFLT", 4)) {
0435         /*
0436          * Previously, here was a printk to tell people
0437          *   "BINFMT_FLAT: bad header magic".
0438          * But for the kernel which also use ELF FD-PIC format, this
0439          * error message is confusing.
0440          * because a lot of people do not manage to produce good
0441          */
0442         ret = -ENOEXEC;
0443         goto err;
0444     }
0445 
0446     if (flags & FLAT_FLAG_KTRACE)
0447         pr_info("Loading file: %s\n", bprm->filename);
0448 
0449 #ifdef CONFIG_BINFMT_FLAT_OLD
0450     if (rev != FLAT_VERSION && rev != OLD_FLAT_VERSION) {
0451         pr_err("bad flat file version 0x%x (supported 0x%lx and 0x%lx)\n",
0452                rev, FLAT_VERSION, OLD_FLAT_VERSION);
0453         ret = -ENOEXEC;
0454         goto err;
0455     }
0456 
0457     /*
0458      * fix up the flags for the older format,  there were all kinds
0459      * of endian hacks,  this only works for the simple cases
0460      */
0461     if (rev == OLD_FLAT_VERSION &&
0462        (flags || IS_ENABLED(CONFIG_BINFMT_FLAT_OLD_ALWAYS_RAM)))
0463         flags = FLAT_FLAG_RAM;
0464 
0465 #else /* CONFIG_BINFMT_FLAT_OLD */
0466     if (rev != FLAT_VERSION) {
0467         pr_err("bad flat file version 0x%x (supported 0x%lx)\n",
0468                rev, FLAT_VERSION);
0469         ret = -ENOEXEC;
0470         goto err;
0471     }
0472 #endif /* !CONFIG_BINFMT_FLAT_OLD */
0473 
0474     /*
0475      * Make sure the header params are sane.
0476      * 28 bits (256 MB) is way more than reasonable in this case.
0477      * If some top bits are set we have probable binary corruption.
0478     */
0479     if ((text_len | data_len | bss_len | stack_len | full_data) >> 28) {
0480         pr_err("bad header\n");
0481         ret = -ENOEXEC;
0482         goto err;
0483     }
0484 
0485 #ifndef CONFIG_BINFMT_ZFLAT
0486     if (flags & (FLAT_FLAG_GZIP|FLAT_FLAG_GZDATA)) {
0487         pr_err("Support for ZFLAT executables is not enabled.\n");
0488         ret = -ENOEXEC;
0489         goto err;
0490     }
0491 #endif
0492 
0493     /*
0494      * Check initial limits. This avoids letting people circumvent
0495      * size limits imposed on them by creating programs with large
0496      * arrays in the data or bss.
0497      */
0498     rlim = rlimit(RLIMIT_DATA);
0499     if (rlim >= RLIM_INFINITY)
0500         rlim = ~0;
0501     if (data_len + bss_len > rlim) {
0502         ret = -ENOMEM;
0503         goto err;
0504     }
0505 
0506     /* Flush all traces of the currently running executable */
0507     ret = begin_new_exec(bprm);
0508     if (ret)
0509         goto err;
0510 
0511     /* OK, This is the point of no return */
0512     set_personality(PER_LINUX_32BIT);
0513     setup_new_exec(bprm);
0514 
0515     /*
0516      * calculate the extra space we need to map in
0517      */
0518     extra = max_t(unsigned long, bss_len + stack_len,
0519             relocs * sizeof(unsigned long));
0520 
0521     /*
0522      * there are a couple of cases here,  the separate code/data
0523      * case,  and then the fully copied to RAM case which lumps
0524      * it all together.
0525      */
0526     if (!IS_ENABLED(CONFIG_MMU) && !(flags & (FLAT_FLAG_RAM|FLAT_FLAG_GZIP))) {
0527         /*
0528          * this should give us a ROM ptr,  but if it doesn't we don't
0529          * really care
0530          */
0531         pr_debug("ROM mapping of file (we hope)\n");
0532 
0533         textpos = vm_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC,
0534                   MAP_PRIVATE, 0);
0535         if (!textpos || IS_ERR_VALUE(textpos)) {
0536             ret = textpos;
0537             if (!textpos)
0538                 ret = -ENOMEM;
0539             pr_err("Unable to mmap process text, errno %d\n", ret);
0540             goto err;
0541         }
0542 
0543         len = data_len + extra +
0544             DATA_START_OFFSET_WORDS * sizeof(unsigned long);
0545         len = PAGE_ALIGN(len);
0546         realdatastart = vm_mmap(NULL, 0, len,
0547             PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0);
0548 
0549         if (realdatastart == 0 || IS_ERR_VALUE(realdatastart)) {
0550             ret = realdatastart;
0551             if (!realdatastart)
0552                 ret = -ENOMEM;
0553             pr_err("Unable to allocate RAM for process data, "
0554                    "errno %d\n", ret);
0555             vm_munmap(textpos, text_len);
0556             goto err;
0557         }
0558         datapos = ALIGN(realdatastart +
0559                 DATA_START_OFFSET_WORDS * sizeof(unsigned long),
0560                 FLAT_DATA_ALIGN);
0561 
0562         pr_debug("Allocated data+bss+stack (%u bytes): %lx\n",
0563              data_len + bss_len + stack_len, datapos);
0564 
0565         fpos = ntohl(hdr->data_start);
0566 #ifdef CONFIG_BINFMT_ZFLAT
0567         if (flags & FLAT_FLAG_GZDATA) {
0568             result = decompress_exec(bprm, fpos, (char *)datapos,
0569                          full_data, 0);
0570         } else
0571 #endif
0572         {
0573             result = read_code(bprm->file, datapos, fpos,
0574                     full_data);
0575         }
0576         if (IS_ERR_VALUE(result)) {
0577             ret = result;
0578             pr_err("Unable to read data+bss, errno %d\n", ret);
0579             vm_munmap(textpos, text_len);
0580             vm_munmap(realdatastart, len);
0581             goto err;
0582         }
0583 
0584         reloc = (__be32 __user *)
0585             (datapos + (ntohl(hdr->reloc_start) - text_len));
0586         memp = realdatastart;
0587         memp_size = len;
0588     } else {
0589 
0590         len = text_len + data_len + extra +
0591             DATA_START_OFFSET_WORDS * sizeof(u32);
0592         len = PAGE_ALIGN(len);
0593         textpos = vm_mmap(NULL, 0, len,
0594             PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
0595 
0596         if (!textpos || IS_ERR_VALUE(textpos)) {
0597             ret = textpos;
0598             if (!textpos)
0599                 ret = -ENOMEM;
0600             pr_err("Unable to allocate RAM for process text/data, "
0601                    "errno %d\n", ret);
0602             goto err;
0603         }
0604 
0605         realdatastart = textpos + ntohl(hdr->data_start);
0606         datapos = ALIGN(realdatastart +
0607                 DATA_START_OFFSET_WORDS * sizeof(u32),
0608                 FLAT_DATA_ALIGN);
0609 
0610         reloc = (__be32 __user *)
0611             (datapos + (ntohl(hdr->reloc_start) - text_len));
0612         memp = textpos;
0613         memp_size = len;
0614 #ifdef CONFIG_BINFMT_ZFLAT
0615         /*
0616          * load it all in and treat it like a RAM load from now on
0617          */
0618         if (flags & FLAT_FLAG_GZIP) {
0619 #ifndef CONFIG_MMU
0620             result = decompress_exec(bprm, sizeof(struct flat_hdr),
0621                      (((char *)textpos) + sizeof(struct flat_hdr)),
0622                      (text_len + full_data
0623                           - sizeof(struct flat_hdr)),
0624                      0);
0625             memmove((void *) datapos, (void *) realdatastart,
0626                     full_data);
0627 #else
0628             /*
0629              * This is used on MMU systems mainly for testing.
0630              * Let's use a kernel buffer to simplify things.
0631              */
0632             long unz_text_len = text_len - sizeof(struct flat_hdr);
0633             long unz_len = unz_text_len + full_data;
0634             char *unz_data = vmalloc(unz_len);
0635             if (!unz_data) {
0636                 result = -ENOMEM;
0637             } else {
0638                 result = decompress_exec(bprm, sizeof(struct flat_hdr),
0639                              unz_data, unz_len, 0);
0640                 if (result == 0 &&
0641                     (copy_to_user((void __user *)textpos + sizeof(struct flat_hdr),
0642                           unz_data, unz_text_len) ||
0643                      copy_to_user((void __user *)datapos,
0644                           unz_data + unz_text_len, full_data)))
0645                     result = -EFAULT;
0646                 vfree(unz_data);
0647             }
0648 #endif
0649         } else if (flags & FLAT_FLAG_GZDATA) {
0650             result = read_code(bprm->file, textpos, 0, text_len);
0651             if (!IS_ERR_VALUE(result)) {
0652 #ifndef CONFIG_MMU
0653                 result = decompress_exec(bprm, text_len, (char *) datapos,
0654                          full_data, 0);
0655 #else
0656                 char *unz_data = vmalloc(full_data);
0657                 if (!unz_data) {
0658                     result = -ENOMEM;
0659                 } else {
0660                     result = decompress_exec(bprm, text_len,
0661                                unz_data, full_data, 0);
0662                     if (result == 0 &&
0663                         copy_to_user((void __user *)datapos,
0664                              unz_data, full_data))
0665                         result = -EFAULT;
0666                     vfree(unz_data);
0667                 }
0668 #endif
0669             }
0670         } else
0671 #endif /* CONFIG_BINFMT_ZFLAT */
0672         {
0673             result = read_code(bprm->file, textpos, 0, text_len);
0674             if (!IS_ERR_VALUE(result))
0675                 result = read_code(bprm->file, datapos,
0676                            ntohl(hdr->data_start),
0677                            full_data);
0678         }
0679         if (IS_ERR_VALUE(result)) {
0680             ret = result;
0681             pr_err("Unable to read code+data+bss, errno %d\n", ret);
0682             vm_munmap(textpos, text_len + data_len + extra +
0683                   DATA_START_OFFSET_WORDS * sizeof(u32));
0684             goto err;
0685         }
0686     }
0687 
0688     start_code = textpos + sizeof(struct flat_hdr);
0689     end_code = textpos + text_len;
0690     text_len -= sizeof(struct flat_hdr); /* the real code len */
0691 
0692     /* The main program needs a little extra setup in the task structure */
0693     current->mm->start_code = start_code;
0694     current->mm->end_code = end_code;
0695     current->mm->start_data = datapos;
0696     current->mm->end_data = datapos + data_len;
0697     /*
0698      * set up the brk stuff, uses any slack left in data/bss/stack
0699      * allocation.  We put the brk after the bss (between the bss
0700      * and stack) like other platforms.
0701      * Userspace code relies on the stack pointer starting out at
0702      * an address right at the end of a page.
0703      */
0704     current->mm->start_brk = datapos + data_len + bss_len;
0705     current->mm->brk = (current->mm->start_brk + 3) & ~3;
0706 #ifndef CONFIG_MMU
0707     current->mm->context.end_brk = memp + memp_size - stack_len;
0708 #endif
0709 
0710     if (flags & FLAT_FLAG_KTRACE) {
0711         pr_info("Mapping is %lx, Entry point is %x, data_start is %x\n",
0712             textpos, 0x00ffffff&ntohl(hdr->entry), ntohl(hdr->data_start));
0713         pr_info("%s %s: TEXT=%lx-%lx DATA=%lx-%lx BSS=%lx-%lx\n",
0714             "Load", bprm->filename,
0715             start_code, end_code, datapos, datapos + data_len,
0716             datapos + data_len, (datapos + data_len + bss_len + 3) & ~3);
0717     }
0718 
0719     /* Store the current module values into the global library structure */
0720     libinfo->lib_list[0].start_code = start_code;
0721     libinfo->lib_list[0].start_data = datapos;
0722     libinfo->lib_list[0].start_brk = datapos + data_len + bss_len;
0723     libinfo->lib_list[0].text_len = text_len;
0724     libinfo->lib_list[0].loaded = 1;
0725     libinfo->lib_list[0].entry = (0x00ffffff & ntohl(hdr->entry)) + textpos;
0726     libinfo->lib_list[0].build_date = ntohl(hdr->build_date);
0727 
0728     /*
0729      * We just load the allocations into some temporary memory to
0730      * help simplify all this mumbo jumbo
0731      *
0732      * We've got two different sections of relocation entries.
0733      * The first is the GOT which resides at the beginning of the data segment
0734      * and is terminated with a -1.  This one can be relocated in place.
0735      * The second is the extra relocation entries tacked after the image's
0736      * data segment. These require a little more processing as the entry is
0737      * really an offset into the image which contains an offset into the
0738      * image.
0739      */
0740     if (flags & FLAT_FLAG_GOTPIC) {
0741         rp = skip_got_header((u32 __user *) datapos);
0742         for (; ; rp++) {
0743             u32 addr, rp_val;
0744             if (get_user(rp_val, rp))
0745                 return -EFAULT;
0746             if (rp_val == 0xffffffff)
0747                 break;
0748             if (rp_val) {
0749                 addr = calc_reloc(rp_val, libinfo);
0750                 if (addr == RELOC_FAILED) {
0751                     ret = -ENOEXEC;
0752                     goto err;
0753                 }
0754                 if (put_user(addr, rp))
0755                     return -EFAULT;
0756             }
0757         }
0758     }
0759 
0760     /*
0761      * Now run through the relocation entries.
0762      * We've got to be careful here as C++ produces relocatable zero
0763      * entries in the constructor and destructor tables which are then
0764      * tested for being not zero (which will always occur unless we're
0765      * based from address zero).  This causes an endless loop as __start
0766      * is at zero.  The solution used is to not relocate zero addresses.
0767      * This has the negative side effect of not allowing a global data
0768      * reference to be statically initialised to _stext (I've moved
0769      * __start to address 4 so that is okay).
0770      */
0771     if (rev > OLD_FLAT_VERSION) {
0772         for (i = 0; i < relocs; i++) {
0773             u32 addr, relval;
0774             __be32 tmp;
0775 
0776             /*
0777              * Get the address of the pointer to be
0778              * relocated (of course, the address has to be
0779              * relocated first).
0780              */
0781             if (get_user(tmp, reloc + i))
0782                 return -EFAULT;
0783             relval = ntohl(tmp);
0784             addr = flat_get_relocate_addr(relval);
0785             rp = (u32 __user *)calc_reloc(addr, libinfo);
0786             if (rp == (u32 __user *)RELOC_FAILED) {
0787                 ret = -ENOEXEC;
0788                 goto err;
0789             }
0790 
0791             /* Get the pointer's value.  */
0792             ret = flat_get_addr_from_rp(rp, relval, flags, &addr);
0793             if (unlikely(ret))
0794                 goto err;
0795 
0796             if (addr != 0) {
0797                 /*
0798                  * Do the relocation.  PIC relocs in the data section are
0799                  * already in target order
0800                  */
0801                 if ((flags & FLAT_FLAG_GOTPIC) == 0) {
0802                     /*
0803                      * Meh, the same value can have a different
0804                      * byte order based on a flag..
0805                      */
0806                     addr = ntohl((__force __be32)addr);
0807                 }
0808                 addr = calc_reloc(addr, libinfo);
0809                 if (addr == RELOC_FAILED) {
0810                     ret = -ENOEXEC;
0811                     goto err;
0812                 }
0813 
0814                 /* Write back the relocated pointer.  */
0815                 ret = flat_put_addr_at_rp(rp, addr, relval);
0816                 if (unlikely(ret))
0817                     goto err;
0818             }
0819         }
0820 #ifdef CONFIG_BINFMT_FLAT_OLD
0821     } else {
0822         for (i = 0; i < relocs; i++) {
0823             __be32 relval;
0824             if (get_user(relval, reloc + i))
0825                 return -EFAULT;
0826             old_reloc(ntohl(relval));
0827         }
0828 #endif /* CONFIG_BINFMT_FLAT_OLD */
0829     }
0830 
0831     flush_icache_user_range(start_code, end_code);
0832 
0833     /* zero the BSS,  BRK and stack areas */
0834     if (clear_user((void __user *)(datapos + data_len), bss_len +
0835                (memp + memp_size - stack_len -      /* end brk */
0836                libinfo->lib_list[0].start_brk) +    /* start brk */
0837                stack_len))
0838         return -EFAULT;
0839 
0840     return 0;
0841 err:
0842     return ret;
0843 }
0844 
0845 
0846 /****************************************************************************/
0847 
0848 /*
0849  * These are the functions used to load flat style executables and shared
0850  * libraries.  There is no binary dependent code anywhere else.
0851  */
0852 
0853 static int load_flat_binary(struct linux_binprm *bprm)
0854 {
0855     struct lib_info libinfo;
0856     struct pt_regs *regs = current_pt_regs();
0857     unsigned long stack_len = 0;
0858     unsigned long start_addr;
0859     int res;
0860     int i, j;
0861 
0862     memset(&libinfo, 0, sizeof(libinfo));
0863 
0864     /*
0865      * We have to add the size of our arguments to our stack size
0866      * otherwise it's too easy for users to create stack overflows
0867      * by passing in a huge argument list.  And yes,  we have to be
0868      * pedantic and include space for the argv/envp array as it may have
0869      * a lot of entries.
0870      */
0871 #ifndef CONFIG_MMU
0872     stack_len += PAGE_SIZE * MAX_ARG_PAGES - bprm->p; /* the strings */
0873 #endif
0874     stack_len += (bprm->argc + 1) * sizeof(char *);   /* the argv array */
0875     stack_len += (bprm->envc + 1) * sizeof(char *);   /* the envp array */
0876     stack_len = ALIGN(stack_len, FLAT_STACK_ALIGN);
0877 
0878     res = load_flat_file(bprm, &libinfo, &stack_len);
0879     if (res < 0)
0880         return res;
0881 
0882     /* Update data segment pointers for all libraries */
0883     for (i = 0; i < MAX_SHARED_LIBS; i++) {
0884         if (!libinfo.lib_list[i].loaded)
0885             continue;
0886         for (j = 0; j < MAX_SHARED_LIBS; j++) {
0887             unsigned long val = libinfo.lib_list[j].loaded ?
0888                 libinfo.lib_list[j].start_data : UNLOADED_LIB;
0889             unsigned long __user *p = (unsigned long __user *)
0890                 libinfo.lib_list[i].start_data;
0891             p -= j + 1;
0892             if (put_user(val, p))
0893                 return -EFAULT;
0894         }
0895     }
0896 
0897     set_binfmt(&flat_format);
0898 
0899 #ifdef CONFIG_MMU
0900     res = setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT);
0901     if (!res)
0902         res = create_flat_tables(bprm, bprm->p);
0903 #else
0904     /* Stash our initial stack pointer into the mm structure */
0905     current->mm->start_stack =
0906         ((current->mm->context.end_brk + stack_len + 3) & ~3) - 4;
0907     pr_debug("sp=%lx\n", current->mm->start_stack);
0908 
0909     /* copy the arg pages onto the stack */
0910     res = transfer_args_to_stack(bprm, &current->mm->start_stack);
0911     if (!res)
0912         res = create_flat_tables(bprm, current->mm->start_stack);
0913 #endif
0914     if (res)
0915         return res;
0916 
0917     /* Fake some return addresses to ensure the call chain will
0918      * initialise library in order for us.  We are required to call
0919      * lib 1 first, then 2, ... and finally the main program (id 0).
0920      */
0921     start_addr = libinfo.lib_list[0].entry;
0922 
0923 #ifdef FLAT_PLAT_INIT
0924     FLAT_PLAT_INIT(regs);
0925 #endif
0926 
0927     finalize_exec(bprm);
0928     pr_debug("start_thread(regs=0x%p, entry=0x%lx, start_stack=0x%lx)\n",
0929          regs, start_addr, current->mm->start_stack);
0930     start_thread(regs, start_addr, current->mm->start_stack);
0931 
0932     return 0;
0933 }
0934 
0935 /****************************************************************************/
0936 
0937 static int __init init_flat_binfmt(void)
0938 {
0939     register_binfmt(&flat_format);
0940     return 0;
0941 }
0942 core_initcall(init_flat_binfmt);
0943 
0944 /****************************************************************************/