Hi Eyal,
This is something that is still a bit of a work-in-progress, but if
you make set the userid bit on the tup executable it will run all
sub-processes in a chroot. This way gcc doesn't know that its inside
the fuse file-system and thinks it's just writing to
'/home/user/foo/tupexample.o' instead of the whole path with the
@tupjob marker in it. However, all accesses go through fuse instead of
to the actual file-system so tup can see them. I built your example
with a suid tup and it ran successfully. Unfortunately you will have
to rebuild it from scratch if you switch between a suid tup and a
non-suid tup, since complete support for this isn't finished yet
(eventually it will be configured by an option to select how far
dependency detection & chrooting goes, and rebuilding will be
automatic when necessary).
Let me know if you have any trouble with running it in suid mode.
-Mike
Hi Eyal,
I believe this feature is now complete. You will still need tup with
suid root enabled, and you can specify certain processes to run in a
chroot using a ^-flag in the :-rule like so:
: foreach *.c |> ^c^ gcc --coverage -c %f -o %o |> %B.o | %B.gcno
Or if you already use the ^^ markers for display purposes:
: foreach *.c |> ^c CC %f^ gcc --coverage -c %f -o %o |> %B.o | %B.gcno
The 'c' character comes directly after the first carat, and tells tup
to run the sub-process in a chroot. All this really does is let the
sub-process not know that it is running in a funny tup directory, and
has a side effect of running a bit slower. Note that the
update.full_deps option also runs sub-processes in a chroot, but that
is for a different purpose.
I know the syntax is a little funky, but there is unfortunately no
easier way to get the information from the parser stage to the command
running stage. Let me know if you have any issues with it.
-Mike
-Mike
--
tup-users mailing list
email: tup-...@googlegroups.com
unsubscribe: tup-users+...@googlegroups.com
options: http://groups.google.com/group/tup-users?hl=en
I don't think I understand completely - I tried a simple Tupfile:
: foreach *.c |> ^c^ gcc --coverage -c %f -o %o |> %B.o | %B.gcno
: *.o |> ^c^ gcc --coverage %f -o %o |> prog
And created a main.c and foo.c file. After 'tup upd' I got the .gcno
files and a program. I ran the program at the command line and got two
.gcda files. Now I touch foo.c and 'tup upd', and it runs successfully
- are you seeing it try to write to foo.gcda here?
-Mike
In order to actually use the chroot, you have to bind-mount /dev into
the chroot directory (so that .tup/mnt/@tupjob-1/dev mirrors /dev),
otherwise the sub-process can't access things like /dev/null. Mounting
that requires cap_sys_admin anyway, so unfortunately just using
cap_sys_chroot isn't useful here. I would much prefer if tup didn't
have to mess with privileges at all, but I don't know of a better way
to run a sub-process purely inside the tup file-system without chroot.
> - I'm using chroot already for doing 32-bit builds on a 64-bit machine, will
> this prevent tup+chroot from working?
I'm not sure - is it easy for you to try? I don't have such an
environment set up. I have no idea how a series of chroots all the way
down would work :).
-Mike
On Wed, Mar 21, 2012 at 10:28 AM, Slawomir Czarko
wrote:
> Hi,
>
> I've got two, questions about chroot mode:
> - have you tried using "setcap cap_sys_chroot+ep tup" instead of using suid?In order to actually use the chroot, you have to bind-mount /dev into
the chroot directory (so that .tup/mnt/@tupjob-1/dev mirrors /dev),
otherwise the sub-process can't access things like /dev/null. Mounting
that requires cap_sys_admin anyway, so unfortunately just using
cap_sys_chroot isn't useful here. I would much prefer if tup didn't
have to mess with privileges at all, but I don't know of a better way
to run a sub-process purely inside the tup file-system without chroot.
> - I'm using chroot already for doing 32-bit builds on a 64-bit machine, will
> this prevent tup+chroot from working?I'm not sure - is it easy for you to try? I don't have such an
environment set up. I have no idea how a series of chroots all the way
down would work :).
Yep, that should be it (and if tup is not privileged, it will give you
an error that it can't run it in a chroot). Assuming it builds
correctly, it might also help to check that changing an input file
actually triggers a re-compile (to make sure they aren't being dropped
somehow). But if it detects the output file being written correctly, I
don't think it will be a problem.
-Mike
Why not just individually link a few important devices like null,
zero, etc.? Most builds won't need to access /dev/tty or the like.
It looks like mknod() also requires privileged access. Is there some
other way you were thinking of linking them?
Thanks,
-Mike
I was thinking a symlink, but I suppose that could mess up programs
expecting a bona fide device. Still, I suspect most programs just try
and use the standard devices without caring too much about what they
actually are.
Unfortunately a symlink can't point outside the chroot :(. As far as
the sub-process is concerned, what it sees as "/dev/null" is really
"/home/user/.../.tup/mnt/@tupjob-1/dev/null". There isn't a way for it
to access the real /dev/null directly, so the symlink would be broken
(ignoring the possibility that a sub-process could explicitly break
out of the chroot, but tup isn't using chroot for security so that's
not really an issue).
Thanks,
-Mike
Has a solution been created for the "The gcda files are not considered auto-generated by tup" yet?
The problem arises when you use a script to run your test inside of Tup.
Eg.
": foreach *.c |> ^c^ gcc --coverage -c %f -o %o |> %B.o | %B.gcno: *.o |> ^c^ gcc --coverage %f -o %o |> prog: prog |> runTestScript $f |>
"
The run test script forces the creation of the .gcda files as it ran the executable, but tup isn't aware of the gcda files, even with adding " | %B.gcda".
All you receive is: "tup error: Expected to write to file '*.gcda' from cmd * but didn't", or without that line it isn't expressed as an output.