about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPaul Pluzhnikov <ppluzhnikov@google.com>2014-06-19 19:57:57 -0700
committerPaul Pluzhnikov <ppluzhnikov@google.com>2014-06-19 19:57:57 -0700
commit007f8306a3944bdee42c0f15ac849dc8132d67f1 (patch)
tree62ff09d66c1921f57daee39bff1a1c2cd891734a
parent95d48c5aeaf55b709a1a82d890e0c5b0ad71a9fc (diff)
downloadglibc-007f8306a3944bdee42c0f15ac849dc8132d67f1.tar.gz
glibc-007f8306a3944bdee42c0f15ac849dc8132d67f1.tar.xz
glibc-007f8306a3944bdee42c0f15ac849dc8132d67f1.zip
For b/13901604 (suid-root exe + unsecure environment variable => wrong __google_auxv), forward-port the second part of the fix (http://cr/69343116) to GRTEv4 via
-rw-r--r--README.google8
-rw-r--r--csu/elf-init.c14
-rw-r--r--sysdeps/i386/start.S70
-rw-r--r--sysdeps/x86_64/start.S51
4 files changed, 22 insertions, 121 deletions
diff --git a/README.google b/README.google
index 3ffd7d28e1..775e6b81e8 100644
--- a/README.google
+++ b/README.google
@@ -366,3 +366,11 @@ stdio-common/tmpnam.c
   b/6115789
   TODO(ppluzhnikov): revert this after cleanup.
   (ppluzhnikov, google-local)
+
+csu/elf-init.c
+sysdeps/i386/start.S
+sysdeps/x86_64/start.S
+  For b/13901604, revert local changes to sysdeps/{i386,x86_64}/elf/start.S,
+  and initialize __google_auxv in __libc_csu_init instead.
+  (ppluzhnikov, google-local)
+
diff --git a/csu/elf-init.c b/csu/elf-init.c
index 4daf673e67..d064d6969e 100644
--- a/csu/elf-init.c
+++ b/csu/elf-init.c
@@ -35,6 +35,8 @@
 
 #include <stddef.h>
 
+# include <link.h>  // For ElfW.
+
 
 /* These magic symbols are provided by the linker.  */
 extern void (*__preinit_array_start []) (int, char **, char **)
@@ -77,6 +79,18 @@ __libc_csu_init (int argc, char **argv, char **envp)
     for (i = 0; i < size; i++)
       (*__preinit_array_start [i]) (argc, argv, envp);
   }
+
+  extern ElfW(auxv_t) *__google_auxv;  /* Defined in dl-init.c  */
+  /* _dl_init() is never called for fully-static binary.
+     Initialize __google_auxv here.  */
+  if (__google_auxv == NULL)
+    {
+      char **e;
+
+      for (e = envp; *e; ++e) /* Skip.  */;
+      __google_auxv = (ElfW(auxv_t) *) ++e;
+    }
+
 #endif
 
 #ifndef NO_INITFINI
diff --git a/sysdeps/i386/start.S b/sysdeps/i386/start.S
index 2b8c671a6e..b79bff2dfc 100644
--- a/sysdeps/i386/start.S
+++ b/sysdeps/i386/start.S
@@ -59,7 +59,6 @@ _start:
 	/* Clear the frame pointer.  The ABI suggests this be done, to mark
 	   the outermost frame obviously.  */
 	xorl %ebp, %ebp
-	call __google_init
 
 	/* Extract the arguments as encoded on the stack and set up
 	   the arguments for `main': argc, argv.  envp will be determined
@@ -123,64 +122,6 @@ _start:
 	ret
 #endif
 
-/*
-  %esp		The stack contains the arguments and environment:
-		0(%esp)				ra
-		1*4(%esp)			argc
-		2*4(%esp)			argv[0]
-		...
-		(argc+2)*4(%esp)		NULL
-		(argc+3)*4(%esp)		envp[0]
-		...
-		(argc+2+env_count+1)*4(%esp)	NULL
-                (argc+2+env_count+2)*4(%esp)	auxv[0]
-		...
-*/
-
-__google_init:
-#ifdef SHARED
-	call 1b
-	addl $_GLOBAL_OFFSET_TABLE_, %ebx
-	leal __google_argc@GOTOFF(%ebx), %ecx
-#else
-	leal __google_argc, %ecx
-#endif
-	movl 4(%esp), %eax
-	movl %eax, 0(%ecx)
-	push %esp
-	pop %eax
-	addl $2*4, %eax
-#ifdef SHARED
-	leal __google_argv@GOTOFF(%ebx), %ecx
-#else
-	leal __google_argv, %ecx
-#endif
-	movl %eax, 0(%ecx)
-/* The next loop could be omitted if we are to trust argc from the kernel.  */
-1:	cmpl $0, 0(%eax)  /* while(argv[i++] != 0) skip; */
-	je 2f
-	addl $4, %eax
-	jmp 1b
-2:	addl $4, %eax
-#ifdef SHARED
-	leal __google_envp@GOTOFF(%ebx), %ecx
-#else
-	leal __google_envp, %ecx
-#endif
-	movl %eax, 0(%ecx)
-3:	cmpl $0, 0(%eax)  /* while (envp[i++] != 0) skip; */
-	je 4f
-	addl $4, %eax
-	jmp 3b
-4:	addl $4, %eax
-#ifdef SHARED
-	leal __google_auxv@GOTOFF(%ebx), %ecx
-#else
-	leal __google_auxv, %ecx
-#endif
-	movl %eax, 0(%ecx)
-	ret
-
 /* To fulfill the System V/i386 ABI we need this symbol.  Yuck, it's so
    meaningless since we don't support machines < 80386.  */
 	.section .rodata
@@ -196,14 +137,3 @@ __data_start:
 	.long 0
 	.weak data_start
 	data_start = __data_start
-
-/* The {argc,argv,envp} variables are not exposed to keep the interface narrow
-   (we don't need anything except auxv right now). If/when they are needed,
-   simply mark them with ".globl".  */
-__google_argc: .long 0
-__google_argv: .long 0
-__google_envp: .long 0
-	.globl __google_auxv
-__google_auxv: .long 0
-
-
diff --git a/sysdeps/x86_64/start.S b/sysdeps/x86_64/start.S
index 09020cffe1..e3d4ff8e20 100644
--- a/sysdeps/x86_64/start.S
+++ b/sysdeps/x86_64/start.S
@@ -65,7 +65,6 @@ _start:
 	/* Clear the frame pointer.  The ABI suggests this be done, to mark
 	   the outermost frame obviously.  */
 	xorl %ebp, %ebp
-	call __google_init
 
 	/* Extract the arguments as encoded on the stack and set up
 	   the arguments for __libc_start_main (int (*main) (int, char **, char **),
@@ -126,46 +125,6 @@ _start:
 	hlt			/* Crash if somehow `exit' does return.	 */
 	cfi_endproc
 
-/*
-   %rsp		The stack contains the arguments and environment:
-		0(%rsp)				ra
-		1*8(%rsp)			argc
-		2*8(%rsp)			argv[0]
-		...
-		(argc+2)*8(%rsp)		NULL
-		(argc+3)*8(%rsp)		envp[0]
-		...
-		(argc+2+env_count+1)*8(%rsp)	NULL
-                (argc+2+env_count+2)*8(%rsp)	auxv[0]
-		...
-*/
-__google_init:
-	leaq __google_argc(%rip), %rbx  /* %rbx = &__google_argc  */
-	movq 8(%rsp), %rax
-	movq %rax, 0(%rbx)
-	push %rsp
-	pop %rax
-	addq $2*8, %rax
-	leaq __google_argv(%rip), %rbx
-	movq %rax, 0(%rbx)
-/* The next loop could be omitted if we are to trust argc from the kernel.  */
-1:	cmpq $0, 0(%rax)  /* while(argv[i++] != 0) skip; */
-	je 2f
-	addq $8, %rax
-	jmp 1b
-2:	addq $8, %rax
-	leaq __google_envp(%rip), %rbx
-	movq %rax, 0(%rbx)
-3:	cmpq $0, 0(%rax)  /* while (envp[i++] != 0) skip; */
-	je 4f
-	addq $8, %rax
-	jmp 3b
-4:	addq $8, %rax
-	leaq __google_auxv(%rip), %rbx
-	movq %rax, 0(%rbx)
-	ret
-
-
 /* Define a symbol for the first piece of initialized data.  */
 	.data
 	.globl __data_start
@@ -173,13 +132,3 @@ __data_start:
 	.long 0
 	.weak data_start
 	data_start = __data_start
-
-	.p2align 3
-/* The {argc,argv,envp} variables are not exposed to keep the interface narrow
-   (we don't need anything except auxv right now). If/when they are needed,
-   simply mark them with ".globl".  */
-__google_argc: .quad 0
-__google_argv: .quad 0
-__google_envp: .quad 0
-	.globl __google_auxv
-__google_auxv: .quad 0