Fs/exec.c
1674 SYSCALL_DEFINE3(execve,
1675 ▸ ▸ const char __user *, filename,
1676 ▸ ▸ const char __user *const __user *, argv,
1677 ▸ ▸ const char __user *const __user *, envp)
1678 {
1679 ▸ struct filename *path = getname(filename); //将一个可执行文件的名称装入到一个新分配的页面中。
1680 ▸ int error = PTR_ERR(path);
1681 ▸ if (!IS_ERR(path)) {
1682 ▸ ▸ error = do_execve(path->name, argv, envp); //执行可执行文件
1683 ▸ ▸ putname(path);
1684 ▸ }
1685 ▸ return error;
1686 }
在这里1674-1677这段代码的SYSCALL_DEFINE3(execve,filename,argv.envp)等同于:
= SYSCALL_DEFINEx(3,## execve,__VA_ARGS)
= asmlinkage long sys_execve(SC_DECL,(_VA_ARGS__))…
= asmlinkage long sys_execve(filename,argv.envp)
参照include/linux/syscalls.h
176 #define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
186 #define __SYSCALL_DEFINEx(x, name, ...)▸▸ ▸ ▸ ▸ \
187 ▸ asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));▸ \
188 ▸ static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__));▸ \
189 ▸ asmlinkage long SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__))▸ \
190 ▸ {▸ ▸ ▸ ▸ ▸ ▸ ▸ ▸ \
191 ▸ ▸ long ret = SYSC##name(__MAP(x,__SC_CAST,__VA_ARGS__));▸ \
192 ▸ ▸ __MAP(x,__SC_TEST,__VA_ARGS__);▸▸ ▸ ▸ \
193 ▸ ▸ __PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__));▸ \
194 ▸ ▸ return ret;▸ ▸ ▸ ▸ ▸ ▸ \
195 ▸ }▸ ▸ ▸ ▸ ▸ ▸ ▸ ▸ \
196 ▸ SYSCALL_ALIAS(sys##name, SyS##name);▸ ▸ ▸ ▸ \
197 ▸ static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__))
198
=>
99 #define __SC_DECL(t, a)▸t a
do_execve code:
1580 int do_execve(const char *filename,
1581 ▸ const char __user *const __user *__argv,
1582 ▸ const char __user *const __user *__envp)
1583 {
1584 ▸ struct user_arg_ptr argv = { .ptr.native = __argv }; //封装结构
1585 ▸ struct user_arg_ptr envp = { .ptr.native = __envp };
1586 ▸ return do_execve_common(filename, argv, envp); //调用do_execve_common
1587 }
1588
1450 /*
1451 * sys_execve() executes a new program.
1452 */
1453 static int do_execve_common(const char *filename,
1454 ▸ ▸ ▸ ▸ struct user_arg_ptr argv,
1455 ▸ ▸ ▸ ▸ struct user_arg_ptr envp)
1456 {
1457 ▸ struct linux_binprm *bprm; //保存和要执行的文件相关数据
1458 ▸ struct file *file;
1459 ▸ struct files_struct *displaced;
1460 ▸ bool clear_in_exec;
1461 ▸ int retval;
1462 ▸ const struct cred *cred = current_cred();
1463
1464 ▸ /*
1465 ▸ * We move the actual failure in case of RLIMIT_NPROC excess from
1466 ▸ * set*uid() to execve() because too many poorly written programs
1467 ▸ * don't check setuid() return code. Here we additionally recheck
1468 ▸ * whether NPROC limit is still exceeded.
1469 ▸ */
1470 ▸ if ((current->flags & PF_NPROC_EXCEEDED) &&
1471 ▸ atomic_read(&cred->user->processes) > rlimit(RLIMIT_NPROC)) {
1472 ▸ ▸ retval = -EAGAIN;
1473 ▸ ▸ goto out_ret;
1474 ▸ }
1475
1476 ▸ /* We're below the limit (still or again), so we don't want to make
1477 ▸ * further execve() calls fail. */
1478 ▸ current->flags &= ~PF_NPROC_EXCEEDED;
1479
1480 ▸ retval = unshare_files(&displaced);
1481 ▸ if (retval)
1482 ▸ ▸ goto out_ret;
1483
1484 ▸ retval = -ENOMEM;
1485 ▸ bprm = kzalloc(sizeof(*bprm), GFP_KERNEL); //在堆上分配一个linux_binprm结构
1486 ▸ if (!bprm)
1487 ▸ ▸ goto out_files;
1488
1489 ▸ retval = prepare_bprm_creds(bprm);
1490 ▸ if (retval)
1491 ▸ ▸ goto out_free;
1492
1493 ▸ retval = check_unsafe_exec(bprm);
1494 ▸ if (retval < 0)
1495 ▸ ▸ goto out_free;
1496 ▸ clear_in_exec = retval;
1497 ▸ current->in_execve = 1;
1498
1499 ▸ file = open_exec(filename); //调用open_exec 读取可执行文件
1500 ▸ retval = PTR_ERR(file);
1501 ▸ if (IS_ERR(file))
1502 ▸ ▸ goto out_unmark;
1503
1504 ▸ sched_exec(); //选择确定最小负载的cpu执行,并把当前process转移过去
1506 ▸ bprm->file = file;
1507 ▸ bprm->filename = filename;
1508 ▸ bprm->interp = filename;
1509
1510 ▸ retval = bprm_mm_init(bprm); //调用bprm_mm_init 为新程序初始化内存
1511 ▸ if (retval)
1512 ▸ ▸ goto out_file;
1513
1514 ▸ bprm->argc = count(argv, MAX_ARG_STRINGS);
1515 ▸ if ((retval = bprm->argc) < 0)
1516 ▸ ▸ goto out;
1517
1518 ▸ bprm->envc = count(envp, MAX_ARG_STRINGS);
1519 ▸ if ((retval = bprm->envc) < 0)
1520 ▸ ▸ goto out;
1521
1522 ▸ retval = prepare_binprm(bprm); 填充bprm结构
1523 ▸ if (retval < 0)
1524 ▸ ▸ goto out;
1525
1526 ▸ retval = copy_strings_kernel(1, &bprm->filename, bprm); //拷贝filename到新进程中
1527 ▸ if (retval < 0)
1528 ▸ ▸ goto out;
1529
1530 ▸ bprm->exec = bprm->p;
1531 ▸ retval = copy_strings(bprm->envc, envp, bprm); //拷贝环境变量envp到新进程中
1532 ▸ if (retval < 0)
1533 ▸ ▸ goto out;
1534
1535 ▸ retval = copy_strings(bprm->argc, argv, bprm); //拷贝参数argv到新进程中
1536 ▸ if (retval < 0)
1537 ▸ ▸ goto out;
1538
1539 ▸ retval = search_binary_handler(bprm); //该函数式对formats链表进行扫描,并尝试每个load_binary函数,如果成功加载了文件的执行格式,对formats的扫描终止
1540 ▸ if (retval < 0)
1541 ▸ ▸ goto out;
1542
1543 ▸ /* execve succeeded */
1544 ▸ current->fs->in_exec = 0;
1545 ▸ current->in_execve = 0;
1546 ▸ acct_update_integrals(current);
1547 ▸ task_numa_free(current);
1548 ▸ free_bprm(bprm); //释放bprm 结构
1549 ▸ if (displaced)
1550 ▸ ▸ put_files_struct(displaced);
1551 ▸ return retval;
1552
1553 out:
1554 ▸ if (bprm->mm) {
1555 ▸ ▸ acct_arg_size(bprm, 0);
1556 ▸ ▸ mmput(bprm->mm);
1557 ▸ }
1558
1559 out_file:
1560 ▸ if (bprm->file) {
1561 ▸ ▸ allow_write_access(bprm->file);
1562 ▸ ▸ fput(bprm->file);
1563 ▸ }
1564
1565 out_unmark:
1566 ▸ if (clear_in_exec)
1567 ▸ ▸ current->fs->in_exec = 0;
1568 ▸ current->in_execve = 0;
1569
1570 out_free:
1571 ▸ free_bprm(bprm);
1572
1573 out_files:
1574 ▸ if (displaced)
1575 ▸ ▸ reset_files_struct(displaced);
1576 out_ret:
1577 ▸ return retval;
1578 }
1579
load_elf_binary函数,该函数位于fs/binfmt_elf.c中
569 static int load_elf_binary(struct linux_binprm *bprm)
570 {
571 ▸ struct file *interpreter = NULL; /* to shut gcc up */
572 ▸ unsigned long load_addr = 0, load_bias = 0;
573 ▸ int load_addr_set = 0;
574 ▸ char * elf_interpreter = NULL;
575 ▸ unsigned long error;
576 ▸ struct elf_phdr *elf_ppnt, *elf_phdata;
577 ▸ unsigned long elf_bss, elf_brk;
578 ▸ int retval, i;
579 ▸ unsigned int size;
580 ▸ unsigned long elf_entry;
581 ▸ unsigned long interp_load_addr = 0;
582 ▸ unsigned long start_code, end_code, start_data, end_data;
583 ▸ unsigned long reloc_func_desc __maybe_unused = 0;
584 ▸ int executable_stack = EXSTACK_DEFAULT;
585 ▸ unsigned long def_flags = 0;
586 ▸ struct pt_regs *regs = current_pt_regs();
587 ▸ struct {
588 ▸ ▸ struct elfhdr elf_ex;
589 ▸ ▸ struct elfhdr interp_elf_ex;
590 ▸ } *loc;
591
592 ▸ loc = kmalloc(sizeof(*loc), GFP_KERNEL);
593 ▸ if (!loc) {
594 ▸ ▸ retval = -ENOMEM;
595 ▸ ▸ goto out_ret;
596 ▸ }
597 ▸
598 ▸ /* Get the exec-header */
//读取可执行文件的首部,首部描述程序的段和所需 的共享库
599 ▸ loc->elf_ex = *((struct elfhdr *)bprm->buf);
600
600
601 ▸ retval = -ENOEXEC;
602 ▸ /* First of all, some simple consistency checks */
//一致性检测
603 ▸ if (memcmp(loc->elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
604 ▸ ▸ goto out;
605
606 ▸ if (loc->elf_ex.e_type != ET_EXEC && loc->elf_ex.e_type != ET_DYN)
607 ▸ ▸ goto out;
608 ▸ if (!elf_check_arch(&loc->elf_ex))
609 ▸ ▸ goto out;
610 ▸ if (!bprm->file->f_op || !bprm->file->f_op->mmap)
611 ▸ ▸ goto out;
612
613 ▸ /* Now read in all of the header information */
//读取所有的首部信息
614 ▸ if (loc->elf_ex.e_phentsize != sizeof(struct elf_phdr))
615 ▸ ▸ goto out;
616 ▸ if (loc->elf_ex.e_phnum < 1 ||
617 ▸ ▸ loc->elf_ex.e_phnum > 65536U / sizeof(struct elf_phdr))
618 ▸ ▸ goto out;
619 ▸ size = loc->elf_ex.e_phnum * sizeof(struct elf_phdr);
620 ▸ retval = -ENOMEM;
621 ▸ elf_phdata = kmalloc(size, GFP_KERNEL);
622 ▸ if (!elf_phdata)
623 ▸ ▸ goto out;
624
625 ▸ retval = kernel_read(bprm->file, loc->elf_ex.e_phoff,
626 ▸ ▸ ▸ (char *)elf_phdata, size);
627 ▸ if (retval != size) {
628 ▸ ▸ if (retval >= 0)
629 ▸ ▸ ▸ retval = -EIO;
630 ▸ ▸ goto out_free_ph;
631 ▸ }
632
633 ▸ elf_ppnt = elf_phdata;
634 ▸ elf_bss = 0;
635 ▸ elf_brk = 0;
636
637 ▸ start_code = ~0UL;
638 ▸ end_code = 0;
639 ▸ start_data = 0;
640 ▸ end_data = 0;
641 //从可执行文件中确定动态链接程序的路径名。并用它来确定共享库的位置,并把他们映射到内存。
642 ▸ for (i = 0; i < loc->elf_ex.e_phnum; i++) {
643 ▸ ▸ if (elf_ppnt->p_type == PT_INTERP) {
644 ▸ ▸ ▸ /* This is the program interpreter used for
645 ▸ ▸ ▸ * shared libraries - for now assume that this
646 ▸ ▸ ▸ * is an a.out format binary
647 ▸ ▸ ▸ */
648 ▸ ▸ ▸ retval = -ENOEXEC;
649 ▸ ▸ ▸ if (elf_ppnt->p_filesz > PATH_MAX ||▫
650 ▸ ▸ ▸ elf_ppnt->p_filesz < 2)
651 ▸ ▸ ▸ ▸ goto out_free_ph;
652
653 ▸ ▸ ▸ retval = -ENOMEM;
654 ▸ ▸ ▸ elf_interpreter = kmalloc(elf_ppnt->p_filesz,
655 ▸ ▸ ▸ ▸ ▸ ▸ GFP_KERNEL);
656 ▸ ▸ ▸ if (!elf_interpreter)
657 ▸ ▸ ▸ ▸ goto out_free_ph;
658
659 ▸ ▸ ▸ retval = kernel_read(bprm->file, elf_ppnt->p_offset,
660 ▸ ▸ ▸ ▸ ▸ elf_interpreter,
661 ▸ ▸ ▸ ▸ ▸ elf_ppnt->p_filesz);
662 ▸ ▸ ▸ if (retval != elf_ppnt->p_filesz) {
663 ▸ ▸ ▸ ▸ if (retval >= 0)
664 ▸ ▸ ▸ ▸ ▸ retval = -EIO;
665 ▸ ▸ ▸ ▸ goto out_free_interp;
666 ▸ ▸ ▸ }
667 ▸ ▸ ▸ /* make sure path is NULL terminated */
668 ▸ ▸ ▸ retval = -ENOEXEC;
669 ▸ ▸ ▸ if (elf_interpreter[elf_ppnt->p_filesz - 1] != '\0')
670 ▸ ▸ ▸ ▸ goto out_free_interp;
671
672 ▸ ▸ ▸ interpreter = open_exec(elf_interpreter);
673 ▸ ▸ ▸ retval = PTR_ERR(interpreter);
674 ▸ ▸ ▸ if (IS_ERR(interpreter))
675 ▸ ▸ ▸ ▸ goto out_free_interp;
676
677 ▸ ▸ ▸ /*
678 ▸ ▸ ▸ * If the binary is not readable then enforce
679 ▸ ▸ ▸ * mm->dumpable = 0 regardless of the interpreter's
680 ▸ ▸ ▸ * permissions.
681 ▸ ▸ ▸ */
682 ▸ ▸ ▸ would_dump(bprm, interpreter);
683
684 ▸ ▸ ▸ retval = kernel_read(interpreter, 0, bprm->buf,
685 ▸ ▸ ▸ ▸ ▸ BINPRM_BUF_SIZE);
686 ▸ ▸ ▸ if (retval != BINPRM_BUF_SIZE) {
687 ▸ ▸ ▸ ▸ if (retval >= 0)
688 ▸ ▸ ▸ ▸ ▸ retval = -EIO;
689 ▸ ▸ ▸ ▸ goto out_free_dentry;
690 ▸ ▸ ▸ }
691
692 ▸ ▸ ▸ /* Get the exec headers */
693 ▸ ▸ ▸ loc->interp_elf_ex = *((struct elfhdr *)bprm->buf);
694 ▸ ▸ ▸ break;
695 ▸ ▸ }
696 ▸ ▸ elf_ppnt++;
697 ▸ }
698
699 ▸ elf_ppnt = elf_phdata;
700 ▸ for (i = 0; i < loc->elf_ex.e_phnum; i++, elf_ppnt++)
701 ▸ ▸ if (elf_ppnt->p_type == PT_GNU_STACK) {
702 ▸ ▸ ▸ if (elf_ppnt->p_flags & PF_X)
703 ▸ ▸ ▸ ▸ executable_stack = EXSTACK_ENABLE_X;
704 ▸ ▸ ▸ else
705 ▸ ▸ ▸ ▸ executable_stack = EXSTACK_DISABLE_X;
706 ▸ ▸ ▸ break;
707 ▸ ▸ }
708
709 ▸ /* Some simple consistency checks for the interpreter */
//对动态链接库执行一致性检测
710 ▸ if (elf_interpreter) {
711 ▸ ▸ retval = -ELIBBAD;
712 ▸ ▸ /* Not an ELF interpreter */
713 ▸ ▸ if (memcmp(loc->interp_elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
714 ▸ ▸ ▸ goto out_free_dentry;
715 ▸ ▸ /* Verify the interpreter has a valid arch */
716 ▸ ▸ if (!elf_check_arch(&loc->interp_elf_ex))
717 ▸ ▸ ▸ goto out_free_dentry;
718 ▸ }
719
720 ▸ /* Flush all traces of the currently running executable */
//释放当前运行的可执行文件占用的所有资源
721 ▸ retval = flush_old_exec(bprm);
722 ▸ if (retval)
723 ▸ ▸ goto out_free_dentry;
724
725 ▸ /* OK, This is the point of no return */
726 ▸ current->mm->def_flags = def_flags;
727
728 ▸ /* Do this immediately, since STACK_TOP as used in setup_arg_pages
729 ▸ may depend on the personality. */
730 ▸ SET_PERSONALITY(loc->elf_ex);
731 ▸ if (elf_read_implies_exec(loc->elf_ex, executable_stack))
732 ▸ ▸ current->personality |= READ_IMPLIES_EXEC;
733
734 ▸ if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
735 ▸ ▸ current->flags |= PF_RANDOMIZE;
736
737 ▸ setup_new_exec(bprm);
738
739 ▸ /* Do this so that we can load the interpreter, if need be. We will
740 ▸ change some of these later */
741 ▸ current->mm->free_area_cache = current->mm->mmap_base;
742 ▸ current->mm->cached_hole_size = 0;
//为进程的用户态堆栈分配一个新的线性区描述符,并把那个线性区插入到进程的地址空间。
743 ▸ retval = setup_arg_pages(bprm, randomize_stack_top(STACK_TOP),
744 ▸ ▸ ▸ ▸ executable_stack);
745 ▸ if (retval < 0) {
746 ▸ ▸ send_sig(SIGKILL, current, 0);
747 ▸ ▸ goto out_free_dentry;
748 ▸ }
749 ▸
750 ▸ current->mm->start_stack = bprm->p;
751
752 ▸ /* Now we do a little grungy work by mmapping the ELF image into
753 ▸ the correct location in memory. */
//将ELF镜像文件映射到内存中正确的位置
754 ▸ for(i = 0, elf_ppnt = elf_phdata;
755 ▸ i < loc->elf_ex.e_phnum; i++, elf_ppnt++) {
756 ▸ ▸ int elf_prot = 0, elf_flags;
757 ▸ ▸ unsigned long k, vaddr;
758
759 ▸ ▸ if (elf_ppnt->p_type != PT_LOAD)
760 ▸ ▸ ▸ continue;
761
762 ▸ ▸ if (unlikely (elf_brk > elf_bss)) {
763 ▸ ▸ ▸ unsigned long nbyte;
764 ▸ ▫▫▫▫▫▫▫▫▫▫▫▫
765 ▸ ▸ ▸ /* There was a PT_LOAD segment with p_memsz > p_filesz
766 ▸ ▸ ▸ before this one. Map anonymous pages, if needed,
767 ▸ ▸ ▸ and clear the area. */
768 ▸ ▸ ▸ retval = set_brk(elf_bss + load_bias,
769 ▸ ▸ ▸ ▸ ▸ elf_brk + load_bias);
770 ▸ ▸ ▸ if (retval) {
771 ▸ ▸ ▸ ▸ send_sig(SIGKILL, current, 0);
772 ▸ ▸ ▸ ▸ goto out_free_dentry;
773 ▸ ▸ ▸ }
774 ▸ ▸ ▸ nbyte = ELF_PAGEOFFSET(elf_bss);
775 ▸ ▸ ▸ if (nbyte) {
776 ▸ ▸ ▸ ▸ nbyte = ELF_MIN_ALIGN - nbyte;
777 ▸ ▸ ▸ ▸ if (nbyte > elf_brk - elf_bss)
778 ▸ ▸ ▸ ▸ ▸ nbyte = elf_brk - elf_bss;
779 ▸ ▸ ▸ ▸ if (clear_user((void __user *)elf_bss +
780 ▸ ▸ ▸ ▸ ▸ ▸ ▸ load_bias, nbyte)) {
781 ▸ ▸ ▸ ▸ ▸ /*
782 ▸ ▸ ▸ ▸ ▸ * This bss-zeroing can fail if the ELF
783 ▸ ▸ ▸ ▸ ▸ * file specifies odd protections. So
784 ▸ ▸ ▸ ▸ ▸ * we don't check the return value
785 ▸ ▸ ▸ ▸ ▸ */
786 ▸ ▸ ▸ ▸ }
787 ▸ ▸ ▸ }
788 ▸ ▸ }
789
790 ▸ ▸ if (elf_ppnt->p_flags & PF_R)
791 ▸ ▸ ▸ elf_prot |= PROT_READ;
792 ▸ ▸ if (elf_ppnt->p_flags & PF_W)
793 ▸ ▸ ▸ elf_prot |= PROT_WRITE;
794 ▸ ▸ if (elf_ppnt->p_flags & PF_X)
795 ▸ ▸ ▸ elf_prot |= PROT_EXEC;
796
797 ▸ ▸ elf_flags = MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE;
798
799 ▸ ▸ vaddr = elf_ppnt->p_vaddr;
800 ▸ ▸ if (loc->elf_ex.e_type == ET_EXEC || load_addr_set) {
801 ▸ ▸ ▸ elf_flags |= MAP_FIXED;
802 ▸ ▸ } else if (loc->elf_ex.e_type == ET_DYN) {
803 ▸ ▸ ▸ /* Try and get dynamic programs out of the way of the
804 ▸ ▸ ▸ * default mmap base, as well as whatever program they
805 ▸ ▸ ▸ * might try to exec. This is because the brk will
806 ▸ ▸ ▸ * follow the loader, and is not movable. */
807 #ifdef CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE
808 ▸ ▸ ▸ /* Memory randomization might have been switched off
809 ▸ ▸ ▸ * in runtime via sysctl or explicit setting of
810 ▸ ▸ ▸ * personality flags.
811 ▸ ▸ ▸ * If that is the case, retain the original non-zero
812 ▸ ▸ ▸ * load_bias value in order to establish proper
813 ▸ ▸ ▸ * non-randomized mappings.
814 ▸ ▸ ▸ */
815 ▸ ▸ ▸ if (current->flags & PF_RANDOMIZE)
816 ▸ ▸ ▸ ▸ load_bias = 0;
817 ▸ ▸ ▸ else
818 ▸ ▸ ▸ ▸ load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
819 #else
820 ▸ ▸ ▸ load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
821 #endif
822 ▸ ▸ }
823
824 ▸ ▸ error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
825 ▸ ▸ ▸ ▸ elf_prot, elf_flags, 0);
826 ▸ ▸ if (BAD_ADDR(error)) {
827 ▸ ▸ ▸ send_sig(SIGKILL, current, 0);
828 ▸ ▸ ▸ retval = IS_ERR((void *)error) ?
829 ▸ ▸ ▸ ▸ PTR_ERR((void*)error) : -EINVAL;
830 ▸ ▸ ▸ goto out_free_dentry;
831 ▸ ▸ }
832
833 ▸ ▸ if (!load_addr_set) {
834 ▸ ▸ ▸ load_addr_set = 1;
835 ▸ ▸ ▸ load_addr = (elf_ppnt->p_vaddr - elf_ppnt->p_offset);
836 ▸ ▸ ▸ if (loc->elf_ex.e_type == ET_DYN) {
837 ▸ ▸ ▸ ▸ load_bias += error -
838 ▸ ▸ ▸ ▸ ELF_PAGESTART(load_bias + vaddr);
839 ▸ ▸ ▸ ▸ load_addr += load_bias;
840 ▸ ▸ ▸ ▸ reloc_func_desc = load_bias;
841 ▸ ▸ ▸ }
842 ▸ ▸ }
843 ▸ ▸ k = elf_ppnt->p_vaddr;
844 ▸ ▸ if (k < start_code)
845 ▸ ▸ ▸ start_code = k;
846 ▸ ▸ if (start_data < k)
847 ▸ ▸ ▸ start_data = k;
848
849 ▸ ▸ /*
850 ▸ ▸ * Check to see if the section's size will overflow the
851 ▸ ▸ * allowed task size. Note that p_filesz must always be
852 ▸ ▸ * <= p_memsz so it is only necessary to check p_memsz.
853 ▸ ▸ */
854 ▸ ▸ if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
855 ▸ ▸ elf_ppnt->p_memsz > TASK_SIZE ||
856 ▸ ▸ TASK_SIZE - elf_ppnt->p_memsz < k) {
857 ▸ ▸ ▸ /* set_brk can never work. Avoid overflows. */
858 ▸ ▸ ▸ send_sig(SIGKILL, current, 0);
859 ▸ ▸ ▸ retval = -EINVAL;
860 ▸ ▸ ▸ goto out_free_dentry;
861 ▸ ▸ }
862
863 ▸ ▸ k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
864
865 ▸ ▸ if (k > elf_bss)
866 ▸ ▸ ▸ elf_bss = k;
867 ▸ ▸ if ((elf_ppnt->p_flags & PF_X) && end_code < k)
868 ▸ ▸ ▸ end_code = k;
869 ▸ ▸ if (end_data < k)
870 ▸ ▸ ▸ end_data = k;
871 ▸ ▸ k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
872 ▸ ▸ if (k > elf_brk)
873 ▸ ▸ ▸ elf_brk = k;
874 ▸ }
875
876 ▸ loc->elf_ex.e_entry += load_bias;
877 ▸ elf_bss += load_bias;
878 ▸ elf_brk += load_bias;
879 ▸ start_code += load_bias;
880 ▸ end_code += load_bias;
881 ▸ start_data += load_bias;
882 ▸ end_data += load_bias;
883
884 ▸ /* Calling set_brk effectively mmaps the pages that we need
885 ▸ * for the bss and break sections. We must do this before
886 ▸ * mapping in the interpreter, to make sure it doesn't wind
887 ▸ * up getting placed where the bss needs to go.
888 ▸ */
890 ▸ if (retval) {
891 ▸ ▸ send_sig(SIGKILL, current, 0);
892 ▸ ▸ goto out_free_dentry;
893 ▸ }
894 ▸ if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
895 ▸ ▸ send_sig(SIGSEGV, current, 0);
896 ▸ ▸ retval = -EFAULT; /* Nobody gets to see this, but.. */
897 ▸ ▸ goto out_free_dentry;
898 ▸ }
899 //调用一个动态链接程序的函数,如果动态链接程序是elf可执行的,调用load_elf_interp(动态链接程序)
900 ▸ if (elf_interpreter) {
901 ▸ ▸ unsigned long interp_map_addr = 0;
902
903 ▸ ▸ elf_entry = load_elf_interp(&loc->interp_elf_ex,
904 ▸ ▸ ▸ ▸ ▸ interpreter,
905 ▸ ▸ ▸ ▸ ▸ &interp_map_addr,
906 ▸ ▸ ▸ ▸ ▸ load_bias);
907 ▸ ▸ if (!IS_ERR((void *)elf_entry)) {
908 ▸ ▸ ▸ /*
909 ▸ ▸ ▸ * load_elf_interp() returns relocation
910 ▸ ▸ ▸ * adjustment
911 ▸ ▸ ▸ */
912 ▸ ▸ ▸ interp_load_addr = elf_entry;
913 ▸ ▸ ▸ elf_entry += loc->interp_elf_ex.e_entry;
914 ▸ ▸ }
915 ▸ ▸ if (BAD_ADDR(elf_entry)) {
916 ▸ ▸ ▸ force_sig(SIGSEGV, current);
917 ▸ ▸ ▸ retval = IS_ERR((void *)elf_entry) ?
918 ▸ ▸ ▸ ▸ ▸ (int)elf_entry : -EINVAL;
919 ▸ ▸ ▸ goto out_free_dentry;
920 ▸ ▸ }
921 ▸ ▸ reloc_func_desc = interp_load_addr;
922
923 ▸ ▸ allow_write_access(interpreter);
924 ▸ ▸ fput(interpreter);
925 ▸ ▸ kfree(elf_interpreter);
926 ▸ } else {
927 ▸ ▸ elf_entry = loc->elf_ex.e_entry;
928 ▸ ▸ if (BAD_ADDR(elf_entry)) {
929 ▸ ▸ ▸ force_sig(SIGSEGV, current);
930 ▸ ▸ ▸ retval = -EINVAL;
931 ▸ ▸ ▸ goto out_free_dentry;
932 ▸ ▸ }
933 ▸ }
934
935 ▸ kfree(elf_phdata);
936 //把可执行格式的linux_binfmt对象地址存放在进程描述符binfmt字段中
937 ▸ set_binfmt(&elf_format);
938
939 #ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES
940 ▸ retval = arch_setup_additional_pages(bprm, !!elf_interpreter);
941 ▸ if (retval < 0) {
942 ▸ ▸ send_sig(SIGKILL, current, 0);
943 ▸ ▸ goto out;
944 ▸ }
945 #endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */
946
947 ▸ install_exec_creds(bprm);
948 ▸ retval = create_elf_tables(bprm, &loc->elf_ex,
949 ▸ ▸ ▸ load_addr, interp_load_addr);
950 ▸ if (retval < 0) {
951 ▸ ▸ send_sig(SIGKILL, current, 0);
952 ▸ ▸ goto out;
953 ▸ }
954 ▸ /* N.B. passed_fileno might not be initialized? */
955 ▸ current->mm->end_code = end_code;
956 ▸ current->mm->start_code = start_code;
957 ▸ current->mm->start_data = start_data;
958 ▸ current->mm->end_data = end_data;
959 ▸ current->mm->start_stack = bprm->p;
960
961 #ifdef arch_randomize_brk
962 ▸ if ((current->flags & PF_RANDOMIZE) && (randomize_va_space > 1)) {
963 ▸ ▸ current->mm->brk = current->mm->start_brk =
964 ▸ ▸ ▸ arch_randomize_brk(current->mm);
965 #ifdef CONFIG_COMPAT_BRK
966 ▸ ▸ current->brk_randomized = 1;
967 #endif
968 ▸ }
969 #endif
970
971 ▸ if (current->personality & MMAP_PAGE_ZERO) {
972 ▸ ▸ /* Why this, you ask??? Well SVr4 maps page 0 as read-only,
973 ▸ ▸ and some applications "depend" upon this behavior.
974 ▸ ▸ Since we do not have the power to recompile these, we
975 ▸ ▸ emulate the SVr4 behavior. Sigh. */
976 ▸ ▸ error = vm_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC,
977 ▸ ▸ ▸ ▸ MAP_FIXED | MAP_PRIVATE, 0);
978 ▸ }
979
980 #ifdef ELF_PLAT_INIT
981 ▸ /*
982 ▸ * The ABI may specify that certain registers be set up in special
983 ▸ * ways (on i386 %edx is the address of a DT_FINI function, for
984 ▸ * example. In addition, it may also specify (eg, PowerPC64 ELF)
985 ▸ * that the e_entry field is the address of the function descriptor
986 ▸ * for the startup routine, rather than the address of the startup
987 ▸ * routine itself. This macro performs whatever initialization to
988 ▸ * the regs structure is required as well as any relocations to the
989 ▸ * function descriptor entries when executing dynamically links apps.
990 ▸ */
991 ▸ ELF_PLAT_INIT(regs, reloc_func_desc);
992 #endif
993
994 ▸ start_thread(regs, elf_entry, bprm->p);
995 ▸ retval = 0;
996 out:
997 ▸ kfree(loc);
998 out_ret:
999 ▸ return retval;
1000
1001 ▸ /* error cleanup */
1002 out_free_dentry:
1003 ▸ allow_write_access(interpreter);
1004 ▸ if (interpreter)
1005 ▸ ▸ fput(interpreter);
1006 out_free_interp:
1007 ▸ kfree(elf_interpreter);
1008 out_free_ph:
1009 ▸ kfree(elf_phdata);
1010 ▸ goto out;
1011 }