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.c34
1 files changed, 25 insertions, 9 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 8fcfa398d350..e3ff2b9e602f 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -152,12 +152,14 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
152 elf_addr_t __user *sp; 152 elf_addr_t __user *sp;
153 elf_addr_t __user *u_platform; 153 elf_addr_t __user *u_platform;
154 elf_addr_t __user *u_base_platform; 154 elf_addr_t __user *u_base_platform;
155 elf_addr_t __user *u_rand_bytes;
155 const char *k_platform = ELF_PLATFORM; 156 const char *k_platform = ELF_PLATFORM;
156 const char *k_base_platform = ELF_BASE_PLATFORM; 157 const char *k_base_platform = ELF_BASE_PLATFORM;
158 unsigned char k_rand_bytes[16];
157 int items; 159 int items;
158 elf_addr_t *elf_info; 160 elf_addr_t *elf_info;
159 int ei_index = 0; 161 int ei_index = 0;
160 struct task_struct *tsk = current; 162 const struct cred *cred = current_cred();
161 struct vm_area_struct *vma; 163 struct vm_area_struct *vma;
162 164
163 /* 165 /*
@@ -196,6 +198,15 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
196 return -EFAULT; 198 return -EFAULT;
197 } 199 }
198 200
201 /*
202 * Generate 16 random bytes for userspace PRNG seeding.
203 */
204 get_random_bytes(k_rand_bytes, sizeof(k_rand_bytes));
205 u_rand_bytes = (elf_addr_t __user *)
206 STACK_ALLOC(p, sizeof(k_rand_bytes));
207 if (__copy_to_user(u_rand_bytes, k_rand_bytes, sizeof(k_rand_bytes)))
208 return -EFAULT;
209
199 /* Create the ELF interpreter info */ 210 /* Create the ELF interpreter info */
200 elf_info = (elf_addr_t *)current->mm->saved_auxv; 211 elf_info = (elf_addr_t *)current->mm->saved_auxv;
201 /* update AT_VECTOR_SIZE_BASE if the number of NEW_AUX_ENT() changes */ 212 /* update AT_VECTOR_SIZE_BASE if the number of NEW_AUX_ENT() changes */
@@ -223,11 +234,12 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
223 NEW_AUX_ENT(AT_BASE, interp_load_addr); 234 NEW_AUX_ENT(AT_BASE, interp_load_addr);
224 NEW_AUX_ENT(AT_FLAGS, 0); 235 NEW_AUX_ENT(AT_FLAGS, 0);
225 NEW_AUX_ENT(AT_ENTRY, exec->e_entry); 236 NEW_AUX_ENT(AT_ENTRY, exec->e_entry);
226 NEW_AUX_ENT(AT_UID, tsk->uid); 237 NEW_AUX_ENT(AT_UID, cred->uid);
227 NEW_AUX_ENT(AT_EUID, tsk->euid); 238 NEW_AUX_ENT(AT_EUID, cred->euid);
228 NEW_AUX_ENT(AT_GID, tsk->gid); 239 NEW_AUX_ENT(AT_GID, cred->gid);
229 NEW_AUX_ENT(AT_EGID, tsk->egid); 240 NEW_AUX_ENT(AT_EGID, cred->egid);
230 NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm)); 241 NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm));
242 NEW_AUX_ENT(AT_RANDOM, (elf_addr_t)(unsigned long)u_rand_bytes);
231 NEW_AUX_ENT(AT_EXECFN, bprm->exec); 243 NEW_AUX_ENT(AT_EXECFN, bprm->exec);
232 if (k_platform) { 244 if (k_platform) {
233 NEW_AUX_ENT(AT_PLATFORM, 245 NEW_AUX_ENT(AT_PLATFORM,
@@ -949,14 +961,14 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
949 set_binfmt(&elf_format); 961 set_binfmt(&elf_format);
950 962
951#ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES 963#ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES
952 retval = arch_setup_additional_pages(bprm, executable_stack); 964 retval = arch_setup_additional_pages(bprm, !!elf_interpreter);
953 if (retval < 0) { 965 if (retval < 0) {
954 send_sig(SIGKILL, current, 0); 966 send_sig(SIGKILL, current, 0);
955 goto out; 967 goto out;
956 } 968 }
957#endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */ 969#endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */
958 970
959 compute_creds(bprm); 971 install_exec_creds(bprm);
960 current->flags &= ~PF_FORKNOEXEC; 972 current->flags &= ~PF_FORKNOEXEC;
961 retval = create_elf_tables(bprm, &loc->elf_ex, 973 retval = create_elf_tables(bprm, &loc->elf_ex,
962 load_addr, interp_load_addr); 974 load_addr, interp_load_addr);
@@ -1361,6 +1373,7 @@ static void fill_prstatus(struct elf_prstatus *prstatus,
1361static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p, 1373static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
1362 struct mm_struct *mm) 1374 struct mm_struct *mm)
1363{ 1375{
1376 const struct cred *cred;
1364 unsigned int i, len; 1377 unsigned int i, len;
1365 1378
1366 /* first copy the parameters from user space */ 1379 /* first copy the parameters from user space */
@@ -1388,8 +1401,11 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
1388 psinfo->pr_zomb = psinfo->pr_sname == 'Z'; 1401 psinfo->pr_zomb = psinfo->pr_sname == 'Z';
1389 psinfo->pr_nice = task_nice(p); 1402 psinfo->pr_nice = task_nice(p);
1390 psinfo->pr_flag = p->flags; 1403 psinfo->pr_flag = p->flags;
1391 SET_UID(psinfo->pr_uid, p->uid); 1404 rcu_read_lock();
1392 SET_GID(psinfo->pr_gid, p->gid); 1405 cred = __task_cred(p);
1406 SET_UID(psinfo->pr_uid, cred->uid);
1407 SET_GID(psinfo->pr_gid, cred->gid);
1408 rcu_read_unlock();
1393 strncpy(psinfo->pr_fname, p->comm, sizeof(psinfo->pr_fname)); 1409 strncpy(psinfo->pr_fname, p->comm, sizeof(psinfo->pr_fname));
1394 1410
1395 return 0; 1411 return 0;