From: blacklight on 15 Apr 2010 13:36 I'm experiencing a weird behaviour in executing programs in a chroot() environment. This is the situation. I have a path like this: /p + |--> /p/popen |--> /p/exe This is popen.c: #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main ( int argc, char *argv[] ) { FILE *pipe; char ch; if (chroot("/p") < 0) return EXIT_FAILURE; if (!(pipe = popen("/exe", "r"))) return EXIT_FAILURE; printf ("RESULT: "); while (fread(&ch, 1, 1, pipe) > 0) printf ("%c", ch); printf ("\n"); pclose(pipe); return EXIT_SUCCESS; } popen() does not fail, but just no character is read. Of course if I do not use chroot() and i just call popen ("./exe", "r") I have no problem. I also have tried popen-ing "./exe" and "exe", both without any results. Even calling a system() on "/exe", "./exe" or "exe" gives no results. So, how do I invoke an executable file in a chroot() environment? Thanks, BlackLight -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GAT d? a? C++++ U++++ P++++ L+++++ E--- W+++ !w PS+++ PE-- Y++ PGP++ X++ R+ tv-- b+>+++ DI++ G++ e+++ h* r++ z** ------END GEEK CODE BLOCK------ -ONLY- email me using my PGP key # http://pgp.mit.edu:11371/pks/lookup?op=get&search=0xE8468AFB46DBC195 Admin of # http://0x00.ath.cx
From: Nicolas George on 15 Apr 2010 13:43 blacklight wrote in message <hq7iro$ch4$1(a)speranza.aioe.org>: > I have a path like this: > /p + > |--> /p/popen > |--> /p/exe Statically linked?
From: blacklight on 15 Apr 2010 14:29 Hmmm what do you mean? They're ordinary executable files statically generated by gcc, not symbolic links nor executable relying on external dependencies. Nicolas George <nicolas$george(a)salle-s.org> wrote: > blacklight wrote in message <hq7iro$ch4$1(a)speranza.aioe.org>: >> I have a path like this: >> /p + >> |--> /p/popen >> |--> /p/exe > > Statically linked? -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GAT d? a? C++++ U++++ P++++ L+++++ E--- W+++ !w PS+++ PE-- Y++ PGP++ X++ R+ tv-- b+>+++ DI++ G++ e+++ h* r++ z** ------END GEEK CODE BLOCK------ -ONLY- email me using my PGP key # http://pgp.mit.edu:11371/pks/lookup?op=get&search=0xE8468AFB46DBC195 Admin of # http://0x00.ath.cx
From: guenther on 15 Apr 2010 14:34 On Apr 15, 10:36 am, blacklight <blackli...(a)wintermute.blacklight.org> wrote: > I'm experiencing a weird behaviour in executing programs in a chroot() > environment. This is the situation. .... > popen() does not fail, but just no character is read. Of course if I do not use > chroot() and i just call popen ("./exe", "r") I have no problem. popen() is required to support shell syntax in the command line that it is given to execute. All the systems I know do this by having it fork and exec the shell (generally /bin/sh, but there are exceptions). Since you don't have the shell in your chroot tree, the exec fails and you see EOF immediately on the pipe. If you were to actually check the result of pclose(), you would find that it indicated that the command failed, probably with status 127, the standard status for "command could not be found". The two obvious options are 1) include the shell (and dependent libraries) in the chroot 2) switch from popen() to doing your own pipe/fork/exec combo Philip Guenther
From: William Ahern on 15 Apr 2010 21:53 blacklight <blacklight(a)wintermute.blacklight.org> wrote: > I'm experiencing a weird behaviour in executing programs in a chroot() > environment. This is the situation. <snip> > while (fread(&ch, 1, 1, pipe) > 0) > printf ("%c", ch); > printf ("\n"); > > pclose(pipe); > return EXIT_SUCCESS; > } > > popen() does not fail, but just no character is read. popen() will only fail if it cannot create a pipe or fork (or perhaps allocate memory). So popen() will work even if the executable doesn't even exist, because that won't be determined until the exec() is attempted. If the exec() fails, then what? That somehow must be communicated to the process that called popen(), but there's no defined way to do that. pclose() won't give you the exit value of the process. And you can't generally distinguish a successful fork+exec which happens to write nothing to stdout from a failed exec after the fork. Basically, popen() isn't very useful for debugging your issue; it can't signal the cause of the probable culprit. There's another more specific issue, which is probably the source of your troubles. popen() and system() use the command as a parameter to /bin/sh, which is what they will actually exec() directly (i.e. `/bin/sh -c "[command]"'). Unless /bin/sh exists in the new root, you can't expect to use either popen() or system(), no matter what you're ultimately trying to execute. If there's no /bin/sh, then you need to create your own popen-like routine using pipe()+fork()+exec(). The code to do this is quite short but conceptually very dense, so one so should be very familiar with the Unix process model before attempting it. Note that system() does return the exit value, and I bet you'll see a difference if you compare the value from the chroot'd call and the non-chroot'd call. > Of course if I do not use chroot() and i just call popen ("./exe", "r") I > have no problem. I also have tried popen-ing "./exe" and "exe", both > without any results. Even calling a system() on "/exe", "./exe" or "exe" > gives no results. So, how do I invoke an executable file in a chroot() > environment? The procedure is exactly the same. There are no other side-effects of the chroot() itself. The problem is likely the absence of /bin/sh, however, which is a collateral issue.
|
Next
|
Last
Pages: 1 2 3 Prev: TCP/IP stream socket Next: Using a mutex within the data structure that I want to protect |