LinuxQuestions.org
Did you know LQ has a Linux Hardware Compatibility List?
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 08-18-2010, 07:55 AM   #1
thelogix
LQ Newbie
 
Registered: Aug 2010
Posts: 6

Rep: Reputation: 0
Lightbulb setuid on different pid or child-process


Hia all.

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.)
 
Old 08-18-2010, 12:34 PM   #2
unSpawn
Moderator
 
Registered: May 2001
Posts: 27,369
Blog Entries: 54

Rep: Reputation: 2870Reputation: 2870Reputation: 2870Reputation: 2870Reputation: 2870Reputation: 2870Reputation: 2870Reputation: 2870Reputation: 2870Reputation: 2870Reputation: 2870
Quote:
Originally Posted by thelogix View Post
(..) 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.
 
Old 08-18-2010, 12:38 PM   #3
wje_lq
Member
 
Registered: Sep 2007
Location: Mariposa
Distribution: Debian lenny, Slackware 12
Posts: 808

Rep: Reputation: 178Reputation: 178
Quote:
Originally Posted by thelogix View Post
Is there some way to do a setuid() on another pid? or maybe something can be done through /proc/<pid>/?

Any idea's?
Absolutely none (other than losing the gratuitous apostrophe). Can't be done.
 
Old 08-19-2010, 08:10 AM   #4
thelogix
LQ Newbie
 
Registered: Aug 2010
Posts: 6

Original Poster
Rep: Reputation: 0
Smile

Quote:
Originally Posted by unSpawn View Post
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
 
Old 08-19-2010, 09:49 AM   #5
wje_lq
Member
 
Registered: Sep 2007
Location: Mariposa
Distribution: Debian lenny, Slackware 12
Posts: 808

Rep: Reputation: 178Reputation: 178
Quote:
Originally Posted by thelogix View Post
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.

What am I missing?
 
Old 08-20-2010, 06:42 AM   #6
thelogix
LQ Newbie
 
Registered: Aug 2010
Posts: 6

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by wje_lq View Post
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
 
Old 08-20-2010, 10:30 AM   #7
estabroo
Senior Member
 
Registered: Jun 2008
Distribution: debian, ubuntu, sidux
Posts: 1,094
Blog Entries: 2

Rep: Reputation: 111Reputation: 111
Instead of using setuid how about using seteuid. This would reduce the privs but still allow the process to use seteuid again to regain full privs.

Code:
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>

int main(int argc, char* argv[]) {
        int err;
        int fd;
        err = seteuid(1000);

        fd = open ("/tmp/test1", O_RDWR|O_CREAT, 0600);
        write(fd, "test\n", 5);
        close(fd);
        seteuid(0);
        fd = open ("/tmp/test2", O_RDWR|O_CREAT, 0600);
        write(fd, "test\n", 5);
        close(fd);
}

Last edited by estabroo; 08-20-2010 at 10:31 AM. Reason: added example
 
1 members found this post helpful.
Old 08-21-2010, 05:13 AM   #8
thelogix
LQ Newbie
 
Registered: Aug 2010
Posts: 6

Original Poster
Rep: Reputation: 0
estabroo:

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)?
 
Old 08-21-2010, 08:50 AM   #9
estabroo
Senior Member
 
Registered: Jun 2008
Distribution: debian, ubuntu, sidux
Posts: 1,094
Blog Entries: 2

Rep: Reputation: 111Reputation: 111
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
 
Old 08-25-2010, 08:13 PM   #10
estabroo
Senior Member
 
Registered: Jun 2008
Distribution: debian, ubuntu, sidux
Posts: 1,094
Blog Entries: 2

Rep: Reputation: 111Reputation: 111
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.
 
Old 08-26-2010, 05:29 AM   #11
thelogix
LQ Newbie
 
Registered: Aug 2010
Posts: 6

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by estabroo View Post
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.

Great find estabroo.. Ill look into it.
 
Old 08-26-2010, 06:32 PM   #12
estabroo
Senior Member
 
Registered: Jun 2008
Distribution: debian, ubuntu, sidux
Posts: 1,094
Blog Entries: 2

Rep: Reputation: 111Reputation: 111
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.
 
  


Reply

Tags
cpp, linux, setuid


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Under which circumstances a child process creates another child process using fork? mitsulas Programming 3 12-08-2009 08:16 AM
Kill child process problem. No matter what i try cant stop pid becoming a zombie?? ajb181 Linux - Software 1 11-15-2009 05:36 PM
bash setuid child proccess RGummi Linux - General 4 03-25-2008 05:24 PM
How to kill a Child and all its subsequent child process in C shayer009 Programming 3 12-04-2007 12:40 AM
get the PID of a separate process (no parent-child relationship) arunj Linux - Software 6 02-03-2006 01:50 AM


All times are GMT -5. The time now is 09:35 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration