@@ -505,8 +505,9 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
505
505
char * k_platform , * k_base_platform ;
506
506
char __user * u_platform , * u_base_platform , * p ;
507
507
int loop ;
508
- int nr ; /* reset for each csp adjustment */
509
508
unsigned long flags = 0 ;
509
+ int ei_index ;
510
+ elf_addr_t * elf_info ;
510
511
511
512
#ifdef CONFIG_MMU
512
513
/* In some cases (e.g. Hyper-Threading), we want to avoid L1 evictions
@@ -601,44 +602,24 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
601
602
csp -= sp & 15UL ;
602
603
sp -= sp & 15UL ;
603
604
604
- /* put the ELF interpreter info on the stack */
605
- #define NEW_AUX_ENT (id , val ) \
606
- do { \
607
- struct { unsigned long _id, _val; } __user *ent, v; \
608
- \
609
- ent = (void __user *) csp; \
610
- v._id = (id); \
611
- v._val = (val); \
612
- if (copy_to_user(ent + nr, &v, sizeof(v))) \
613
- return -EFAULT; \
614
- nr++; \
605
+ /* Create the ELF interpreter info */
606
+ elf_info = (elf_addr_t * )mm -> saved_auxv ;
607
+ /* update AT_VECTOR_SIZE_BASE if the number of NEW_AUX_ENT() changes */
608
+ #define NEW_AUX_ENT (id , val ) \
609
+ do { \
610
+ *elf_info++ = id; \
611
+ *elf_info++ = val; \
615
612
} while (0)
616
613
617
- nr = 0 ;
618
- csp -= 2 * sizeof (unsigned long );
619
- NEW_AUX_ENT (AT_NULL , 0 );
620
- if (k_platform ) {
621
- nr = 0 ;
622
- csp -= 2 * sizeof (unsigned long );
623
- NEW_AUX_ENT (AT_PLATFORM ,
624
- (elf_addr_t ) (unsigned long ) u_platform );
625
- }
626
-
627
- if (k_base_platform ) {
628
- nr = 0 ;
629
- csp -= 2 * sizeof (unsigned long );
630
- NEW_AUX_ENT (AT_BASE_PLATFORM ,
631
- (elf_addr_t ) (unsigned long ) u_base_platform );
632
- }
633
-
634
- if (bprm -> have_execfd ) {
635
- nr = 0 ;
636
- csp -= 2 * sizeof (unsigned long );
637
- NEW_AUX_ENT (AT_EXECFD , bprm -> execfd );
638
- }
639
-
640
- nr = 0 ;
641
- csp -= DLINFO_ITEMS * 2 * sizeof (unsigned long );
614
+ #ifdef ARCH_DLINFO
615
+ /*
616
+ * ARCH_DLINFO must come first so PPC can do its special alignment of
617
+ * AUXV.
618
+ * update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT() in
619
+ * ARCH_DLINFO changes
620
+ */
621
+ ARCH_DLINFO ;
622
+ #endif
642
623
NEW_AUX_ENT (AT_HWCAP , ELF_HWCAP );
643
624
#ifdef ELF_HWCAP2
644
625
NEW_AUX_ENT (AT_HWCAP2 , ELF_HWCAP2 );
@@ -659,17 +640,29 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
659
640
NEW_AUX_ENT (AT_EGID , (elf_addr_t ) from_kgid_munged (cred -> user_ns , cred -> egid ));
660
641
NEW_AUX_ENT (AT_SECURE , bprm -> secureexec );
661
642
NEW_AUX_ENT (AT_EXECFN , bprm -> exec );
643
+ if (k_platform )
644
+ NEW_AUX_ENT (AT_PLATFORM ,
645
+ (elf_addr_t )(unsigned long )u_platform );
646
+ if (k_base_platform )
647
+ NEW_AUX_ENT (AT_BASE_PLATFORM ,
648
+ (elf_addr_t )(unsigned long )u_base_platform );
649
+ if (bprm -> have_execfd )
650
+ NEW_AUX_ENT (AT_EXECFD , bprm -> execfd );
651
+ #undef NEW_AUX_ENT
652
+ /* AT_NULL is zero; clear the rest too */
653
+ memset (elf_info , 0 , (char * )mm -> saved_auxv +
654
+ sizeof (mm -> saved_auxv ) - (char * )elf_info );
662
655
663
- #ifdef ARCH_DLINFO
664
- nr = 0 ;
665
- csp -= AT_VECTOR_SIZE_ARCH * 2 * sizeof (unsigned long );
656
+ /* And advance past the AT_NULL entry. */
657
+ elf_info += 2 ;
666
658
667
- /* ARCH_DLINFO must come last so platform specific code can enforce
668
- * special alignment requirements on the AUXV if necessary (eg. PPC).
669
- */
670
- ARCH_DLINFO ;
671
- #endif
672
- #undef NEW_AUX_ENT
659
+ ei_index = elf_info - (elf_addr_t * )mm -> saved_auxv ;
660
+ csp -= ei_index * sizeof (elf_addr_t );
661
+
662
+ /* Put the elf_info on the stack in the right place. */
663
+ if (copy_to_user ((void __user * )csp , mm -> saved_auxv ,
664
+ ei_index * sizeof (elf_addr_t )))
665
+ return - EFAULT ;
673
666
674
667
/* allocate room for argv[] and envv[] */
675
668
csp -= (bprm -> envc + 1 ) * sizeof (elf_caddr_t );
0 commit comments