chroot() and popen() won't get along

B

blacklight

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
 
E

Ersek, Laszlo

I'm experiencing a weird behaviour in executing programs in a chroot()
environment.[...]

You want comp.unix.programmer.

.... and a working shell in your chroot jail.

Read the Fine Manual on popen()/system(), please.

lacos
 
P

Phil Carmody

blacklight said:
I'm experiencing a weird behaviour in executing programs in a chroot()
environment. This is the situation.

I can prove this is a unix programming question, not a C one...
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")))

There's no such thing as /exe. You're in / still.

And proof this is a unix programming issue not a C one:
-- 8< -- chroot.pl -----
#!/usr/bin/perl
chroot('/tmp');
system('/exe.pl'); # try /tmp/exe.pl instead
-- 8< --

-- 8< -- exe.pl -----
#!/usr/bin/perl
print("exe\n");
-- 8< --

Read your manpages.

Phil
 
P

Phil Carmody

Keith Thompson said:
This requires proof?

Quite possibly, a typical response to such snubs is "but I'm doing
it in C". I thought it was simplest to just prove that the language
was strictly irrelevant.

Phil
 
M

Michael Foukarakis

So, how do I invoke an
executable file in a chroot() environment?

You either need a shell for popen(), or execve(). Read the manuals,
more carefully this time.

You want comp.unix.programmer.

Aren't you just an adorable fluffy tropical cookie.
 
B

blacklight

Well, before continuing I'd like to specify a pair of things:

1. Of course I posted to comp.unix.programmer too, but nobody was able
to help me there. They mostly said to me "is your executable file
statically linked? Does it have any dependencies not taken inside the
chroot'ed environment?" but I get these errors even if my "exe" has
only a write() syscall.

2. Yeah, I read the manual pages, more than once, but there's really
nothing about this. And if the manual has nothing about this kind of
issue, I cannot imagine the solution reading it. I'm someone who likes
the RTFM philosophy too, but if the RTFM philosophy does not take to a
solution, then it's not smart to insist.

3. Some other guys on comp.unix.programmer told me "popen() uses the
local shell in order to execute the file, copy it inside the chroot'ed
environment". Well, I had already tried to copy sh and zsh inside the
chroot'ed environment, and inside its bin/ directory too, but always
without any results. Another piece of suggestion I got was "try with
the pipe-fork-exec sequence". Well, I actually tried it. Again, this is
my situation:

+-> /p
|---> /p/popen
|---> /p/exe

This, very simply, is exe.c:


#include <unistd.h>
#include <stdlib.h>

int
main ( int argc, char *argv[] )
{
write (1, "asd", 4);
return EXIT_SUCCESS;
} /* ---------- end of function main ---------- */


This is popen.c:


#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

typedef int pipe_t[2];

int
main ( int argc, char *argv[] )
{
char ch;
pipe_t pp;

if (chroot(".") < 0)
return EXIT_FAILURE;

if (pipe(pp) < 0)
return EXIT_FAILURE;

if (!fork()) {
close(pp[0]);
close(1);
dup(pp[1]);

execl ("exe", "exe", NULL);
exit(0);
} else {
close(pp[1]);
close(0);
dup(pp[0]);

while (read(0, &ch, 1) > 0)
write (1, &ch, 1);
write (1, "\n", 1);

close(pp[0]);
wait ((int*) 0);
}

return EXIT_SUCCESS;
} /* ---------- end of function main ---------- */

Even this implementation took no results. Note: if I remove the
chroot() call, everything works properly. I even tried in the exec call
to invoke the first argument as /p/exe, as ./exe, as /exe, but nothing,
always no results. Now the question is: how the **** can I execute an
external command in a chroot'ed environment?

Michael Foukarakis said:
You either need a shell for popen(), or execve(). Read the manuals,
more carefully this time.



Aren't you just an adorable fluffy tropical cookie.

--
-----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
 
I

Ian Collins

Well, before continuing I'd like to specify a pair of things:

1. Of course I posted to comp.unix.programmer too, but nobody was able
to help me there. They mostly said to me "is your executable file
statically linked? Does it have any dependencies not taken inside the
chroot'ed environment?" but I get these errors even if my "exe" has
only a write() syscall.

2. Yeah, I read the manual pages, more than once, but there's really
nothing about this. And if the manual has nothing about this kind of
issue, I cannot imagine the solution reading it. I'm someone who likes
the RTFM philosophy too, but if the RTFM philosophy does not take to a
solution, then it's not smart to insist.

3. Some other guys on comp.unix.programmer told me "popen() uses the
local shell in order to execute the file, copy it inside the chroot'ed
environment". Well, I had already tried to copy sh and zsh inside the
chroot'ed environment, and inside its bin/ directory too, but always
without any results. Another piece of suggestion I got was "try with
the pipe-fork-exec sequence". Well, I actually tried it. Again, this is
my situation:

That's three. A pair is two.

You had quite a few decent answers on c.u.p, so why don't you follow up
there, where this question belongs?
 
A

Alan Curry

|
|1. Of course I posted to comp.unix.programmer too, but nobody was able
|to help me there. They mostly said to me "is your executable file
|statically linked? Does it have any dependencies not taken inside the
|chroot'ed environment?" but I get these errors even if my "exe" has
|only a write() syscall.

You have so far given no answer to the question of whether it was statically
linked, and quite a bit of evidence that you don't know what static linking
is. Well here's some bad that was a very relevant question, and dodging
it has prevented you (and the poor fools trying to help you) from
investigating the most likely cause of your problem. You better go read up on
the concepts of dynamic linking and static linking if you want to do
something more than uselessly rant at us.

Hint 1: man ldd
 
P

Phil Carmody

blacklight said:
Well, before continuing I'd like to specify a pair of things:

1. Of course I posted to comp.unix.programmer too, but nobody was able
to help me there. They mostly said to me "is your executable file
statically linked? Does it have any dependencies not taken inside the
chroot'ed environment?" but I get these errors even if my "exe" has
only a write() syscall.

2. Yeah, I read the manual pages, more than once, but there's really
nothing about this.

Lie. It's as bold as bold can be. You don't even need to page down
on a 24-line console to see what it says about it.

Phil
 
B

blacklight

I know what we're talking about, I just don't think anyway that any web
server operating by chroot(), or any software based on the chroot()
jail, must first copy libc and ld-linux inside its own tree to allow
executable files to run. Because these are the only libraries the
called executable file relies on:


[blacklight@wintermute]-(17/04/2010, 13:24:53)
(~) ldd exe
linux-gate.so.1 => (0xb7f4d000)
libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb7dd1000)
/lib/ld-linux.so.2 (0xb7f4e000)


And anyway, I tried to copy the files they're linked to in a /lib
directory under my chroot'ed path, and set the symlinks correctly, but
still I'm having the same issue with both the versions of the popen
file (the one based on popen() call, and the one based on
pipe-fork-exec routines as well), so I don't think this is the issue.

Anyway it would be really stupid if all the chroot'ed contexts need a
copy of these libraries. And however, I cannot do without the chroot in
my case. I'm modifying a tiny web server that strongly relies on chroot
to work, in order to make it compatible with CGI scripts/apps. And I
know there are several other web servers relying on a chroot jail to
manage everything properly (thttpd first), and I don't think they copy
in their root paths libc, ld-linux and any other vital library in order
to let the CGI application work. So, what's the 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
 
B

burton.samograd

blacklight said:
I know what we're talking about, I just don't think anyway that any web
server operating by chroot(), or any software based on the chroot()
jail, must first copy libc and ld-linux inside its own tree to allow
executable files to run. Because these are the only libraries the
called executable file relies on:


[blacklight@wintermute]-(17/04/2010, 13:24:53)
(~) ldd exe
linux-gate.so.1 => (0xb7f4d000)
libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb7dd1000)
/lib/ld-linux.so.2 (0xb7f4e000)


And anyway, I tried to copy the files they're linked to in a /lib
directory under my chroot'ed path, and set the symlinks correctly, but
still I'm having the same issue with both the versions of the popen
file (the one based on popen() call, and the one based on
pipe-fork-exec routines as well), so I don't think this is the issue.

Anyway it would be really stupid if all the chroot'ed contexts need a
copy of these libraries. And however, I cannot do without the chroot in
my case. I'm modifying a tiny web server that strongly relies on chroot
to work, in order to make it compatible with CGI scripts/apps. And I
know there are several other web servers relying on a chroot jail to
manage everything properly (thttpd first), and I don't think they copy
in their root paths libc, ld-linux and any other vital library in order
to let the CGI application work. So, what's the issue?

It's not really stupid, it's how chroot works. There is nothing in a
new chroot'ed file system, so any libraries and dependancies that are
required by the program you want to popen need to be there.

Like someone else said, ldd is your friend with chroot. Just copy (and
make sure you copy and not symlink) the libraries into a /lib directory
in your chroot directory and it should work just fine.

A good way to check if it will work is to do a manual chroot from your
shell into the directory that contains the executable and see if it
works from there on the command line. If not, you're missing something.

Also, sometimes things depend on $PATH. You might need to put your
executable into a /bin directory into your chroot directory. Check your
popen man page for that one though, I can't recall at the moment.

Hopefully this helps.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top