From: Seebs on 16 Apr 2010 02:39 On 2010-04-15 12:36:56 -0500, blacklight said: > 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 most likely explanation would be that your chroot environment doesn't have all the libraries and support files the programs need to run. It's possible that a statically-linked binary would work on your system (I seem to recall that being one of the workarounds), otherwise, you need to get enough of the infrastructure of the system in place that executables run. Usually that means a fair bit of /lib or /usr/lib, /etc, and probably /bin. Generally, chroot(2) is most useful for simplifying execution paths within a program that will use it directly. The case of setting up an entire virtual filesystem and spawning new programs is a lot harder to get right. Note also that plain chroot(2) offers essentially no security if you don't know how to use it; you have to be root to use it, and if you don't immediately drop those privileges, well, root can get out of a chroot directory very easily. -s -- Copyright 2010, all wrongs reversed. Peter Seebach / usenet-nospam(a)seebs.net http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
From: blacklight on 16 Apr 2010 06:37 -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Well I've also tried by using pipe()+fork()+exec() routing to get around the issue, but it doesn't work this way too. Again, this is the tree where I'm going to chroot: + /p |--> /p/popen |--> /p/test The source code of test in this case is very simple, a simple and stupid printf, so it relies on no external library. This is the new code of popen.c: #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main ( int argc, char *argv[] ) { if (chroot(".") < 0) return EXIT_FAILURE; execl ("/test", "test", NULL); return EXIT_SUCCESS; } Again, it doesn't work like this (if I just remove the chroot call and I exec "test" in the ordinary way, through the absolute path "/p/test" as first parameter of execl, everything works fine). I've also tried using a pipe: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> typedef int pipe_t[2]; int main ( int argc, char *argv[] ) { pipe_t pp; char ch; if (chroot(".") < 0) return EXIT_FAILURE; if (pipe(pp) < 0) return EXIT_FAILURE; if (!fork()) { close(pp[0]); close(1); dup(pp[1]); execl ("/test", "test", NULL); close(pp[1]); exit(0); } else { close(pp[1]); while (read(pp[0], &ch, 1) > 0) write (1, &ch, 1); write (1, "\n", 1); close(pp[0]); wait ((int*) 0); } return EXIT_SUCCESS; } This behaviour is really weird and I can find no explanation for that. Anyway, I cannot avoid the chroot() jail. I'm working to improve a tiny webserver coded by a friend in order to let it work with CGI apps/scripts, and it strongly relies on chroot() system call. (Oh, and of course I execute this program as root, lol). William Ahern <william(a)wilbur.25thandclement.com> wrote: > 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. - -- - -----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 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEUEARECAAYFAkvIPe8ACgkQ6EaK+0bbwZVbQACY3RwWmaNo6jH23674Wwk0MDPJ oQCePA3XQlq13hREUyDgN7I7DAGA9tI= =BrVq -----END PGP SIGNATURE-----
From: Rainer Weikusat on 16 Apr 2010 07:30 blacklight <blacklight(a)wintermute.blacklight.org> writes: > Again, this is the tree where I'm going to chroot: > > + /p > |--> /p/popen > |--> /p/test > > The source code of test in this case is very simple, a simple and stupid > printf, so it relies on no external library. This is the new code of popen.c: > > > #include <stdio.h> > #include <stdlib.h> > #include <unistd.h> > > int > main ( int argc, char *argv[] ) > { > if (chroot(".") < 0) > return EXIT_FAILURE; > > execl ("/test", "test", NULL); > return EXIT_SUCCESS; > } > > Again, it doesn't work like this (if I just remove the chroot call and I exec > "test" in the ordinary way, through the absolute path "/p/test" as first > parameter of execl, everything works fine). You either need to add a couple libraries to your chroot or ensure that programs you might want to execute are statically linked.
From: Mark Hobley on 16 Apr 2010 08:03 blacklight <blacklight(a)wintermute.blacklight.org> wrote: > This behaviour is really weird and I can find no explanation for that. > Anyway, I cannot avoid the chroot() jail. I'm working to improve a tiny > webserver coded by a friend in order to let it work with CGI apps/scripts, and > it strongly relies on chroot() system call. You might want to look at thttpd then. That is a tiny webserver with CGI and chroot capabilities, so is probably a similar to the one you are working on. Mark. -- Mark Hobley Linux User: #370818 http://markhobley.yi.org/
From: Casper H.S. Dik on 16 Apr 2010 08:39 Rainer Weikusat <rweikusat(a)mssgmbh.com> writes: >blacklight <blacklight(a)wintermute.blacklight.org> writes: >> Again, this is the tree where I'm going to chroot: >> >> + /p >> |--> /p/popen >> |--> /p/test >> >> The source code of test in this case is very simple, a simple and stupid >> printf, so it relies on no external library. This is the new code of popen.c: >> >> >> #include <stdio.h> >> #include <stdlib.h> >> #include <unistd.h> >> >> int >> main ( int argc, char *argv[] ) >> { >> if (chroot(".") < 0) >> return EXIT_FAILURE; >> >> execl ("/test", "test", NULL); >> return EXIT_SUCCESS; >> } >> >> Again, it doesn't work like this (if I just remove the chroot call and I exec >> "test" in the ordinary way, through the absolute path "/p/test" as first >> parameter of execl, everything works fine). >You either need to add a couple libraries to your chroot or ensure >that programs you might want to execute are statically linked. You can also easily test this using: chroot /p /test Casper -- Expressed in this posting are my opinions. They are in no way related to opinions held by my employer, Sun Microsystems. Statements on Sun products included here are not gospel and may be fiction rather than truth.
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 Prev: TCP/IP stream socket Next: Using a mutex within the data structure that I want to protect |