-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Attached is the C source that is my first attempt at a mock launcher program. This program is built as the executable /usr/bin/mock with setuid:root, setgid:mock and will exec python with the input file /usr/bin/mock.py. The program successfully launches python, but I haven't worked through all the issues to complete a build (yet). I know that mock.py needs to be modified to remove the dont-run-as-root test and I've made a first cut at removing mock-helper from .cfg files, but I'm sure there are other things that need to be done. I have checked nothing into CVS at this point and even if/when I do, I suspect I'll be working off a branch for a while.
Note that the program makes use of Linux namespaces. This *should* make our handling of mount points within the chroot (/proc, /sys, etc.) a bit easier to clean up, since when the process dies the mounts should just go away. I haven't verified this though, so caveat emptor.
Anyway, it's a starting point. Please look it over and provide feedback.
Clark
Nice start. A couple discussion points:
void debug(const char *format, ...) { #ifdef DEBUG
instead of #ifdef DEBUG, can we have an env var that controls this on/off? (No recompile)
#define NSFLAG "NAMESPACE=1"
What is the purpose of this?
// elevate our privileges if (setreuid (geteuid (), geteuid ())) error("setreuid failed: %s", strerror(errno)); debug("running with uid: %d, gid: %d\n", getuid(), getgid());
Is this necessary? It seems to me like this is something that can be done in mock.py for the cases where it is necessary, as mock.py might need to know the user id of the person running mock, and so it can switch back to that user for writing output files. -- Michael
-----Original Message----- From: fedora-buildsys-list-bounces@redhat.com [mailto:fedora-buildsys-list-bounces@redhat.com] On Behalf Of Clark Williams Sent: Wednesday, June 14, 2006 10:46 AM To: Discussion of Fedora build system Subject: First cut a new mock launcher
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Attached is the C source that is my first attempt at a mock launcher program. This program is built as the executable /usr/bin/mock with setuid:root, setgid:mock and will exec python with the input file /usr/bin/mock.py. The program successfully launches python, but I haven't worked through all the issues to complete a build (yet). I know that mock.py needs to be modified to remove the dont-run-as-root test and I've made a first cut at removing mock-helper from .cfg files, but I'm sure there are other things that need to be done. I have checked nothing into CVS at this point and even if/when I do, I suspect I'll be working off a branch for a while.
Note that the program makes use of Linux namespaces. This *should* make our handling of mount points within the chroot (/proc, /sys, etc.) a bit easier to clean up, since when the process dies the mounts should just go away. I haven't verified this though, so caveat emptor.
Anyway, it's a starting point. Please look it over and provide feedback.
Clark
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.3 (GNU/Linux) Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org
iD8DBQFEkC9DHyuj/+TTEp0RAq+4AKCn4hj3bGInJBMWd1Bj6h1SMeCV+QCgt3NW hPHE9hW9DXL9ZkPLbaJrL6Y= =XtsC -----END PGP SIGNATURE-----
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Michael_E_Brown@Dell.com wrote:
Nice start. A couple discussion points:
void debug(const char *format, ...) { #ifdef DEBUG
instead of #ifdef DEBUG, can we have an env var that controls this on/off? (No recompile)
Thought about that. I didn't know if we wanted a "production" version that didn't have all the debug spew. I can rework it to use an environment variable.
#define NSFLAG "NAMESPACE=1"
What is the purpose of this?
I was unsure if we needed to know that we were running with namespaces and modify our behavior in mock.py. If it turns out we don't need to do anything differently, I'll pull this out of the environment.
// elevate our privileges if (setreuid (geteuid (), geteuid ())) error("setreuid failed: %s", strerror(errno)); debug("running with uid: %d, gid: %d\n", getuid(), getgid());
Is this necessary? It seems to me like this is something that can be done in mock.py for the cases where it is necessary, as mock.py might need to know the user id of the person running mock, and so it can switch back to that user for writing output files.
So, you're thinking we just to seteuid/setegid rather than setting the real uid/gid?
Clark
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Clark Williams wrote:
// elevate our privileges if (setreuid (geteuid (), geteuid ())) error("setreuid failed: %s", strerror(errno)); debug("running with uid: %d, gid: %d\n", getuid(), getgid());
Is this necessary? It seems to me like this is something that can be done in mock.py for the cases where it is necessary, as mock.py might need to know the user id of the person running mock, and so it can switch back to that user for writing output files.
So, you're thinking we just to seteuid/setegid rather than setting the real uid/gid?
Ok, I pulled out my shiny new 2nd Edition copy of "Advanced Programming in the UNIX Environment" to try jog a brain cell or three about uid/gid manipulation. Now that I reread what you said, it sounds like you want me just to leave it alone and manipulate effective uid/gid only when we need to in mock.py.
Is that a correct statement?
Clark
-----Original Message----- From: fedora-buildsys-list-bounces@redhat.com [mailto:fedora-buildsys-list-bounces@redhat.com] On Behalf Of Clark Williams Sent: Wednesday, June 14, 2006 3:12 PM To: Discussion of Fedora build system Subject: Re: First cut a new mock launcher
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Clark Williams wrote:
Ok, I pulled out my shiny new 2nd Edition copy of "Advanced Programming in the UNIX Environment" to try jog a brain cell or three about uid/gid manipulation. Now that I reread what you said, it sounds like you want me just to leave it alone and manipulate effective uid/gid only when we need to in mock.py.
Is that a correct statement?
That accurately represents the intent of my statement. -- Michael
Michael_E_Brown@Dell.com wrote:
// elevate our privileges if (setreuid (geteuid (), geteuid ())) error("setreuid failed: %s", strerror(errno)); debug("running with uid: %d, gid: %d\n", getuid(), getgid());
Is this necessary? It seems to me like this is something that can be done in mock.py for the cases where it is necessary, as mock.py might need to know the user id of the person running mock, and so it can switch back to that user for writing output files.
Another option is to pass the original user in a environment variable (like sudo does).
Clark Williams wrote:
Note that the program makes use of Linux namespaces. This *should* make our handling of mount points within the chroot (/proc, /sys, etc.) a bit easier to clean up, since when the process dies the mounts should just go away. I haven't verified this though, so caveat emptor.
Using namespaces does not relieve us of managing our mounts. For example, mock.py still needs to make sure the mounts are gone before attempting to remove a buildroot. It mainly serves as a safety net.
#ifdef USE_SELINUX // add LD_PRELOAD for our selinux lib if selinux is in use is set
I don't think the SELINUX preload needs to be done here anymore. mock.py can set it up when running mock-yum if need be.
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Mike McLean wrote:
Clark Williams wrote:
Note that the program makes use of Linux namespaces. This *should* make our handling of mount points within the chroot (/proc, /sys, etc.) a bit easier to clean up, since when the process dies the mounts should just go away. I haven't verified this though, so caveat emptor.
Using namespaces does not relieve us of managing our mounts. For example, mock.py still needs to make sure the mounts are gone before attempting to remove a buildroot. It mainly serves as a safety net.
I suppose I should have said "if the process terminates abnormally" as opposed to "when the process dies". I realize that we can't whack a directory that still has a mount on/in it and that namespaces do nothing for us there.
#ifdef USE_SELINUX // add LD_PRELOAD for our selinux lib if selinux is in use is set
I don't think the SELINUX preload needs to be done here anymore. mock.py can set it up when running mock-yum if need be.
Yeah, I meant to ask that on my original email. I didn't build the new mock.c with USE_SELINUX enabled, because I wasn't sure if we were going to need it, or if we were going to push forward with a mock SELinux policy, or something completely different. I will admit to not having paid the closest attention to all the SELinux traffic on the lists lately... :).
As I recall, we do an LD_PRELOAD of our .so before going into the chroot, so that selinux is effectively disabled in the chroot. Personally, I think that SELinux is a bit of overkill inside a chroot, but someone running at a high-security facility may feel differently.
I'm ok with letting mock.py manage the addition of LD_PRELOAD to the chroot and moving it out of the launcher. The code is only complete when you can remove no more...
Clark
mike@redhat.com (Mike McLean) writes:
Note that the program makes use of Linux namespaces. This *should* make our handling of mount points within the chroot (/proc, /sys, etc.) a bit easier to clean up, since when the process dies the mounts should just go away. I haven't verified this though, so caveat emptor.
Using namespaces does not relieve us of managing our mounts. For example, mock.py still needs to make sure the mounts are gone before attempting to remove a buildroot.
No; you can do
| $ mock foo.src.rpm | --> | - enter new namespace | - cleanup buildroot | - mount /proc + /dev/pts | - rpm -U ... + rpmbuild ... | - exit() | --> | kernel unmounts /proc + /dev/pts when last process in the newly | created namespace terminates
| $ mock bar.src.rpm | --> | - enter new namespace | - cleanup buildroot
There is no need for an explicit 'umount(2)'; you have just to make sure that no daemons or other programs are hanging around which were started during the 'rpm -U ... + rpmbuild ...' phase.
Enrico
buildsys@lists.fedoraproject.org