History

binfmt_elf_fdpic: support 64-bit systems

The binfmt_flat_fdpic code has a number of 32-bit specific data structures associated with it. Extend it to be able to support and be used on 64-bit systems as well. The new code defines a number of key 64-bit variants of the core elf-fdpic data structures - along side the existing 32-bit sized ones. A common set of generic named structures are defined to be either the 32-bit or 64-bit ones as required at compile time. This is a similar technique to that used in the ELF binfmt loader. For example: elf_fdpic_loadseg is either elf32_fdpic_loadseg or elf64_fdpic_loadseg elf_fdpic_loadmap is either elf32_fdpic_loadmap or elf64_fdpic_loadmap the choice based on ELFCLASS32 or ELFCLASS64.

Greg Ungerer committed 3 years ago

Commit b922bf01 parent 06c2afb3 files · +47 −20Browse files

Unified · Split

3 files
  1. fs/binfmt_elf_fdpic.c +19 −19
  2. include/linux/elf-fdpic.h +13 −1
  3. include/uapi/linux/elf-fdpic.h +15 −0
fs/binfmt_elf_fdpic.c+19−19
@@ -138,7 +138,7 @@ static int is_constdisp(struct elfhdr *hdr) · 137 unmodified lines
138static int elf_fdpic_fetch_phdrs(struct elf_fdpic_params *params,138static int elf_fdpic_fetch_phdrs(struct elf_fdpic_params *params,
139 struct file *file)139 struct file *file)
140{140{
141 struct elf32_phdr *phdr;141 struct elf_phdr *phdr;
142 unsigned long size;142 unsigned long size;
143 int retval, loop;143 int retval, loop;
144 loff_t pos = params->hdr.e_phoff;144 loff_t pos = params->hdr.e_phoff;
@@ -560,8 +560,8 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm, · 415 unmodified lines
560 sp &= ~7UL;560 sp &= ~7UL;
561 561
562 /* stack the load map(s) */562 /* stack the load map(s) */
563 len = sizeof(struct elf32_fdpic_loadmap);563 len = sizeof(struct elf_fdpic_loadmap);
564 len += sizeof(struct elf32_fdpic_loadseg) * exec_params->loadmap->nsegs;564 len += sizeof(struct elf_fdpic_loadseg) * exec_params->loadmap->nsegs;
565 sp = (sp - len) & ~7UL;565 sp = (sp - len) & ~7UL;
566 exec_params->map_addr = sp;566 exec_params->map_addr = sp;
567 567
@@ -571,8 +571,8 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm, · 3 unmodified lines
571 current->mm->context.exec_fdpic_loadmap = (unsigned long) sp;571 current->mm->context.exec_fdpic_loadmap = (unsigned long) sp;
572 572
573 if (interp_params->loadmap) {573 if (interp_params->loadmap) {
574 len = sizeof(struct elf32_fdpic_loadmap);574 len = sizeof(struct elf_fdpic_loadmap);
575 len += sizeof(struct elf32_fdpic_loadseg) *575 len += sizeof(struct elf_fdpic_loadseg) *
576 interp_params->loadmap->nsegs;576 interp_params->loadmap->nsegs;
577 sp = (sp - len) & ~7UL;577 sp = (sp - len) & ~7UL;
578 interp_params->map_addr = sp;578 interp_params->map_addr = sp;
@@ -740,13 +740,13 @@ static int elf_fdpic_map_file(struct elf_fdpic_params *params, · 161 unmodified lines
740 struct mm_struct *mm,740 struct mm_struct *mm,
741 const char *what)741 const char *what)
742{742{
743 struct elf32_fdpic_loadmap *loadmap;743 struct elf_fdpic_loadmap *loadmap;
744#ifdef CONFIG_MMU744#ifdef CONFIG_MMU
745 struct elf32_fdpic_loadseg *mseg;745 struct elf_fdpic_loadseg *mseg;
746 unsigned long load_addr;746 unsigned long load_addr;
747#endif747#endif
748 struct elf32_fdpic_loadseg *seg;748 struct elf_fdpic_loadseg *seg;
749 struct elf32_phdr *phdr;749 struct elf_phdr *phdr;
750 unsigned nloads, tmp;750 unsigned nloads, tmp;
751 unsigned long stop;751 unsigned long stop;
752 int loop, ret;752 int loop, ret;
@@ -766,7 +766,7 @@ static int elf_fdpic_map_file(struct elf_fdpic_params *params, · 13 unmodified lines
766 766
767 params->loadmap = loadmap;767 params->loadmap = loadmap;
768 768
769 loadmap->version = ELF32_FDPIC_LOADMAP_VERSION;769 loadmap->version = ELF_FDPIC_LOADMAP_VERSION;
770 loadmap->nsegs = nloads;770 loadmap->nsegs = nloads;
771 771
772 /* map the requested LOADs into the memory space */772 /* map the requested LOADs into the memory space */
@@ -839,8 +839,8 @@ static int elf_fdpic_map_file(struct elf_fdpic_params *params, · 66 unmodified lines
839 if (phdr->p_vaddr >= seg->p_vaddr &&839 if (phdr->p_vaddr >= seg->p_vaddr &&
840 phdr->p_vaddr + phdr->p_memsz <=840 phdr->p_vaddr + phdr->p_memsz <=
841 seg->p_vaddr + seg->p_memsz) {841 seg->p_vaddr + seg->p_memsz) {
842 Elf32_Dyn __user *dyn;842 Elf_Dyn __user *dyn;
843 Elf32_Sword d_tag;843 Elf_Sword d_tag;
844 844
845 params->dynamic_addr =845 params->dynamic_addr =
846 (phdr->p_vaddr - seg->p_vaddr) +846 (phdr->p_vaddr - seg->p_vaddr) +
@@ -850,11 +850,11 @@ static int elf_fdpic_map_file(struct elf_fdpic_params *params, · 3 unmodified lines
850 * one item, and that the last item is a NULL850 * one item, and that the last item is a NULL
851 * entry */851 * entry */
852 if (phdr->p_memsz == 0 ||852 if (phdr->p_memsz == 0 ||
853 phdr->p_memsz % sizeof(Elf32_Dyn) != 0)853 phdr->p_memsz % sizeof(Elf_Dyn) != 0)
854 goto dynamic_error;854 goto dynamic_error;
855 855
856 tmp = phdr->p_memsz / sizeof(Elf32_Dyn);856 tmp = phdr->p_memsz / sizeof(Elf_Dyn);
857 dyn = (Elf32_Dyn __user *)params->dynamic_addr;857 dyn = (Elf_Dyn __user *)params->dynamic_addr;
858 if (get_user(d_tag, &dyn[tmp - 1].d_tag) ||858 if (get_user(d_tag, &dyn[tmp - 1].d_tag) ||
859 d_tag != 0)859 d_tag != 0)
860 goto dynamic_error;860 goto dynamic_error;
@@ -923,8 +923,8 @@ static int elf_fdpic_map_file_constdisp_on_uclinux( · 62 unmodified lines
923 struct file *file,923 struct file *file,
924 struct mm_struct *mm)924 struct mm_struct *mm)
925{925{
926 struct elf32_fdpic_loadseg *seg;926 struct elf_fdpic_loadseg *seg;
927 struct elf32_phdr *phdr;927 struct elf_phdr *phdr;
928 unsigned long load_addr, base = ULONG_MAX, top = 0, maddr = 0;928 unsigned long load_addr, base = ULONG_MAX, top = 0, maddr = 0;
929 int loop, ret;929 int loop, ret;
930 930
@@ -1007,8 +1007,8 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params, · 76 unmodified lines
1007 struct file *file,1007 struct file *file,
1008 struct mm_struct *mm)1008 struct mm_struct *mm)
1009{1009{
1010 struct elf32_fdpic_loadseg *seg;1010 struct elf_fdpic_loadseg *seg;
1011 struct elf32_phdr *phdr;1011 struct elf_phdr *phdr;
1012 unsigned long load_addr, delta_vaddr;1012 unsigned long load_addr, delta_vaddr;
1013 int loop, dvset;1013 int loop, dvset;
1014 1014
include/linux/elf-fdpic.h+13−1
@@ -10,13 +10,25 @@ · 9 unmodified lines
10 10
11#include <uapi/linux/elf-fdpic.h>11#include <uapi/linux/elf-fdpic.h>
12 12
13#if ELF_CLASS == ELFCLASS32
14#define Elf_Sword Elf32_Sword
15#define elf_fdpic_loadseg elf32_fdpic_loadseg
16#define elf_fdpic_loadmap elf32_fdpic_loadmap
17#define ELF_FDPIC_LOADMAP_VERSION ELF32_FDPIC_LOADMAP_VERSION
18#else
19#define Elf_Sword Elf64_Sxword
20#define elf_fdpic_loadmap elf64_fdpic_loadmap
21#define elf_fdpic_loadseg elf64_fdpic_loadseg
22#define ELF_FDPIC_LOADMAP_VERSION ELF64_FDPIC_LOADMAP_VERSION
23#endif
24
13/*25/*
14 * binfmt binary parameters structure26 * binfmt binary parameters structure
15 */27 */
16struct elf_fdpic_params {28struct elf_fdpic_params {
17 struct elfhdr hdr; /* ref copy of ELF header */29 struct elfhdr hdr; /* ref copy of ELF header */
18 struct elf_phdr *phdrs; /* ref copy of PT_PHDR table */30 struct elf_phdr *phdrs; /* ref copy of PT_PHDR table */
19 struct elf32_fdpic_loadmap *loadmap; /* loadmap to be passed to userspace */31 struct elf_fdpic_loadmap *loadmap; /* loadmap to be passed to userspace */
20 unsigned long elfhdr_addr; /* mapped ELF header user address */32 unsigned long elfhdr_addr; /* mapped ELF header user address */
21 unsigned long ph_addr; /* mapped PT_PHDR user address */33 unsigned long ph_addr; /* mapped PT_PHDR user address */
22 unsigned long map_addr; /* mapped loadmap user address */34 unsigned long map_addr; /* mapped loadmap user address */
include/uapi/linux/elf-fdpic.h+15−0
@@ -32,4 +32,19 @@ struct elf32_fdpic_loadmap { · 31 unmodified lines
32 32
33#define ELF32_FDPIC_LOADMAP_VERSION 0x000033#define ELF32_FDPIC_LOADMAP_VERSION 0x0000
34 34
35/* segment mappings for ELF FDPIC libraries/executables/interpreters */
36struct elf64_fdpic_loadseg {
37 Elf64_Addr addr; /* core address to which mapped */
38 Elf64_Addr p_vaddr; /* VMA recorded in file */
39 Elf64_Word p_memsz; /* allocation size recorded in file */
40};
41
42struct elf64_fdpic_loadmap {
43 Elf64_Half version; /* version of these structures, just in case... */
44 Elf64_Half nsegs; /* number of segments */
45 struct elf64_fdpic_loadseg segs[];
46};
47
48#define ELF64_FDPIC_LOADMAP_VERSION 0x0000
49
35#endif /* _UAPI_LINUX_ELF_FDPIC_H */50#endif /* _UAPI_LINUX_ELF_FDPIC_H */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t