Function report

Linux Kernel

v5.5.9

Brick Technologies Co., Ltd

Source Code:fs\binfmt_elf.c Create Date:2022-07-28 20:28:24
Last Modify:2020-03-12 14:18:49 Copyright©Brick
home page Tree
Annotation kernel can get tool activityDownload SCCTChinese

Name:load_elf_binary

Proto:static int load_elf_binary(struct linux_binprm *bprm)

Type:int

Parameter:

TypeParameterName
struct linux_binprm *bprm
683  struct file * interpreter = NULL
684  load_addr = 0 , load_bias = 0
685  load_addr_set = 0
687  struct elf64_phdr * elf_ppnt, * elf_phdata, * interp_elf_phdata = NULL
689  bss_prot = 0
692  interp_load_addr = 0
694  reloc_func_desc((__unused__)) = 0
695  executable_stack = Whatever the arch defaults to
696  struct{struct elf64_hdr elf_ex;struct elf64_hdr interp_elf_ex;} * loc
700  arch_state = INIT_ARCH_ELF_STATE
703  loc = Allocation memory
704  If Not loc Then
705  retval = -ENOMEM
706  Go to out_ret
710  elf_ex = *buf
712  retval = -ENOEXEC
714  If memcmp( ELF "magic number" , ELFMAG, SELFMAG) != 0 Then Go to out
717  If e_type != ET_EXEC && e_type != ET_DYN Then Go to out
719  If Not elf_check_arch( & elf_ex) Then Go to out
721  If That's for binfmt_elf_fdpic to deal with ( & elf_ex) Then Go to out
723  If Not mmap Then Go to out
726  elf_phdata = load_elf_phdrs() - load ELF program headers*@elf_ex: ELF header of the binary whose program headers should be loaded*@elf_file: the opened ELF binary file* Loads ELF program headers from the binary file elf_file, which has the ELF
727  If Not elf_phdata Then Go to out
730  elf_ppnt = elf_phdata
731  When i < e_phnum cycle
734  If p_type != PT_INTERP Then Continue
741  retval = -ENOEXEC
742  If Segment size in file > # chars in a path name including nul || Segment size in file < 2 Then Go to out_free_ph
745  retval = -ENOMEM
746  elf_interpreter = Allocation memory
747  If Not elf_interpreter Then Go to out_free_ph
750  retval = elf_read(file, elf_interpreter, Segment size in file , Segment file offset )
752  If retval < 0 Then Go to out_free_interp
755  retval = -ENOEXEC
756  If elf_interpreter[ Segment size in file - 1] != '\0' Then Go to out_free_interp
759  interpreter = open_exec(elf_interpreter)
760  kfree(elf_interpreter)
761  retval = PTR_ERR(interpreter)
762  If IS_ERR(interpreter) Then Go to out_free_ph
769  would_dump(bprm, interpreter)
772  retval = elf_read(interpreter, & interp_elf_ex, size of interp_elf_ex , 0)
774  If retval < 0 Then Go to out_free_dentry
777  Break
779  out_free_interp :
780  kfree(elf_interpreter)
781  Go to out_free_ph
784  elf_ppnt = elf_phdata
785  When i < e_phnum cycle switch p_type
787  Case p_type == PT_GNU_STACK
788  If p_flags & PF_X Then executable_stack = Enable executable stacks
790  Else executable_stack = Disable executable stacks
792  Break
794  Case p_type == PT_LOPROC...PT_HIPROC
795  retval = arch_elf_pt_proc() - check a PT_LOPROC
798  If retval Then Go to out_free_dentry
800  Break
804  If interpreter Then
805  retval = -ELIBBAD
807  If memcmp( ELF "magic number" , ELFMAG, SELFMAG) != 0 Then Go to out_free_dentry
810  If Not elf_check_arch( & interp_elf_ex) || That's for binfmt_elf_fdpic to deal with ( & interp_elf_ex) Then Go to out_free_dentry
815  interp_elf_phdata = load_elf_phdrs() - load ELF program headers*@elf_ex: ELF header of the binary whose program headers should be loaded*@elf_file: the opened ELF binary file* Loads ELF program headers from the binary file elf_file, which has the ELF
817  If Not interp_elf_phdata Then Go to out_free_dentry
821  elf_ppnt = interp_elf_phdata
822  When i < e_phnum cycle switch p_type
824  Case p_type == PT_LOPROC...PT_HIPROC
828  If retval Then Go to out_free_dentry
830  Break
839  retval = arch_check_elf() - check an ELF executable*@ehdr: The main ELF header*@has_interp: True if the ELF has an interpreter, else false.*@interp_ehdr: The interpreter's ELF header*@state: Architecture-specific state preserved throughout the process
842  If retval Then Go to out_free_dentry
846  retval = Calling this is the point of no return. None of the failures will be* seen by userspace since either the process is already taking a fatal* signal (via de_thread() or coredump), or will have SEGV raised
847  If retval Then Go to out_free_dentry
852  SET_PERSONALITY2(elf_ex, & arch_state)
853  If An executable for which elf_read_implies_exec() returns TRUE will* have the READ_IMPLIES_EXEC personality flag set automatically.(elf_ex, executable_stack) Then personality |= READ_IMPLIES_EXEC
856  If Not (personality & ADDR_NO_RANDOMIZE) && Randomize the address space (stacks, mmaps, brk, etc.).* ( When CONFIG_COMPAT_BRK=y we exclude brk from randomization,* as ancient (libc5 based) binaries can segfault. ) Then flags |= Randomize virtual address space
859  setup_new_exec(bprm)
860  stall the new credentials for this executable
864  retval = Finalizes the stack vm_area_struct. The flags and permissions are updated,* the stack is optionally relocated, and some extra space is added.
866  If retval < 0 Then Go to out_free_dentry
869  elf_bss = 0
870  elf_brk = 0
872  start_code = ~0UL
873  end_code = 0
874  start_data = 0
875  end_data = 0
879  When i < e_phnum cycle
883  total_size = 0
885  If p_type != PT_LOAD Then Continue
897  If retval Then Go to out_free_dentry
900  If nbyte Then
915  elf_prot = make_prot(p_flags)
917  elf_flags = Changes are private | ETXTBSY | mark it as an executable
919  vaddr = Segment virtual address
924  If e_type == ET_EXEC || load_addr_set Then
926  Else if e_type == ET_DYN Then
957  If interpreter Then
962  Else load_bias = 0
976  If Not total_size Then
977  retval = -EINVAL
978  Go to out_free_dentry
982  error = elf_map(file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags, total_size)
984  If BAD_ADDR(error) Then
985  retval = If IS_ERR((void * )error) Then PTR_ERR((void * )error) Else -EINVAL
987  Go to out_free_dentry
990  If Not load_addr_set Then
991  load_addr_set = 1
993  If e_type == ET_DYN Then
1000  k = Segment virtual address
1001  If k < start_code Then start_code = k
1003  If start_data < k Then start_data = k
1015  retval = -EINVAL
1016  Go to out_free_dentry
1019  k = Segment virtual address + Segment size in file
1021  If k > elf_bss Then elf_bss = k
1023  If p_flags & PF_X && end_code < k Then end_code = k
1025  If end_data < k Then end_data = k
1027  k = Segment virtual address + Segment size in memory
1028  If k > elf_brk Then
1029  bss_prot = elf_prot
1030  elf_brk = k
1034  Entry point virtual address += load_bias
1035  elf_bss += load_bias
1036  elf_brk += load_bias
1037  start_code += load_bias
1038  end_code += load_bias
1039  start_data += load_bias
1040  end_data += load_bias
1047  retval = set_brk(elf_bss, elf_brk, bss_prot)
1048  If retval Then Go to out_free_dentry
1050  If Value is more likely to compile time(elf_bss != elf_brk) && Value for the false possibility is greater at compile time(We need to explicitly zero any fractional pagesafter the data section (i.e. bss). This wouldcontain the junk from the file that should notbe in memory) Then
1051  retval = -EFAULT
1052  Go to out_free_dentry
1055  If interpreter Then
1056  elf_entry = This is much more generalized than the library routine read function,so we keep this separate. Technically the library read functionis only provided so that we can read a.out libraries that havean ELF header
1059  If Not IS_ERR((void * )elf_entry) Then
1067  If BAD_ADDR(elf_entry) Then
1068  retval = If IS_ERR((void * )elf_entry) Then elf_entry Else -EINVAL
1070  Go to out_free_dentry
1072  reloc_func_desc = interp_load_addr
1074  allow_write_access(interpreter)
1075  fput(interpreter)
1076  Else
1077  elf_entry = Entry point virtual address
1078  If BAD_ADDR(elf_entry) Then
1079  retval = -EINVAL
1080  Go to out_free_dentry
1084  kfree(interp_elf_phdata)
1085  kfree(elf_phdata)
1087  set_binfmt( & elf_format)
1090  retval = arch_setup_additional_pages(bprm, !!interpreter)
1091  If retval < 0 Then Go to out
1095  retval = create_elf_tables(bprm, & elf_ex, load_addr, interp_load_addr)
1097  If retval < 0 Then Go to out
1099  end_code = end_code
1100  start_code = start_code
1101  start_data = start_data
1102  end_data = end_data
1103  start_stack = p
1105  If flags & Randomize virtual address space && Randomize the address space (stacks, mmaps, brk, etc.).* ( When CONFIG_COMPAT_BRK=y we exclude brk from randomization,* as ancient (libc5 based) binaries can segfault. ) > 1 Then
1113  If IS_ENABLED(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y' or 'm',* 0 otherwise.(CONFIG_ARCH_HAS_ELF_RANDOMIZE) && e_type == ET_DYN && Not interpreter Then brk = start_brk = This is the base location for PIE (ET_DYN with INTERP) loads. On* 64-bit, this is above 4GB to leave the entire 32-bit address* space open for things that want to use the area for 32-bit pointers.
1118  brk = start_brk = arch_randomize_brk(mm)
1125  If personality & MMAP_PAGE_ZERO Then
1130  error = vm_mmap(NULL, 0, PAGE_SIZE, page can be read | page can be executed , Interpret addr exactly | Changes are private , 0)
1134  regs = current_pt_regs()
1146  SVR4/i386 ABI (pages 3-31, 3-32) says that when the program starts %edxcontains a pointer to a function which might be registered using `atexit'.This provides a mean for the dynamic linker to call DT_FINI functions for(regs, reloc_func_desc)
1149  Runs immediately before start_thread() takes over.
1150  start_thread(regs, elf_entry, p)
1151  retval = 0
1152  out :
1153  kfree(loc)
1154  out_ret :
1155  Return retval
1158  out_free_dentry :
1159  kfree(interp_elf_phdata)
1160  allow_write_access(interpreter)
1161  If interpreter Then fput(interpreter)
1163  out_free_ph :
1164  kfree(elf_phdata)
1165  Go to out