aboutsummaryrefslogtreecommitdiffstats
path: root/fs/binfmt_elf_fdpic.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/binfmt_elf_fdpic.c')
-rw-r--r--fs/binfmt_elf_fdpic.c85
1 files changed, 62 insertions, 23 deletions
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 80c1f952ef78..0e8367c54624 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -25,6 +25,7 @@
25#include <linux/fcntl.h> 25#include <linux/fcntl.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/pagemap.h> 27#include <linux/pagemap.h>
28#include <linux/security.h>
28#include <linux/highmem.h> 29#include <linux/highmem.h>
29#include <linux/highuid.h> 30#include <linux/highuid.h>
30#include <linux/personality.h> 31#include <linux/personality.h>
@@ -455,8 +456,19 @@ error_kill:
455} 456}
456 457
457/*****************************************************************************/ 458/*****************************************************************************/
459
460#ifndef ELF_BASE_PLATFORM
458/* 461/*
459 * present useful information to the program 462 * AT_BASE_PLATFORM indicates the "real" hardware/microarchitecture.
463 * If the arch defines ELF_BASE_PLATFORM (in asm/elf.h), the value
464 * will be copied to the user stack in the same manner as AT_PLATFORM.
465 */
466#define ELF_BASE_PLATFORM NULL
467#endif
468
469/*
470 * present useful information to the program by shovelling it onto the new
471 * process's stack
460 */ 472 */
461static int create_elf_fdpic_tables(struct linux_binprm *bprm, 473static int create_elf_fdpic_tables(struct linux_binprm *bprm,
462 struct mm_struct *mm, 474 struct mm_struct *mm,
@@ -466,15 +478,19 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
466 unsigned long sp, csp, nitems; 478 unsigned long sp, csp, nitems;
467 elf_caddr_t __user *argv, *envp; 479 elf_caddr_t __user *argv, *envp;
468 size_t platform_len = 0, len; 480 size_t platform_len = 0, len;
469 char *k_platform; 481 char *k_platform, *k_base_platform;
470 char __user *u_platform, *p; 482 char __user *u_platform, *u_base_platform, *p;
471 long hwcap; 483 long hwcap;
472 int loop; 484 int loop;
473 int nr; /* reset for each csp adjustment */ 485 int nr; /* reset for each csp adjustment */
474 486
475 /* we're going to shovel a whole load of stuff onto the stack */
476#ifdef CONFIG_MMU 487#ifdef CONFIG_MMU
477 sp = bprm->p; 488 /* In some cases (e.g. Hyper-Threading), we want to avoid L1 evictions
489 * by the processes running on the same package. One thing we can do is
490 * to shuffle the initial stack for them, so we give the architecture
491 * an opportunity to do so here.
492 */
493 sp = arch_align_stack(bprm->p);
478#else 494#else
479 sp = mm->start_stack; 495 sp = mm->start_stack;
480 496
@@ -483,11 +499,14 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
483 return -EFAULT; 499 return -EFAULT;
484#endif 500#endif
485 501
486 /* get hold of platform and hardware capabilities masks for the machine
487 * we are running on. In some cases (Sparc), this info is impossible
488 * to get, in others (i386) it is merely difficult.
489 */
490 hwcap = ELF_HWCAP; 502 hwcap = ELF_HWCAP;
503
504 /*
505 * If this architecture has a platform capability string, copy it
506 * to userspace. In some cases (Sparc), this info is impossible
507 * for userspace to get any other way, in others (i386) it is
508 * merely difficult.
509 */
491 k_platform = ELF_PLATFORM; 510 k_platform = ELF_PLATFORM;
492 u_platform = NULL; 511 u_platform = NULL;
493 512
@@ -499,19 +518,20 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
499 return -EFAULT; 518 return -EFAULT;
500 } 519 }
501 520
502#if defined(__i386__) && defined(CONFIG_SMP) 521 /*
503 /* in some cases (e.g. Hyper-Threading), we want to avoid L1 evictions 522 * If this architecture has a "base" platform capability
504 * by the processes running on the same package. One thing we can do is 523 * string, copy it to userspace.
505 * to shuffle the initial stack for them.
506 *
507 * the conditionals here are unneeded, but kept in to make the code
508 * behaviour the same as pre change unless we have hyperthreaded
509 * processors. This keeps Mr Marcelo Person happier but should be
510 * removed for 2.5
511 */ 524 */
512 if (smp_num_siblings > 1) 525 k_base_platform = ELF_BASE_PLATFORM;
513 sp = sp - ((current->pid % 64) << 7); 526 u_base_platform = NULL;
514#endif 527
528 if (k_base_platform) {
529 platform_len = strlen(k_base_platform) + 1;
530 sp -= platform_len;
531 u_base_platform = (char __user *) sp;
532 if (__copy_to_user(u_base_platform, k_base_platform, platform_len) != 0)
533 return -EFAULT;
534 }
515 535
516 sp &= ~7UL; 536 sp &= ~7UL;
517 537
@@ -541,9 +561,13 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
541 } 561 }
542 562
543 /* force 16 byte _final_ alignment here for generality */ 563 /* force 16 byte _final_ alignment here for generality */
544#define DLINFO_ITEMS 13 564#define DLINFO_ITEMS 15
565
566 nitems = 1 + DLINFO_ITEMS + (k_platform ? 1 : 0) +
567 (k_base_platform ? 1 : 0) + AT_VECTOR_SIZE_ARCH;
545 568
546 nitems = 1 + DLINFO_ITEMS + (k_platform ? 1 : 0) + AT_VECTOR_SIZE_ARCH; 569 if (bprm->interp_flags & BINPRM_FLAGS_EXECFD)
570 nitems++;
547 571
548 csp = sp; 572 csp = sp;
549 sp -= nitems * 2 * sizeof(unsigned long); 573 sp -= nitems * 2 * sizeof(unsigned long);
@@ -575,6 +599,19 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
575 (elf_addr_t) (unsigned long) u_platform); 599 (elf_addr_t) (unsigned long) u_platform);
576 } 600 }
577 601
602 if (k_base_platform) {
603 nr = 0;
604 csp -= 2 * sizeof(unsigned long);
605 NEW_AUX_ENT(AT_BASE_PLATFORM,
606 (elf_addr_t) (unsigned long) u_base_platform);
607 }
608
609 if (bprm->interp_flags & BINPRM_FLAGS_EXECFD) {
610 nr = 0;
611 csp -= 2 * sizeof(unsigned long);
612 NEW_AUX_ENT(AT_EXECFD, bprm->interp_data);
613 }
614
578 nr = 0; 615 nr = 0;
579 csp -= DLINFO_ITEMS * 2 * sizeof(unsigned long); 616 csp -= DLINFO_ITEMS * 2 * sizeof(unsigned long);
580 NEW_AUX_ENT(AT_HWCAP, hwcap); 617 NEW_AUX_ENT(AT_HWCAP, hwcap);
@@ -590,6 +627,8 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
590 NEW_AUX_ENT(AT_EUID, (elf_addr_t) current->euid); 627 NEW_AUX_ENT(AT_EUID, (elf_addr_t) current->euid);
591 NEW_AUX_ENT(AT_GID, (elf_addr_t) current->gid); 628 NEW_AUX_ENT(AT_GID, (elf_addr_t) current->gid);
592 NEW_AUX_ENT(AT_EGID, (elf_addr_t) current->egid); 629 NEW_AUX_ENT(AT_EGID, (elf_addr_t) current->egid);
630 NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm));
631 NEW_AUX_ENT(AT_EXECFN, bprm->exec);
593 632
594#ifdef ARCH_DLINFO 633#ifdef ARCH_DLINFO
595 nr = 0; 634 nr = 0;