This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Preloading a replacement uname is causing environment to be cleaned if libpthread is loaded


Sorry, I forgot to mention that I'm running Fedora 12 on i686:

[west@localhost test-ld]$ rpm -q glibc
glibc-2.11.1-1.i686
[west@localhost test-ld]$ uname -a
Linux localhost.localdomain 2.6.32.9-70.fc12.i686 #1 SMP Wed Mar 3
05:14:32 UTC 2010 i686 i686 i386 GNU/Linux

Not an April Fool's joke...



On Thu, Apr 1, 2010 at 6:03 PM, Rob West <robertfwest@gmail.com> wrote:
> OK, I wouldn't be surprised that I'm doing something wrong, but this
> is quite weird:
>
> I want to be able to overload/wrap uname. So, I have a simple library
> that I preload. Now, even though my test program does not call uname,
> if I link the pthread library with it, the environment variables get
> cleared. Here is a run of the test code linked with pthread:
>
> [west@localhost test-ld]$
> LD_PRELOAD=/home/west/test-ld/libfakeuname.so ./test_w_pthread
> Calling old_uname
> Return value was 0
> Buffer values:
> ?sysname ? ? ? =Linux
> ?nodename ? ? ?=localhost.localdomain
> ?release ? ? ? =2.6.32.9-70.fc12.i686
> ?version ? ? ? =#1 SMP Wed Mar 3 05:14:32 UTC 2010
> ?machine ? ? ? =i686
> HOME=(null)
>
> Here is a run when not linked with pthread:
>
> [west@localhost test-ld]$ LD_PRELOAD=/home/west/test-ld/libfakeuname.so ./test
> HOME=/home/west
>
> What could be going on? It sort of seems like the filling out of the
> uname struct is zeroing the environ pointer, but that's just a guess.
>
> Here is the simple test code (test.c):
>
> #include <stdio.h>
> #include <stdlib.h>
> int main(int argc, char *argv[])
> {
> ?? ?printf("HOME=%s\n", getenv("HOME"));
> ?? ?return 0;
> }
>
> And here is the replacement code (fakeuname.c):
>
> #include <stdio.h>
> #include <dlfcn.h>
> #include <stdlib.h>
> #include <sys/utsname.h>
>
> typedef int (*uname_t)(struct utsname *buf);
> typedef int (*gethostname_t)(char *name, size_t len);
>
> uname_t old_uname;
> gethostname_t old_gethostname;
>
> void fakeuname_init()
> {
> ? ?void *libc;
> ? ?char *error;
>
> ? ?libc = dlopen("/lib/libc.so.6", RTLD_LAZY);
> ? ?if (!libc) {
> ? ? ? ?fputs(dlerror(), stderr);
> ? ? ? ?exit(1);
> ? ?}
>
> ? ?old_uname = dlsym(libc, "uname");
> ? ?if ((error = dlerror()) != NULL) {
> ? ? ? ?fprintf(stderr, "%s\n", error);
> ? ? ? ?exit(1);
> ? ?}
> }
>
> int uname(struct utsname *buf)
> {
> ? ?int i;
>
> ? ?if (!old_uname)
> ? ? ? ?fakeuname_init();
>
> ? ?printf("Calling old_uname\n");
> ? ?i = old_uname(buf);
> ? ?printf("Return value was %d\n", i);
> ? ?if (!i) {
> ? ? ? ?printf("Buffer values:\n");
> ? ? ? ?printf(" ?sysname ? ? ? =%s\n", buf->sysname);
> ? ? ? ?printf(" ?nodename ? ? ?=%s\n", buf->nodename);
> ? ? ? ?printf(" ?release ? ? ? =%s\n", buf->release);
> ? ? ? ?printf(" ?version ? ? ? =%s\n", buf->version);
> ? ? ? ?printf(" ?machine ? ? ? =%s\n", buf->machine);
> ? ?}
> ? ?return i;
> }
>
> This is the makefile:
>
> all: libfakeuname.so test test_w_pthread
>
> libfakeuname.so: fakeuname.c
> ? ? ? ?gcc -Wall -O2 -fpic -shared -ldl -o $@ $^
>
> test: test.c
> ? ? ? ?gcc -Wall -O2 -o $@ $^
>
> test_w_pthread: test.c
> ? ? ? ?gcc -Wall -O2 -o $@ $^ -lpthread
>
> clean:
> ? ? ? ?rm -f libfakeuname.so test test_w_pthread
>
>
>
> Thanks for any help,
> Rob West
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]