0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
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
0055
0056
0057
0058
0059 #define FLAT_DATA_ALIGN (0x20)
0060
0061
0062
0063
0064
0065
0066 #define FLAT_STACK_ALIGN max_t(unsigned long, sizeof(void *), ARCH_SLAB_MINALIGN)
0067
0068 #define RELOC_FAILED 0xff00ff01
0069 #define UNLOADED_LIB 0x7ff000ff
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;
0082 unsigned long start_data;
0083 unsigned long start_brk;
0084 unsigned long text_len;
0085 unsigned long entry;
0086 unsigned long build_date;
0087 bool 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
0102
0103
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;
0119 sp -= 1;
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
0172 #define ASCII_FLAG 0x01
0173 #define CONTINUATION 0x02
0174 #define EXTRA_FIELD 0x04
0175 #define ORIG_NAME 0x08
0176 #define COMMENT 0x10
0177 #define ENCRYPTED 0x20
0178 #define RESERVED 0xC0
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
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
0210 if (ret < 10) {
0211 pr_debug("file too small?\n");
0212 goto out_free_buf;
0213 }
0214
0215
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
0222 if (buf[2] != 8) {
0223 pr_debug("unknown compression method?\n");
0224 goto out_free_buf;
0225 }
0226
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
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)
0322 addr = r + start_code;
0323 else
0324 addr = r - text_len + start_data;
0325
0326
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
0377
0378
0379
0380 static inline u32 __user *skip_got_header(u32 __user *rp)
0381 {
0382 if (IS_ENABLED(CONFIG_RISCV)) {
0383
0384
0385
0386
0387
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);
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
0437
0438
0439
0440
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
0459
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
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
0473
0474
0475
0476
0477
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
0495
0496
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
0507 ret = begin_new_exec(bprm);
0508 if (ret)
0509 goto err;
0510
0511
0512 set_personality(PER_LINUX_32BIT);
0513 setup_new_exec(bprm);
0514
0515
0516
0517
0518 extra = max_t(unsigned long, bss_len + stack_len,
0519 relocs * sizeof(unsigned long));
0520
0521
0522
0523
0524
0525
0526 if (!IS_ENABLED(CONFIG_MMU) && !(flags & (FLAT_FLAG_RAM|FLAT_FLAG_GZIP))) {
0527
0528
0529
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
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
0630
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
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);
0691
0692
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
0699
0700
0701
0702
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
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
0730
0731
0732
0733
0734
0735
0736
0737
0738
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
0762
0763
0764
0765
0766
0767
0768
0769
0770
0771 if (rev > OLD_FLAT_VERSION) {
0772 for (i = 0; i < relocs; i++) {
0773 u32 addr, relval;
0774 __be32 tmp;
0775
0776
0777
0778
0779
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
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
0799
0800
0801 if ((flags & FLAT_FLAG_GOTPIC) == 0) {
0802
0803
0804
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
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
0829 }
0830
0831 flush_icache_user_range(start_code, end_code);
0832
0833
0834 if (clear_user((void __user *)(datapos + data_len), bss_len +
0835 (memp + memp_size - stack_len -
0836 libinfo->lib_list[0].start_brk) +
0837 stack_len))
0838 return -EFAULT;
0839
0840 return 0;
0841 err:
0842 return ret;
0843 }
0844
0845
0846
0847
0848
0849
0850
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
0866
0867
0868
0869
0870
0871 #ifndef CONFIG_MMU
0872 stack_len += PAGE_SIZE * MAX_ARG_PAGES - bprm->p;
0873 #endif
0874 stack_len += (bprm->argc + 1) * sizeof(char *);
0875 stack_len += (bprm->envc + 1) * sizeof(char *);
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
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
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
0910 res = transfer_args_to_stack(bprm, ¤t->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
0918
0919
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