1

I recently read that the kernel and the dynamic loader mostly deal with the program header tables in an ELF file and that assemblers, compilers and linkers deal with the section header tables.

The number of program header tables and section header tables are mentioned in the ELF header in fields named e_phnum and e_shnum respectively. e_phnum is two bytes in size, so if the number of program headers is > 65535, we use a scheme known as extended numbering where, e_phnum is set to 0xffff and sh_link field of the zeroth section header table holds the actual count.

My doubt is :

If the count of program headers exceeds 65535, does that mean the kernel and/or the dynamic loader end up having to read the section table ?

2

I've just checked the linux kernel loading ELF function (loading_elf_binary) and I find out that if e_phnum > (65536U / sizeof(struct elf_phdr)) or e_phnum < 1, the current loading routine will stop (line 613-615), the ELF file won't be loaded:

610         /* Now read in all of the header information */
611         if (loc->elf_ex.e_phentsize != sizeof(struct elf_phdr))
612                 goto out;
613         if (loc->elf_ex.e_phnum < 1 ||
614                 loc->elf_ex.e_phnum > 65536U / sizeof(struct elf_phdr))
615                 goto out;
616         size = loc->elf_ex.e_phnum * sizeof(struct elf_phdr);
617         retval = -ENOMEM;
618         elf_phdata = kmalloc(size, GFP_KERNEL);
619         if (!elf_phdata)
620                 goto out;

Reference: http://lxr.free-electrons.com/source/fs/binfmt_elf.c

Also the number of programheader (e_phnum) in ELF32/64 is always 16 bit variable

203 typedef struct elf32_hdr{
204   unsigned char e_ident[EI_NIDENT];
205   Elf32_Half    e_type;
206   Elf32_Half    e_machine;
207   Elf32_Word    e_version;
208   Elf32_Addr    e_entry;  /* Entry point */
209   Elf32_Off     e_phoff;
210   Elf32_Off     e_shoff;
211   Elf32_Word    e_flags;
212   Elf32_Half    e_ehsize;
213   Elf32_Half    e_phentsize;
214   Elf32_Half    e_phnum;
215   Elf32_Half    e_shentsize;
216   Elf32_Half    e_shnum;
217   Elf32_Half    e_shstrndx;
218 } Elf32_Ehdr;
219 
220 typedef struct elf64_hdr {
221   unsigned char e_ident[EI_NIDENT];     /* ELF "magic number" */
222   Elf64_Half e_type;
223   Elf64_Half e_machine;
224   Elf64_Word e_version;
225   Elf64_Addr e_entry;           /* Entry point virtual address */
226   Elf64_Off e_phoff;            /* Program header table file offset */
227   Elf64_Off e_shoff;            /* Section header table file offset */
228   Elf64_Word e_flags;
229   Elf64_Half e_ehsize;
230   Elf64_Half e_phentsize;
231   Elf64_Half e_phnum;
232   Elf64_Half e_shentsize;
233   Elf64_Half e_shnum;
234   Elf64_Half e_shstrndx;
235 } Elf64_Ehdr;

Define data type as followed:

9 typedef __u16   Elf32_Half;
16 typedef __u16   Elf64_Half;

Reference: http://lxr.free-electrons.com/source/include/uapi/linux/elf.h#L263

So, also in the case of a invalid value of e_phnum (invalid ELF file), the maximum value of e_phnum is 65535.

Hope this helpful!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy