Prev: Bug in sqlite3?
Next: TLS -cadir and 8.4
From: Jeff Hobbs on 28 Apr 2010 12:18 On Apr 28, 6:21 am, Alexandre Ferrieux <alexandre.ferri...(a)gmail.com> wrote: > On Apr 28, 2:43 pm, Alexandre Ferrieux <alexandre.ferri...(a)gmail.com> > wrote: > > > > > - look at the .so itself to see if a shell-interpretation of > > ">BIZARRE_CHARACTERS" could account for the creation of a file named > > BIZARRE_CHARACTERS > > OK nevermind, looking again at the strace I now see the smoking gun :) > > 567 15:55:17.463401 execve("/lib64/libc-2.7.so", ["/lib64/ > libc-2.7.so"], [/* 41 vars */]) = -1 ENOEXEC (Exec format error) > > 567 15:55:17.524935 execve("/bin/sh", ["/bin/sh", "/lib64/ > libc-2.7.so"], [/* 41 vars */] <unfinished ...> > > [snip] > > 567 15:55:17.526982 read(10, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0> > \0\1\0\0\0\340\342"..., 8192) = 8192 > > 567 15:55:17.527263 open(" àâ @°Û @8", O_WRONLY|O_CREAT|O_TRUNC| > O_LARGEFILE, 0666) = 3 > > Here we see that /bin/sh, which is invoked with /lib64/libc-2.7.so > after the failure of the direct execve() of the lib (why does it > fail ???), rightfully parses its beginnings as a command line: > > \177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340\342 > > parsed as (something like) > > \177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0 > \0\1\0\0\0\340\342 > > you'll recognize the sequence \340\342 as the characters "àâ" in the > filename above ! > > So, everything is clear: > > (1) we exec lib.so > > (2) for some reason the exec fails (32-64 compat issue ?) > > (3) the OS then defaults to passing the file to /bin/sh > > (4) in script syntax the beginning contains a ">" redirection which > creates the bizarrely named file > > (5) it is empty, because the characters before the ">" are not a true > command's name either > > This could be fixed by attacking (1) or (2), though (1) is the only > safe way... Wow. Nice analysis. I look at the /lib64/libc.so.6 on my SuSE 9 machine and see the '>' as well, but I assume it doesn't fail the first execve. Note that the code at the Tcl level that causes this is just using Tcl exec, not /bin/sh. The /bin/sh is a fallback I was not aware of from execve, and my SuSE man page doesn't mention it. I do see it mentioned at: http://www.freebsd.org/doc/en/books/handbook/linuxemu-advanced.html but that is about FreeBSD's Linux emulation. Perhaps this behavior is something specific to Ubuntu. I did the strace on my SuSE machine and the [exec /lib64/libc.so.6] invokes clone(). Andreas and I thought this could be an issue with running 32-bit Tcl on 64-bit Linux, but I compiled Tcl 32-bit (-m32) and it still used clone() successfully. Jeff
From: Jeff Hobbs on 28 Apr 2010 13:00 On Apr 28, 6:21 am, Alexandre Ferrieux <alexandre.ferri...(a)gmail.com> wrote: > On Apr 28, 2:43 pm, Alexandre Ferrieux <alexandre.ferri...(a)gmail.com> > wrote: > > > > > - look at the .so itself to see if a shell-interpretation of > > ">BIZARRE_CHARACTERS" could account for the creation of a file named > > BIZARRE_CHARACTERS > > OK nevermind, looking again at the strace I now see the smoking gun :) > > 567 15:55:17.463401 execve("/lib64/libc-2.7.so", ["/lib64/ > libc-2.7.so"], [/* 41 vars */]) = -1 ENOEXEC (Exec format error) > > 567 15:55:17.524935 execve("/bin/sh", ["/bin/sh", "/lib64/ > libc-2.7.so"], [/* 41 vars */] <unfinished ...> > > [snip] > > 567 15:55:17.526982 read(10, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0> > \0\1\0\0\0\340\342"..., 8192) = 8192 > > 567 15:55:17.527263 open(" àâ @°Û @8", O_WRONLY|O_CREAT|O_TRUNC| > O_LARGEFILE, 0666) = 3 > > Here we see that /bin/sh, which is invoked with /lib64/libc-2.7.so > after the failure of the direct execve() of the lib (why does it > fail ???), rightfully parses its beginnings as a command line: > > \177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340\342 > > parsed as (something like) > > \177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0 > \0\1\0\0\0\340\342 > > you'll recognize the sequence \340\342 as the characters "àâ" in the > filename above ! > > So, everything is clear: > > (1) we exec lib.so > > (2) for some reason the exec fails (32-64 compat issue ?) > > (3) the OS then defaults to passing the file to /bin/sh > > (4) in script syntax the beginning contains a ">" redirection which > creates the bizarrely named file > > (5) it is empty, because the characters before the ">" are not a true > command's name either > > This could be fixed by attacking (1) or (2), though (1) is the only > safe way... Kevin on chat described the one situation I hadn't considered ... the / lib64/libc* file exists, but you actually have a 32-bit kernel. This would mean the magic number really isn't known, thus the /bin/sh fallback and resultant failure. I guess the "Ubuntu-specific" failure we have here is that Ubuntu (or some Ubuntu-packaged component) is causing the install of /lib64/libc even on a 32-bit system. This all makes sense, and also supports the solution we had planned - checking for {$::tcl_platform(wordSize) > 4} before checking anything 64-bit related. Jeff
From: Alexandre Ferrieux on 28 Apr 2010 15:48 > I guess the "Ubuntu-specific" failure > we have here is that Ubuntu (or some Ubuntu-packaged component) is > causing the install of /lib64/libc even on a 32-bit system. But even in that case, why would /lib64 be in the LD_LIBRARY_PATH ? > This all makes sense, and also supports the solution we had planned - > checking for {$::tcl_platform(wordSize) > 4} before checking anything > 64-bit related. Yes, that should work too. -Alex
From: Alexandre Ferrieux on 28 Apr 2010 16:35 On Apr 28, 6:18 pm, Jeff Hobbs <jeff.ho...(a)gmail.com> wrote: > > I did the strace on my SuSE machine and > the [exec /lib64/libc.so.6] invokes clone(). Ah, but it does in the original strace too. The Tcl command [exec foo.so] always does fork()+execve(), and fork() is a flavour of clone(). To follow children use the -f flag to strace. In the child you should see the execve(). As for who's doing the /bin/sh fallback, I was wrong to say it was the OS. It turns out it is the library functions execvp() et al which do that, and it is documented on Linux: If the header of a file isnt recognized (the attempted execve(2) failed with the error ENOEXEC), these functions will execute the shell (/bin/sh) with the path of the file as its first argument. (If this attempt fails, no further searching is done.) -Alex
From: kennykb on 28 Apr 2010 18:57
On Apr 28, 3:48 pm, Alexandre Ferrieux <alexandre.ferri...(a)gmail.com> wrote: > > I guess the "Ubuntu-specific" failure > > we have here is that Ubuntu (or some Ubuntu-packaged component) is > > causing the install of /lib64/libc even on a 32-bit system. > > But even in that case, why would /lib64 be in the LD_LIBRARY_PATH ? Because the same crappy installer that put /lib64 on the system added it to the path? -- 73 de ke9tv/2, Kevin |