aboutsummaryrefslogtreecommitdiffstats
path: root/fs/binfmt_elf.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/binfmt_elf.c')
-rw-r--r--fs/binfmt_elf.c106
1 files changed, 61 insertions, 45 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index d48ff5f370f4..655ed8d30a86 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -131,6 +131,15 @@ static int padzero(unsigned long elf_bss)
131#define STACK_ALLOC(sp, len) ({ sp -= len ; sp; }) 131#define STACK_ALLOC(sp, len) ({ sp -= len ; sp; })
132#endif 132#endif
133 133
134#ifndef ELF_BASE_PLATFORM
135/*
136 * AT_BASE_PLATFORM indicates the "real" hardware/microarchitecture.
137 * If the arch defines ELF_BASE_PLATFORM (in asm/elf.h), the value
138 * will be copied to the user stack in the same manner as AT_PLATFORM.
139 */
140#define ELF_BASE_PLATFORM NULL
141#endif
142
134static int 143static int
135create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, 144create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
136 unsigned long load_addr, unsigned long interp_load_addr) 145 unsigned long load_addr, unsigned long interp_load_addr)
@@ -142,7 +151,9 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
142 elf_addr_t __user *envp; 151 elf_addr_t __user *envp;
143 elf_addr_t __user *sp; 152 elf_addr_t __user *sp;
144 elf_addr_t __user *u_platform; 153 elf_addr_t __user *u_platform;
154 elf_addr_t __user *u_base_platform;
145 const char *k_platform = ELF_PLATFORM; 155 const char *k_platform = ELF_PLATFORM;
156 const char *k_base_platform = ELF_BASE_PLATFORM;
146 int items; 157 int items;
147 elf_addr_t *elf_info; 158 elf_addr_t *elf_info;
148 int ei_index = 0; 159 int ei_index = 0;
@@ -172,6 +183,19 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
172 return -EFAULT; 183 return -EFAULT;
173 } 184 }
174 185
186 /*
187 * If this architecture has a "base" platform capability
188 * string, copy it to userspace.
189 */
190 u_base_platform = NULL;
191 if (k_base_platform) {
192 size_t len = strlen(k_base_platform) + 1;
193
194 u_base_platform = (elf_addr_t __user *)STACK_ALLOC(p, len);
195 if (__copy_to_user(u_base_platform, k_base_platform, len))
196 return -EFAULT;
197 }
198
175 /* Create the ELF interpreter info */ 199 /* Create the ELF interpreter info */
176 elf_info = (elf_addr_t *)current->mm->saved_auxv; 200 elf_info = (elf_addr_t *)current->mm->saved_auxv;
177 /* update AT_VECTOR_SIZE_BASE if the number of NEW_AUX_ENT() changes */ 201 /* update AT_VECTOR_SIZE_BASE if the number of NEW_AUX_ENT() changes */
@@ -204,10 +228,15 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
204 NEW_AUX_ENT(AT_GID, tsk->gid); 228 NEW_AUX_ENT(AT_GID, tsk->gid);
205 NEW_AUX_ENT(AT_EGID, tsk->egid); 229 NEW_AUX_ENT(AT_EGID, tsk->egid);
206 NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm)); 230 NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm));
231 NEW_AUX_ENT(AT_EXECFN, bprm->exec);
207 if (k_platform) { 232 if (k_platform) {
208 NEW_AUX_ENT(AT_PLATFORM, 233 NEW_AUX_ENT(AT_PLATFORM,
209 (elf_addr_t)(unsigned long)u_platform); 234 (elf_addr_t)(unsigned long)u_platform);
210 } 235 }
236 if (k_base_platform) {
237 NEW_AUX_ENT(AT_BASE_PLATFORM,
238 (elf_addr_t)(unsigned long)u_base_platform);
239 }
211 if (bprm->interp_flags & BINPRM_FLAGS_EXECFD) { 240 if (bprm->interp_flags & BINPRM_FLAGS_EXECFD) {
212 NEW_AUX_ENT(AT_EXECFD, bprm->interp_data); 241 NEW_AUX_ENT(AT_EXECFD, bprm->interp_data);
213 } 242 }
@@ -974,12 +1003,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
974#endif 1003#endif
975 1004
976 start_thread(regs, elf_entry, bprm->p); 1005 start_thread(regs, elf_entry, bprm->p);
977 if (unlikely(current->ptrace & PT_PTRACED)) {
978 if (current->ptrace & PT_TRACE_EXEC)
979 ptrace_notify ((PTRACE_EVENT_EXEC << 8) | SIGTRAP);
980 else
981 send_sig(SIGTRAP, current, 0);
982 }
983 retval = 0; 1006 retval = 0;
984out: 1007out:
985 kfree(loc); 1008 kfree(loc);
@@ -1477,7 +1500,7 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
1477 const struct user_regset_view *view = task_user_regset_view(dump_task); 1500 const struct user_regset_view *view = task_user_regset_view(dump_task);
1478 struct elf_thread_core_info *t; 1501 struct elf_thread_core_info *t;
1479 struct elf_prpsinfo *psinfo; 1502 struct elf_prpsinfo *psinfo;
1480 struct task_struct *g, *p; 1503 struct core_thread *ct;
1481 unsigned int i; 1504 unsigned int i;
1482 1505
1483 info->size = 0; 1506 info->size = 0;
@@ -1516,31 +1539,26 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
1516 /* 1539 /*
1517 * Allocate a structure for each thread. 1540 * Allocate a structure for each thread.
1518 */ 1541 */
1519 rcu_read_lock(); 1542 for (ct = &dump_task->mm->core_state->dumper; ct; ct = ct->next) {
1520 do_each_thread(g, p) 1543 t = kzalloc(offsetof(struct elf_thread_core_info,
1521 if (p->mm == dump_task->mm) { 1544 notes[info->thread_notes]),
1522 t = kzalloc(offsetof(struct elf_thread_core_info, 1545 GFP_KERNEL);
1523 notes[info->thread_notes]), 1546 if (unlikely(!t))
1524 GFP_ATOMIC); 1547 return 0;
1525 if (unlikely(!t)) { 1548
1526 rcu_read_unlock(); 1549 t->task = ct->task;
1527 return 0; 1550 if (ct->task == dump_task || !info->thread) {
1528 } 1551 t->next = info->thread;
1529 t->task = p; 1552 info->thread = t;
1530 if (p == dump_task || !info->thread) { 1553 } else {
1531 t->next = info->thread; 1554 /*
1532 info->thread = t; 1555 * Make sure to keep the original task at
1533 } else { 1556 * the head of the list.
1534 /* 1557 */
1535 * Make sure to keep the original task at 1558 t->next = info->thread->next;
1536 * the head of the list. 1559 info->thread->next = t;
1537 */
1538 t->next = info->thread->next;
1539 info->thread->next = t;
1540 }
1541 } 1560 }
1542 while_each_thread(g, p); 1561 }
1543 rcu_read_unlock();
1544 1562
1545 /* 1563 /*
1546 * Now fill in each thread's information. 1564 * Now fill in each thread's information.
@@ -1687,7 +1705,6 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
1687{ 1705{
1688#define NUM_NOTES 6 1706#define NUM_NOTES 6
1689 struct list_head *t; 1707 struct list_head *t;
1690 struct task_struct *g, *p;
1691 1708
1692 info->notes = NULL; 1709 info->notes = NULL;
1693 info->prstatus = NULL; 1710 info->prstatus = NULL;
@@ -1719,20 +1736,19 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
1719 1736
1720 info->thread_status_size = 0; 1737 info->thread_status_size = 0;
1721 if (signr) { 1738 if (signr) {
1739 struct core_thread *ct;
1722 struct elf_thread_status *ets; 1740 struct elf_thread_status *ets;
1723 rcu_read_lock(); 1741
1724 do_each_thread(g, p) 1742 for (ct = current->mm->core_state->dumper.next;
1725 if (current->mm == p->mm && current != p) { 1743 ct; ct = ct->next) {
1726 ets = kzalloc(sizeof(*ets), GFP_ATOMIC); 1744 ets = kzalloc(sizeof(*ets), GFP_KERNEL);
1727 if (!ets) { 1745 if (!ets)
1728 rcu_read_unlock(); 1746 return 0;
1729 return 0; 1747
1730 } 1748 ets->thread = ct->task;
1731 ets->thread = p; 1749 list_add(&ets->list, &info->thread_list);
1732 list_add(&ets->list, &info->thread_list); 1750 }
1733 } 1751
1734 while_each_thread(g, p);
1735 rcu_read_unlock();
1736 list_for_each(t, &info->thread_list) { 1752 list_for_each(t, &info->thread_list) {
1737 int sz; 1753 int sz;
1738 1754