From: Rob L. <ro...@la...> - 2005-04-20 11:09:08
|
http://www.landley.net/code/firmware/notes.html It's a ~80 meg tarball (half of which is the gcc, binutils, and linux-2.6.11 source tarballs) on a friend's machine, so don't hit the poor server too hard. I intend to move it to a faster connection after I get back from Penguicon... Yeah, I know the versions of most things are out of date, but the build worked when I ran it, and as a proof of concept it shows you what I did. By the way, I've toyed with the idea of running this sucker in an otherwise empty chroot environment (/proc/self/fd is likely to exist and have fairly uninteresting contents. As a chroot environment, it just has symlinks that point to nothing), but to chroot the UML kernel process from inside the initramfs, I need to come up with a new syscall. Can't do it before running the UML kernel because A) it needs to make its memory file, 2) it needs to access /proc/self/exe, III) it needs to loopback mount its executable file to pull the trick I just did. Does a new "chroot UML" syscall sound like a worthwhile idea? Rob |
From: Blaisorblade <bla...@ya...> - 2005-04-24 14:12:21
|
On Wednesday 20 April 2005 12:06, Rob Landley wrote: > http://www.landley.net/code/firmware/notes.html > > It's a ~80 meg tarball (half of which is the gcc, binutils, and > linux-2.6.11 source tarballs) on a friend's machine, so don't hit the poor > server too hard. I intend to move it to a faster connection after I get > back from Penguicon... > > Yeah, I know the versions of most things are out of date, but the build > worked when I ran it, and as a proof of concept it shows you what I did. > > By the way, I've toyed with the idea of running this sucker in an otherwise > empty chroot environment (/proc/self/fd is likely to exist and have fairly > uninteresting contents. As a chroot environment, it just has symlinks that > point to nothing), but to chroot the UML kernel process from inside the > initramfs, I need to come up with a new syscall. Ok, I now understand... chrooting it on the host! > Can't do it before > running the UML kernel because A) it needs to make its memory file, 2) it > needs to access /proc/self/exe, III) it needs to loopback mount its > executable file to pull the trick I just did. Not sure about this... you'll need to be root anyway to chroot, so you can also (bind)mount what you need inside the chroot and unmount it later. You still need to ask UML to do this, yes, but it's different (also you could even provide a simple module to load to do this, if the other ideas are rejected at any level). > Does a new "chroot UML" syscall sound like a worthwhile idea? A "chroot UML" thing would not be bad, but doing it as a syscall is not very Ok for me*... Better, do it with a /proc entry. Not exactly like /proc/sysemu, however - that was (initially) for testing only and it pollutes the namespace. However, I don't know a better place where to put it (no sysfs please, we don't want to learn kobjects for this :-) ). Also, you can't read the value ("echo a > /proc/chroot; echo a > /proc/chroot" will be equivalent to "echo a/a > /proc/chroot", since you can't chroot *outside*; if you want that "echo a > /proc/chroot; echo > /proc/chroot" does not mean "chroot inside and then go back outside", that's the only possible interpretation). A sysctl is not ok because it's supposed that the value it's "saved" in the entry, while this is not true. Also, we already have /proc/umid and /proc/exitcode which act on the outside, so it would probably be ok. * A syscall is not ok because the syscall table must match the i386 (and whatever arch) one; we can't add "local" entries as we may need to move their number to give place for new i386 syscalls. And asking all other archs to reserve a slot for a syscall on which at least somebody will seriously object won't work. -- Paolo Giarrusso, aka Blaisorblade Linux registered user n. 292729 http://www.user-mode-linux.org/~blaisorblade |
From: Henrik N. <um...@hn...> - 2005-04-24 23:21:16
|
On Wed, 20 Apr 2005, Rob Landley wrote: > By the way, I've toyed with the idea of running this sucker in an otherwise > empty chroot environment (/proc/self/fd is likely to exist and have fairly > uninteresting contents. As a chroot environment, it just has symlinks that > point to nothing), but to chroot the UML kernel process from inside the > initramfs, I need to come up with a new syscall. Not neccesarily. All you need is a way of making the UML execute the chroot syscall. This can be easily be done by loading a module, or even linking a dummy object file with just a kernel init function making the chroot call if it is not sensitive when in the kernel boot process this takes place. > Can't do it before running the UML kernel because A) it needs to make > its memory file, 2) it needs to access /proc/self/exe, III) it needs to > loopback mount its executable file to pull the trick I just did. Ok, then the module approach is the simplest. > Does a new "chroot UML" syscall sound like a worthwhile idea? IMHO a syscall is overkill for this. Regards Henrik |
From: Rob L. <ro...@la...> - 2005-04-27 02:27:29
|
On Saturday 23 April 2005 08:57 am, Blaisorblade wrote: > > By the way, I've toyed with the idea of running this sucker in an > > otherwise empty chroot environment (/proc/self/fd is likely to exist and > > have fairly uninteresting contents. As a chroot environment, it just has > > symlinks that point to nothing), but to chroot the UML kernel process > > from inside the initramfs, I need to come up with a new syscall. > > Ok, I now understand... chrooting it on the host! Yup. > > Can't do it before > > running the UML kernel because A) it needs to make its memory file, 2) it > > needs to access /proc/self/exe, III) it needs to loopback mount its > > executable file to pull the trick I just did. > > Not sure about this... you'll need to be root anyway to chroot, so you can > also (bind)mount what you need inside the chroot and unmount it later. Hmmm. You're right, that's sucks. I've also been thinking about some kind of wrapper that would be root, set up the environment, and run UML as a non-priviledged child process. Working out the details is a bit tough, though... > You > still need to ask UML to do this, yes, but it's different (also you could > even provide a simple module to load to do this, if the other ideas are > rejected at any level). Hmmm... I suppose I could always have a wrapper script that runs UML as a non-root process in the chroot environment and opens a named pipe that we can write into via hostfs when we want the chroot environment depopulated. (I vaguely recall there's a way to tell UML where to drop its memory file...) Better not to modify UML at all, if possible... Rob |
From: Blaisorblade <bla...@ya...> - 2005-04-28 18:08:32
|
On Wednesday 27 April 2005 03:23, Rob Landley wrote: > On Saturday 23 April 2005 08:57 am, Blaisorblade wrote: > > > Can't do it before > > > running the UML kernel because A) it needs to make its memory file, 2) > > > it needs to access /proc/self/exe, III) it needs to loopback mount its > > > executable file to pull the trick I just did. > > > > Not sure about this... you'll need to be root anyway to chroot, so you > > can also (bind)mount what you need inside the chroot and unmount it > > later. > Hmmm. You're right, that's sucks. > I've also been thinking about some kind of wrapper that would be root, set > up the environment, and run UML as a non-priviledged child process. > Working out the details is a bit tough, though... > > > You > > still need to ask UML to do this, yes, but it's different (also you could > > even provide a simple module to load to do this, if the other ideas are > > rejected at any level). > > Hmmm... I suppose I could always have a wrapper script which can't be setuid if in bash, could if in Perl and perlsuid is installed. > that runs UML as a > non-root process in the chroot environment and opens a named pipe that we > can write into via hostfs when we want the chroot environment depopulated. No, that must be a regular file... Linux does not pass requests to work on device nodes, named pipes, sockets down to the filesystem, so none of them can pass datas between the machines. You'd need a real IP socket (TCP/UDP),, or maybe something mconsole-based. You can pass the location through a normal assignment on the cmd.line (which will become a env.var, or you might parse /proc/cmdline). > (I vaguely recall there's a way to tell UML where to drop its memory > file...) Setting TMPDIR. > Better not to modify UML at all, if possible... > > Rob -- Paolo Giarrusso, aka Blaisorblade Skype user "PaoloGiarrusso" Linux registered user n. 292729 http://www.user-mode-linux.org/~blaisorblade |
From: Rob L. <ro...@la...> - 2005-04-29 00:42:12
|
On Friday 29 April 2005 03:16 pm, Blaisorblade wrote: > > Hmmm... I suppose I could always have a wrapper script > > which can't be setuid if in bash, could if in Perl and perlsuid is > installed. Actually you can run bash setuid with the -p option. From bash's "flags.c": /* Non-zero means that this shell is running in `privileged' mode. This is required if the shell is to run setuid. If the `-p' option is not supplied at startup, and the real and effective uids or gids differ, disable_priv_mode is called to relinquish setuid status. */ int privileged_mode = 0; (That said, if you do use -p to get get a setuid bash, there's several other things you should do to make this marginally less dangerous. And I wouldn't trust myself to remember them all off the top of my head...) That said, I wasn't thinking of using bash for the wrapper but either python or C. It's just easier to secure them... > > that runs UML as a > > non-root process in the chroot environment and opens a named pipe that we > > can write into via hostfs when we want the chroot environment > > depopulated. > > No, that must be a regular file... Linux does not pass requests to work on > device nodes, named pipes, sockets down to the filesystem, so none of them > can pass datas between the machines. You'd need a real IP socket > (TCP/UDP),, or maybe something mconsole-based. Okay, the disgusting way to do this: Mount a ramfs somewhere. CD into it, make subdirectories and bind mount in enough of the parent environment to run UML and open the memory file. Run UML. Have UML create a new file in the ramfs to signal when it's up enough that the host filesystem can go away. The parent program detects the file's creation, unmounts all the directories, deletes the empty directories, remounts the ramfs read-only, and then does a lazy unmount of the ramfs. I can come up with a _more_ disgusting way to do this if necessary. :) > You can pass the location through a normal assignment on the cmd.line > (which will become a env.var, or you might parse /proc/cmdline). Creating a temporary file in the ramfs is good enough... > > (I vaguely recall there's a way to tell UML where to drop its memory > > file...) > > Setting TMPDIR. Cool. Rob |
From: Blaisorblade <bla...@ya...> - 2005-05-01 10:56:12
|
On Friday 29 April 2005 01:38, Rob Landley wrote: > On Friday 29 April 2005 03:16 pm, Blaisorblade wrote: > > > Hmmm... I suppose I could always have a wrapper script > > > > which can't be setuid if in bash, could if in Perl and perlsuid is > > installed. > > Actually you can run bash setuid with the -p option. From bash's > "flags.c": > > /* Non-zero means that this shell is running in `privileged' mode. This > is required if the shell is to run setuid. If the `-p' option is > not supplied at startup, and the real and effective uids or gids > differ, disable_priv_mode is called to relinquish setuid status. */ > int privileged_mode = 0; > > (That said, if you do use -p to get get a setuid bash, there's several > other things you should do to make this marginally less dangerous. And I > wouldn't trust myself to remember them all off the top of my head...) No, I'm not saying that a setuid bash won't work because of the bash special code. I'm saying that setuid script plain don't work (the kernel ignores the setuid bit). Except for perl, which has a special mechanism to make them work anyway. > That said, I wasn't thinking of using bash for the wrapper but either > python or C. It's just easier to secure them... Ok, for C no problem. No idea if python supports a similar trick. > Okay, the disgusting way to do this: > > Mount a ramfs somewhere. CD into it, make subdirectories and bind mount in > enough of the parent environment to run UML and open the memory file. Run > UML. Have UML create a new file in the ramfs to signal when it's up enough > that the host filesystem can go away. The parent program detects the > file's creation, unmounts all the directories, deletes the empty > directories, remounts the ramfs read-only, and then does a lazy unmount of > the ramfs. > > I can come up with a _more_ disgusting way to do this if necessary. :) No, I don't even think _this_ way is disgusting. It's nice IMHO. -- Paolo Giarrusso, aka Blaisorblade Skype user "PaoloGiarrusso" Linux registered user n. 292729 http://www.user-mode-linux.org/~blaisorblade |
From: Rob L. <ro...@la...> - 2005-05-02 06:17:49
|
On Sunday 01 May 2005 07:06 am, Blaisorblade wrote: > > (That said, if you do use -p to get get a setuid bash, there's several > > other things you should do to make this marginally less dangerous. And I > > wouldn't trust myself to remember them all off the top of my head...) > > No, I'm not saying that a setuid bash won't work because of the bash > special code. > > I'm saying that setuid script plain don't work (the kernel ignores the > setuid bit). Except for perl, which has a special mechanism to make them > work anyway. I got this to work once, a few years back (under an early 2.4 kernel). The setuid bit wasn't on the bash executable (that would be insane), it was on the script. I don't remember the details (it was a few years ago now) but at one point it was possible. I vaguely remember tracing through both bash and the kernel code to see what the heck it was actually doing, and I think there was something funky and non-obvious about permissions, or some such... And if the perl executable isn't itself suid, then what special mechanism can the perl executable have to execute stuff as root if the kernel isn't passing it root access when you run the script? This "special mechanism" would either have to be the suid bit on the perl executable (which my /usr/bin/perl hasn't got) or some mechanism for cracking root access as a normal user, doesn't it? No, if I remember correctly bash was the problem, in the same holier than thou "we are the FSF, we know better than you because you are dumb and we must protect you from yourself" way that gcc's collect2 won't search the path for ld if the $PATH has "." in it (even at the end), which is the default path in UML by the way. (That took a while to track down...) > > That said, I wasn't thinking of using bash for the wrapper but either > > python or C. It's just easier to secure them... > > Ok, for C no problem. No idea if python supports a similar trick. I got that to work once too. I vaguely recall I had to specify -E, and possibly some other stuff... Rob |
From: Blaisorblade <bla...@ya...> - 2005-05-02 19:37:48
|
On Monday 02 May 2005 07:14, Rob Landley wrote: > On Sunday 01 May 2005 07:06 am, Blaisorblade wrote: > > > (That said, if you do use -p to get get a setuid bash, there's several > > > other things you should do to make this marginally less dangerous. And > > > I wouldn't trust myself to remember them all off the top of my head...) > > No, I'm not saying that a setuid bash won't work because of the bash > > special code. > > I'm saying that setuid script plain don't work (the kernel ignores the > > setuid bit). Except for perl, which has a special mechanism to make them > > work anyway. > I got this to work once, a few years back (under an early 2.4 kernel). The > setuid bit wasn't on the bash executable (that would be insane), it was on > the script. > I don't remember the details (it was a few years ago now) but at one point > it was possible. I vaguely remember tracing through both bash and the > kernel code to see what the heck it was actually doing, and I think there > was something funky and non-obvious about permissions, or some such... > And if the perl executable isn't itself suid, then what special mechanism > can the perl executable have to execute stuff as root if the kernel isn't > passing it root access when you run the script? This "special mechanism" > would either have to be the suid bit on the perl executable (which my > /usr/bin/perl hasn't got) or some mechanism for cracking root access as a > normal user, doesn't it? This mechanism involves having the setuid bit set on /usr/bin/suidperl. Though it's documented in man perl<Something>, here's the basics: *) the kernel can't allow a setuid script to work. There's an inherent race condition: fork(), execve() the script, the kernel runs the shell with id = 0, you modify the file to be nasty and it loses its setuid bit, but still the shell is going to open and execute it. *) perl checks if the script is setuid, and if suidperl is installed, it avoids the problem (probably by copying the source somewhere where it can't be modified, or something smarter, I don't know). > No, if I remember correctly bash was the problem, in the same holier than > thou "we are the FSF, we know better than you because you are dumb and we > must protect you from yourself" way that gcc's collect2 won't search the > path for ld if the $PATH has "." in it (even at the end), > which is the > default path in UML by the way. Sorry, what you mean here? It's the default PATH in your guest image or there is actually something in UML leading to that (which would be a bug?). > (That took a while to track down...) Ah, I remember your very early message "gcc does not find LD, I can find it by hand and it's in the PATH". > I got that to work once too. I vaguely recall I had to specify -E Ignore env. vars such as PYTHONPATH... makes sense to avoid exploits. > , and > possibly some other stuff... -- Paolo Giarrusso, aka Blaisorblade Skype user "PaoloGiarrusso" Linux registered user n. 292729 http://www.user-mode-linux.org/~blaisorblade |