ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
I have a root process (on linux) that forks a child and the child process then drops privileges by doing a setuid() to a normal user.
After the child setuid()'s, it is of course impossible for it to gain root again by itself. But since the main process is still running as root, i was wondering if there was a simple/smart way of getting the root-master-process to elevate the child back to root (or maybe just to another non-privi uid).
Is there some way to do a setuid() on another pid? or maybe something can be done through /proc/<pid>/?
Any idea's?
Killing the child is not an option (because its what it does today and im trying to find a smarter way).
(The program is apache2's mpm-itk worker and the "child" is the actual apache2 process serving a page.)
(..) since the main process is still running as root, i was wondering if there was a (..) way (..) to elevate the child back to root (..) The program is apache2's mpm-itk worker and the "child" is the actual apache2 process (..)
In this specific case understanding the reasons why privileges are separated between the root-owned master and unprivileged children should show you the question is not about a "simple/smart way" of doing things but doing things the right or the wrong way. Unless you're smarter than the Apache devs of course.
In this specific case understanding the reasons why privileges are separated between the root-owned master and unprivileged children should show you the question is not about a "simple/smart way" of doing things but doing things the right or the wrong way. Unless you're smarter than the Apache devs of course.
Apparently you dont know what mpm-itk is. (Which is not made by the Apache devs, of course.)
I understand all the reasons perfectly. This was not a "please-explain-to me-the-basics-of-privilege-separation"-post and im sorry if the post title gave you that idea. Ill post that question in the "Linux - Newbie" forum if i ever need your guidance on that
Apparently you dont know what mpm-itk is. (Which is not made by the Apache devs, of course.)
I didn't know what it was until you mentioned its name, but I just googled it, and, um, it seems to be a short name for apache2-mpm-itk. I found this, and I would assume that it's brought to us by the Apache developers.
I didn't know what it was until you mentioned its name, but I just googled it, and, um, it seems to be a short name for apache2-mpm-itk. I found this, and I would assume that it's brought to us by the Apache developers.
Well.. I guess that depends on the definition of an Apache Developer. I have patches in the official linux-kernel, but that doesnt really make me a "Kernel Developer". .
(Of course, for the purpose of my post, it was irrelevant what product it was for and i added simply because it is polite to do so )
mpm-itk however, is an third-party, experimental, MPM module and it is pretty widely used around the globe.
(More about MPM's here: http://httpd.apache.org/docs/2.0/mpm.html)
mpm-itk is (yet-another) attempt to solve the issues that arise, due to apache2 running everything under one user (ie. on debian, user "www-data").
It does so, by running as root and upon receiving the "Host: " header with the hostname of the site, it looks in the config to find what username to setuid to for that specific host.
So basically isolating each website to one specific user (usually the same as the FTP user for the site).
Works pretty well, but there is a known caveat, which is (so far) unsolved. If you try to get a page from a different hostname on the SAME TCP connection, the process wont have access to the other users pages. So far, the solution is to kill the child, having the client (browser) simply reconnect. This is, of course, not very fast on very busy sites.
So im just investigating 2 different routes around this. The one here, is the idea of having the master (root owned) process, grant the child a new setuid() to a different user.
The other is handing over existing connections between childs, which im told is rather hairy. But so is my setuid() idea, it would seem
Thanks for the idea. Though it would actually work, it defeats the purpose i think, to allow the process itself to regain root. Also, wouldn't any child of this process also be able to seteuid(0)?
any child process that you didn't explicity set the real user id on would be able to seteuid(0), but you could set that id after a fork and before exec'ing mitigating most of the risk
Last edited by estabroo; 08-21-2010 at 08:52 AM.
Reason: coherency
ran across something interesting today in line with this question. You might be able to do exactly what you what using a couple of deprecated functions and capabilities (depends on what your kernel is setup for)
capgetp and capsetp are for getting and setting various capabilities on other processes, so you could give them what they would need to do what you want, CAP_SETUID in particular for just allowing them to change their uid.
ran across something interesting today in line ....
capgetp and capsetp are for getting and setting various capabilities on other processes, so you could give them what they would need to do what you want, CAP_SETUID in particular for just allowing them to change their uid.
That is actually VERY interesting. Almost excactly what i was hoping for.. Though, when you call them "deprecated" it does send a small chill down my spine. Are you certain they are deprecated?
Also, this does gives rise to an alternative idea. If its all a question of temporarily granting CAP_SETUID it might be possible to make an LSM module for the kernel, or even a patch to AppArmor, that allows a single process to grant & revoke capabillities on other processes.
pretty sure. excerpt from the cap_get_proc man page
NOTES
The library also supports the deprecated functions:
int capgetp(pid_t pid, cap_t cap_d);
int capsetp(pid_t pid, cap_t cap_d);
capgetp() attempts to obtain the capabilities of some other process; storing the capabilities in a
pre-allocated cap_d.See cap_init() for information on allocating an empty capability set. This
function, capgetp(), is deprecated, you should use cap_get_pid().
capsetp() attempts to set the capabilities of some other process(es), pid. If pid is positive it
refers to a specific process; if it is zero, it refers to the current process; -1 refers to all
processes other than the current process and process '1' (typically init(8)); other negative val-
ues refer to the -pid process group. In order to use this function, the kernel must support it
and the current process must have CAP_SETPCAP raised in its Effective capability set. The capabil-
ities set in the target process(es) are those contained in cap_d.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.