diff options
author | Paul Pluzhnikov <ppluzhnikov@google.com> | 2014-06-19 19:57:57 -0700 |
---|---|---|
committer | Paul Pluzhnikov <ppluzhnikov@google.com> | 2014-06-19 19:57:57 -0700 |
commit | 007f8306a3944bdee42c0f15ac849dc8132d67f1 (patch) | |
tree | 62ff09d66c1921f57daee39bff1a1c2cd891734a | |
parent | 95d48c5aeaf55b709a1a82d890e0c5b0ad71a9fc (diff) | |
download | glibc-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.google | 8 | ||||
-rw-r--r-- | csu/elf-init.c | 14 | ||||
-rw-r--r-- | sysdeps/i386/start.S | 70 | ||||
-rw-r--r-- | sysdeps/x86_64/start.S | 51 |
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 |