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
You want comp.unix.programmer.
--
Eric Sosman
eso...@ieee-dot-org.invalid
> On 4/15/2010 1:27 PM, blacklight wrote:
>> 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
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
--
I find the easiest thing to do is to k/f myself and just troll away
-- David Melville on r.a.s.f1
This requires proof?
[snip]
--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
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.
You either need a shell for popen(), or execve(). Read the manuals,
more carefully this time.
On Apr 15, 8:33 pm, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
>
> You want comp.unix.programmer.
Aren't you just an adorable fluffy tropical cookie.
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 fuck can I execute an
external command in a chroot'ed environment?
--
-----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
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?
--
Ian Collins
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 news: 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
--
Alan Curry
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.
[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?
> 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.
--
Burton Samograd