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.c99
1 files changed, 60 insertions, 39 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 639d2d8b5710..3b6ff854d983 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 */
@@ -209,6 +233,10 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
209 NEW_AUX_ENT(AT_PLATFORM, 233 NEW_AUX_ENT(AT_PLATFORM,
210 (elf_addr_t)(unsigned long)u_platform); 234 (elf_addr_t)(unsigned long)u_platform);
211 } 235 }
236 if (k_base_platform) {
237 NEW_AUX_ENT(AT_BASE_PLATFORM,
238 (elf_addr_t)(unsigned long)u_base_platform);
239 }
212 if (bprm->interp_flags & BINPRM_FLAGS_EXECFD) { 240 if (bprm->interp_flags & BINPRM_FLAGS_EXECFD) {
213 NEW_AUX_ENT(AT_EXECFD, bprm->interp_data); 241 NEW_AUX_ENT(AT_EXECFD, bprm->interp_data);
214 } 242 }
@@ -1478,7 +1506,7 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
1478 const struct user_regset_view *view = task_user_regset_view(dump_task); 1506 const struct user_regset_view *view = task_user_regset_view(dump_task);
1479 struct elf_thread_core_info *t; 1507 struct elf_thread_core_info *t;
1480 struct elf_prpsinfo *psinfo; 1508 struct elf_prpsinfo *psinfo;
1481 struct task_struct *g, *p; 1509 struct core_thread *ct;
1482 unsigned int i; 1510 unsigned int i;
1483 1511
1484 info->size = 0; 1512 info->size = 0;
@@ -1517,31 +1545,26 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
1517 /* 1545 /*
1518 * Allocate a structure for each thread. 1546 * Allocate a structure for each thread.
1519 */ 1547 */
1520 rcu_read_lock(); 1548 for (ct = &dump_task->mm->core_state->dumper; ct; ct = ct->next) {
1521 do_each_thread(g, p) 1549 t = kzalloc(offsetof(struct elf_thread_core_info,
1522 if (p->mm == dump_task->mm) { 1550 notes[info->thread_notes]),
1523 t = kzalloc(offsetof(struct elf_thread_core_info, 1551 GFP_KERNEL);
1524 notes[info->thread_notes]), 1552 if (unlikely(!t))
1525 GFP_ATOMIC); 1553 return 0;
1526 if (unlikely(!t)) { 1554
1527 rcu_read_unlock(); 1555 t->task = ct->task;
1528 return 0; 1556 if (ct->task == dump_task || !info->thread) {
1529 } 1557 t->next = info->thread;
1530 t->task = p; 1558 info->thread = t;
1531 if (p == dump_task || !info->thread) { 1559 } else {
1532 t->next = info->thread; 1560 /*
1533 info->thread = t; 1561 * Make sure to keep the original task at
1534 } else { 1562 * the head of the list.
1535 /* 1563 */
1536 * Make sure to keep the original task at 1564 t->next = info->thread->next;
1537 * the head of the list. 1565 info->thread->next = t;
1538 */
1539 t->next = info->thread->next;
1540 info->thread->next = t;
1541 }
1542 } 1566 }
1543 while_each_thread(g, p); 1567 }
1544 rcu_read_unlock();
1545 1568
1546 /* 1569 /*
1547 * Now fill in each thread's information. 1570 * Now fill in each thread's information.
@@ -1688,7 +1711,6 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
1688{ 1711{
1689#define NUM_NOTES 6 1712#define NUM_NOTES 6
1690 struct list_head *t; 1713 struct list_head *t;
1691 struct task_struct *g, *p;
1692 1714
1693 info->notes = NULL; 1715 info->notes = NULL;
1694 info->prstatus = NULL; 1716 info->prstatus = NULL;
@@ -1720,20 +1742,19 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
1720 1742
1721 info->thread_status_size = 0; 1743 info->thread_status_size = 0;
1722 if (signr) { 1744 if (signr) {
1745 struct core_thread *ct;
1723 struct elf_thread_status *ets; 1746 struct elf_thread_status *ets;
1724 rcu_read_lock(); 1747
1725 do_each_thread(g, p) 1748 for (ct = current->mm->core_state->dumper.next;
1726 if (current->mm == p->mm && current != p) { 1749 ct; ct = ct->next) {
1727 ets = kzalloc(sizeof(*ets), GFP_ATOMIC); 1750 ets = kzalloc(sizeof(*ets), GFP_KERNEL);
1728 if (!ets) { 1751 if (!ets)
1729 rcu_read_unlock(); 1752 return 0;
1730 return 0; 1753
1731 } 1754 ets->thread = ct->task;
1732 ets->thread = p; 1755 list_add(&ets->list, &info->thread_list);
1733 list_add(&ets->list, &info->thread_list); 1756 }
1734 } 1757
1735 while_each_thread(g, p);
1736 rcu_read_unlock();
1737 list_for_each(t, &info->thread_list) { 1758 list_for_each(t, &info->thread_list) {
1738 int sz; 1759 int sz;
1739 1760