13 #include <linux/module.h>
16 #include <linux/stat.h>
17 #include <linux/sched.h>
19 #include <linux/mman.h>
20 #include <linux/errno.h>
21 #include <linux/signal.h>
22 #include <linux/binfmts.h>
23 #include <linux/string.h>
25 #include <linux/fcntl.h>
26 #include <linux/slab.h>
31 #include <linux/personality.h>
32 #include <linux/ptrace.h>
34 #include <linux/elf.h>
35 #include <linux/elf-fdpic.h>
36 #include <linux/elfcore.h>
39 #include <asm/uaccess.h>
40 #include <asm/param.h>
41 #include <asm/pgalloc.h>
46 #define kdebug(fmt, ...) printk("FDPIC "fmt"\n" ,##__VA_ARGS__ )
48 #define kdebug(fmt, ...) do {} while(0)
52 #define kdcore(fmt, ...) printk("FDPIC "fmt"\n" ,##__VA_ARGS__ )
54 #define kdcore(fmt, ...) do {} while(0)
69 static int elf_fdpic_transfer_args_to_stack(
struct linux_binprm *,
71 static int elf_fdpic_map_file_constdisp_on_uclinux(
struct elf_fdpic_params *,
79 #ifdef CONFIG_ELF_CORE
85 .load_binary = load_elf_fdpic_binary,
86 #ifdef CONFIG_ELF_CORE
87 .core_dump = elf_fdpic_core_dump,
92 static int __init init_elf_fdpic_binfmt(
void)
94 register_binfmt(&elf_fdpic_format);
98 static void __exit exit_elf_fdpic_binfmt(
void)
114 if (!file->
f_op || !file->
f_op->mmap)
130 if (params->
hdr.e_phentsize !=
sizeof(
struct elf_phdr))
132 if (params->
hdr.e_phnum > 65536
U /
sizeof(
struct elf_phdr))
135 size = params->
hdr.e_phnum *
sizeof(
struct elf_phdr);
141 (
char *) params->
phdrs, size);
143 return retval < 0 ? retval : -
ENOEXEC;
146 phdr = params->
phdrs;
147 for (loop = 0; loop < params->
hdr.e_phnum; loop++, phdr++) {
167 static int load_elf_fdpic_binary(
struct linux_binprm *bprm,
172 unsigned long stack_size, entryaddr;
173 #ifdef ELF_FDPIC_PLAT_INIT
174 unsigned long dynaddr;
177 unsigned long stack_prot;
179 struct file *interpreter =
NULL;
180 char *interpreter_name =
NULL;
181 int executable_stack;
186 memset(&exec_params, 0,
sizeof(exec_params));
187 memset(&interp_params, 0,
sizeof(interp_params));
189 exec_params.hdr = *(
struct elfhdr *) bprm->
buf;
194 if (!is_elf_fdpic(&exec_params.hdr, bprm->
file))
198 retval = elf_fdpic_fetch_phdrs(&exec_params, bprm->
file);
203 phdr = exec_params.phdrs;
205 for (i = 0; i < exec_params.hdr.e_phnum; i++, phdr++) {
206 switch (phdr->p_type) {
212 if (phdr->p_filesz < 2)
217 if (!interpreter_name)
224 if (
unlikely(retval != phdr->p_filesz)) {
231 if (interpreter_name[phdr->p_filesz - 1] !=
'\0')
234 kdebug(
"Using ELF interpreter %s", interpreter_name);
237 interpreter =
open_exec(interpreter_name);
238 retval = PTR_ERR(interpreter);
239 if (IS_ERR(interpreter)) {
259 interp_params.hdr = *((
struct elfhdr *) bprm->
buf);
264 if (exec_params.load_addr == 0)
265 exec_params.load_addr = phdr->p_vaddr;
276 if (interpreter_name) {
278 if (!is_elf_fdpic(&interp_params.hdr, interpreter))
284 retval = elf_fdpic_fetch_phdrs(&interp_params, interpreter);
289 stack_size = exec_params.stack_size;
297 if (stack_size == 0) {
298 stack_size = interp_params.stack_size;
335 current->mm->context.exec_fdpic_loadmap = 0;
336 current->mm->context.interp_fdpic_loadmap = 0;
339 elf_fdpic_arch_lay_out_mm(&exec_params,
353 retval = elf_fdpic_map_file(&exec_params, bprm->
file,
current->mm,
358 if (interpreter_name) {
359 retval = elf_fdpic_map_file(&interp_params, interpreter,
366 allow_write_access(interpreter);
398 retval =
current->mm->start_brk;
405 current->mm->context.end_brk +=
411 if (create_elf_fdpic_tables(bprm,
current->mm,
412 &exec_params, &interp_params) < 0)
423 #ifdef ELF_FDPIC_PLAT_INIT
430 dynaddr = interp_params.dynamic_addr ?: exec_params.dynamic_addr;
436 entryaddr = interp_params.entry_addr ?: exec_params.entry_addr;
443 allow_write_access(interpreter);
446 kfree(interpreter_name);
447 kfree(exec_params.phdrs);
448 kfree(exec_params.loadmap);
449 kfree(interp_params.phdrs);
450 kfree(interp_params.loadmap);
462 #ifndef ELF_BASE_PLATFORM
468 #define ELF_BASE_PLATFORM NULL
475 static int create_elf_fdpic_tables(
struct linux_binprm *bprm,
481 unsigned long sp,
csp, nitems;
483 size_t platform_len = 0,
len;
484 char *k_platform, *k_base_platform;
485 char __user *u_platform, *u_base_platform, *
p;
501 if (elf_fdpic_transfer_args_to_stack(bprm, &sp) < 0)
517 platform_len =
strlen(k_platform) + 1;
519 u_platform = (
char __user *) sp;
529 u_base_platform =
NULL;
531 if (k_base_platform) {
532 platform_len =
strlen(k_base_platform) + 1;
534 u_base_platform = (
char __user *) sp;
535 if (
__copy_to_user(u_base_platform, k_base_platform, platform_len) != 0)
544 sp = (sp -
len) & ~7
UL;
550 current->mm->context.exec_fdpic_loadmap = (
unsigned long) sp;
556 sp = (sp -
len) & ~7
UL;
563 current->mm->context.interp_fdpic_loadmap = (
unsigned long) sp;
567 #define DLINFO_ITEMS 15
576 sp -= nitems * 2 *
sizeof(
unsigned long);
577 sp -= (bprm->
envc + 1) *
sizeof(
char *);
578 sp -= (bprm->
argc + 1) *
sizeof(
char *);
579 sp -= 1 *
sizeof(
unsigned long);
585 #define NEW_AUX_ENT(id, val) \
587 struct { unsigned long _id, _val; } __user *ent; \
589 ent = (void __user *) csp; \
590 __put_user((id), &ent[nr]._id); \
591 __put_user((val), &ent[nr]._val); \
596 csp -= 2 *
sizeof(
unsigned long);
600 csp -= 2 *
sizeof(
unsigned long);
605 if (k_base_platform) {
607 csp -= 2 *
sizeof(
unsigned long);
609 (
elf_addr_t) (
unsigned long) u_base_platform);
614 csp -= 2 *
sizeof(
unsigned long);
654 csp -=
sizeof(
unsigned long);
668 for (loop = bprm->
argc; loop > 0; loop--) {
680 for (loop = bprm->
envc; loop > 0; loop--) {
700 static int elf_fdpic_transfer_args_to_stack(
struct linux_binprm *bprm,
749 unsigned long load_addr,
stop;
750 unsigned nloads,
tmp;
756 for (loop = 0; loop < params->
hdr.e_phnum; loop++)
763 size =
sizeof(*loadmap) + nloads *
sizeof(*seg);
771 loadmap->
nsegs = nloads;
781 ret = elf_fdpic_map_file_constdisp_on_uclinux(params, file, mm);
787 ret = elf_fdpic_map_file_by_direct_mmap(params, file, mm);
794 if (params->
hdr.e_entry) {
796 for (loop = loadmap->
nsegs; loop > 0; loop--, seg++) {
797 if (params->
hdr.e_entry >= seg->p_vaddr &&
798 params->
hdr.e_entry < seg->p_vaddr + seg->p_memsz) {
800 (params->
hdr.e_entry - seg->p_vaddr) +
808 stop = params->
hdr.e_phoff;
809 stop += params->
hdr.e_phnum *
sizeof (
struct elf_phdr);
810 phdr = params->
phdrs;
812 for (loop = 0; loop < params->
hdr.e_phnum; loop++, phdr++) {
821 for (loop = loadmap->
nsegs; loop > 0; loop--, seg++) {
822 if (phdr->
p_vaddr >= seg->p_vaddr &&
824 seg->p_vaddr + seg->p_memsz) {
826 (phdr->
p_vaddr - seg->p_vaddr) +
836 phdr = params->
phdrs;
837 for (loop = 0; loop < params->
hdr.e_phnum; loop++, phdr++) {
842 for (loop = loadmap->
nsegs; loop > 0; loop--, seg++) {
843 if (phdr->
p_vaddr >= seg->p_vaddr &&
845 seg->p_vaddr + seg->p_memsz) {
847 (phdr->
p_vaddr - seg->p_vaddr) +
872 nloads = loadmap->
nsegs;
873 mseg = loadmap->
segs;
875 for (loop = 1; loop < nloads; loop++) {
877 if (seg->p_vaddr - mseg->
p_vaddr == seg->addr - mseg->
addr) {
879 if (load_addr == (seg->addr &
PAGE_MASK)) {
896 kdebug(
"Mapped Object [%s]:", what);
902 for (loop = 0; loop < loadmap->
nsegs; loop++, seg++)
903 kdebug(
"- LOAD[%d] : %08x-%08x [va=%x ms=%x]",
905 seg->addr, seg->addr + seg->p_memsz - 1,
906 seg->p_vaddr, seg->p_memsz);
911 printk(
"ELF FDPIC %s with invalid DYNAMIC section (inode=%lu)\n",
912 what, file->
f_path.dentry->d_inode->i_ino);
921 static int elf_fdpic_map_file_constdisp_on_uclinux(
937 phdr = params->
phdrs;
938 for (loop = 0; loop < params->
hdr.e_phnum; loop++, phdr++) {
962 phdr = params->
phdrs;
963 for (loop = 0; loop < params->
hdr.e_phnum; loop++, phdr++) {
973 ret = file->
f_op->read(file, (
void *) seg->
addr,
1013 static int elf_fdpic_map_file_by_direct_mmap(
struct elf_fdpic_params *params,
1019 unsigned long load_addr, delta_vaddr;
1029 phdr = params->
phdrs;
1030 for (loop = 0; loop < params->
hdr.e_phnum; loop++, phdr++) {
1031 unsigned long maddr, disp, excess, excess1;
1032 int prot = 0,
flags;
1037 kdebug(
"[LOAD] va=%lx of=%lx fs=%lx ms=%lx",
1038 (
unsigned long) phdr->
p_vaddr,
1041 (
unsigned long) phdr->
p_memsz);
1075 maddr = load_addr + phdr->
p_vaddr - delta_vaddr;
1095 kdebug(
"mmap[%d] <file> sz=%lx pr=%x fl=%x of=%lx --> %08lx",
1106 seg->
addr = maddr + disp;
1117 kdebug(
"clear[%d] ad=%lx sz=%lx", loop, maddr, disp);
1132 if (excess > excess1) {
1133 unsigned long xaddr = maddr + phdr->
p_filesz + excess1;
1141 " ad=%lx sz=%lx pr=%x fl=%x of=0 --> %08lx",
1142 loop, xaddr, excess - excess1, prot,
flags,
1145 if (xmaddr != xaddr)
1150 kdebug(
"clear[%d] ad=%lx sz=%lx",
1151 loop, maddr + phdr->
p_filesz, excess1);
1159 kdebug(
"clear[%d] ad=%lx sz=%lx",
1160 loop, maddr + phdr->
p_filesz, excess);
1193 #ifdef CONFIG_ELF_CORE
1202 static int maydump(
struct vm_area_struct *vma,
unsigned long mm_flags)
1222 if (vma->
vm_file->f_path.dentry->d_inode->i_nlink == 0) {
1225 vma->
vm_flags, dump_ok ?
"yes" :
"no");
1231 vma->
vm_flags, dump_ok ?
"yes" :
"no");
1240 vma->
vm_flags, dump_ok ?
"yes" :
"no");
1247 dump_ok ?
"yes" :
"no");
1273 #define DUMP_WRITE(addr, nr, foffset) \
1274 do { if (!dump_write(file, (addr), (nr))) return 0; *foffset += (nr); } while(0)
1276 static int alignfile(
struct file *file, loff_t *foffset)
1278 static const char buf[4] = { 0, };
1283 static int writenote(
struct memelfnote *men,
struct file *file,
1288 en.n_descsz = men->
datasz;
1289 en.n_type = men->
type;
1293 if (!alignfile(file, foffset))
1296 if (!alignfile(file, foffset))
1303 static inline void fill_elf_fdpic_header(
struct elfhdr *elf,
int segs)
1316 elf->e_phoff =
sizeof(
struct elfhdr);
1319 elf->e_ehsize =
sizeof(
struct elfhdr);
1320 elf->e_phentsize =
sizeof(
struct elf_phdr);
1321 elf->e_phnum = segs;
1322 elf->e_shentsize = 0;
1324 elf->e_shstrndx = 0;
1328 static inline void fill_elf_note_phdr(
struct elf_phdr *phdr,
int sz, loff_t
offset)
1334 phdr->p_filesz = sz;
1342 unsigned int sz,
void *
data)
1355 static void fill_prstatus(
struct elf_prstatus *prstatus,
1364 prstatus->
pr_pid = task_pid_vnr(p);
1365 prstatus->
pr_pgrp = task_pgrp_vnr(p);
1366 prstatus->
pr_sid = task_session_vnr(p);
1367 if (thread_group_leader(p)) {
1384 prstatus->pr_exec_fdpic_loadmap = p->
mm->context.exec_fdpic_loadmap;
1385 prstatus->pr_interp_fdpic_loadmap = p->
mm->context.interp_fdpic_loadmap;
1392 unsigned int i,
len;
1401 (
const char __user *) mm->
arg_start, len))
1403 for (i = 0; i < len; i++)
1411 psinfo->
pr_pid = task_pid_vnr(p);
1412 psinfo->
pr_pgrp = task_pgrp_vnr(p);
1413 psinfo->
pr_sid = task_session_vnr(p);
1417 psinfo->
pr_sname = (i > 5) ?
'.' :
"RSDTZW"[i];
1432 struct elf_thread_status
1438 #ifdef ELF_CORE_COPY_XFPREGS
1450 static int elf_dump_thread_status(
long signr,
struct elf_thread_status *
t)
1457 fill_prstatus(&t->prstatus, p, signr);
1458 elf_core_copy_task_regs(p, &t->prstatus.pr_reg);
1460 fill_note(&t->notes[0],
"CORE",
NT_PRSTATUS,
sizeof(t->prstatus),
1463 sz += notesize(&t->notes[0]);
1465 t->prstatus.pr_fpvalid = elf_core_copy_task_fpregs(p,
NULL, &t->fpu);
1466 if (t->prstatus.pr_fpvalid) {
1467 fill_note(&t->notes[1],
"CORE",
NT_PRFPREG,
sizeof(t->fpu),
1470 sz += notesize(&t->notes[1]);
1473 #ifdef ELF_CORE_COPY_XFPREGS
1474 if (elf_core_copy_task_xfpregs(p, &t->xfpu)) {
1475 fill_note(&t->notes[2],
"LINUX", ELF_CORE_XFPREG_TYPE,
1476 sizeof(t->xfpu), &t->xfpu);
1478 sz += notesize(&t->notes[2]);
1484 static void fill_extnum_info(
struct elfhdr *elf,
struct elf_shdr *shdr4extnum,
1487 elf->e_shoff = e_shoff;
1488 elf->e_shentsize =
sizeof(*shdr4extnum);
1492 memset(shdr4extnum, 0,
sizeof(*shdr4extnum));
1495 shdr4extnum->sh_size = elf->e_shnum;
1496 shdr4extnum->sh_link = elf->e_shstrndx;
1497 shdr4extnum->sh_info = segs;
1504 static int elf_fdpic_dump_segments(
struct file *file,
size_t *size,
1505 unsigned long *
limit,
unsigned long mm_flags)
1513 if (!maydump(vma, mm_flags))
1518 struct page *
page = get_dump_page(addr);
1520 void *kaddr =
kmap(page);
1543 static int elf_fdpic_dump_segments(
struct file *file,
size_t *size,
1544 unsigned long *limit,
unsigned long mm_flags)
1549 if (!maydump(vma, mm_flags))
1564 static size_t elf_core_vma_data_size(
unsigned long mm_flags)
1570 if (maydump(vma, mm_flags))
1592 loff_t
offset = 0, dataoff, foffset;
1600 #ifdef ELF_CORE_COPY_XFPREGS
1603 int thread_status_size = 0;
1626 prstatus = kzalloc(
sizeof(*prstatus),
GFP_KERNEL);
1638 #ifdef ELF_CORE_COPY_XFPREGS
1646 struct elf_thread_status *
tmp;
1648 for (ct =
current->mm->core_state->dumper.next;
1649 ct; ct = ct->
next) {
1654 tmp->thread = ct->
task;
1655 list_add(&tmp->list, &thread_list);
1659 struct elf_thread_status *
tmp;
1664 thread_status_size += sz;
1670 elf_core_copy_regs(&prstatus->
pr_reg, cprm->
regs);
1672 segs =
current->mm->map_count;
1684 fill_elf_fdpic_header(elf, e_phnum);
1694 fill_note(notes + 0,
"CORE",
NT_PRSTATUS,
sizeof(*prstatus), prstatus);
1696 fill_note(notes + 1,
"CORE",
NT_PRPSINFO,
sizeof(*psinfo), psinfo);
1705 while (auxv[i - 2] !=
AT_NULL);
1706 fill_note(¬es[numnote++],
"CORE",
NT_AUXV,
1711 elf_core_copy_task_fpregs(
current, cprm->
regs, fpu)))
1712 fill_note(notes + numnote++,
1714 #ifdef ELF_CORE_COPY_XFPREGS
1715 if (elf_core_copy_task_xfpregs(
current, xfpu))
1716 fill_note(notes + numnote++,
1717 "LINUX", ELF_CORE_XFPREG_TYPE,
sizeof(*xfpu), xfpu);
1723 offset +=
sizeof(*elf);
1724 offset += segs *
sizeof(
struct elf_phdr);
1731 for (i = 0; i < numnote; i++)
1732 sz += notesize(notes + i);
1734 sz += thread_status_size;
1740 fill_elf_note_phdr(phdr4note, sz, offset);
1747 offset += elf_core_vma_data_size(cprm->
mm_flags);
1755 fill_extnum_info(elf, shdr4extnum, e_shoff, segs);
1760 size +=
sizeof(*elf);
1764 size +=
sizeof(*phdr4note);
1765 if (size > cprm->
limit
1790 size +=
sizeof(phdr);
1791 if (size > cprm->
limit
1800 for (i = 0; i < numnote; i++)
1801 if (!writenote(notes + i, cprm->
file, &foffset))
1806 struct elf_thread_status *tmp =
1809 for (i = 0; i < tmp->num_notes; i++)
1810 if (!writenote(&tmp->notes[i], cprm->
file, &foffset))
1817 if (elf_fdpic_dump_segments(cprm->
file, &size, &cprm->
limit,
1825 size +=
sizeof(*shdr4extnum);
1826 if (size > cprm->
limit
1828 sizeof(*shdr4extnum)))
1832 if (cprm->
file->f_pos != offset) {
1835 "elf_core_dump: file->f_pos (%lld) != offset (%lld)\n",
1836 cprm->
file->f_pos, offset);
1843 while (!list_empty(&thread_list)) {
1844 struct list_head *tmp = thread_list.next;
1855 #ifdef ELF_CORE_COPY_XFPREGS