Back to home page

LXR

 
 

    


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