public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* setpeuid(pid_t, uid_t) proposal
@ 2004-08-24  4:50 Jerry Haltom
  2004-08-24  5:58 ` Valdis.Kletnieks
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Jerry Haltom @ 2004-08-24  4:50 UTC (permalink / raw)
  To: linux-kernel

Please CC me on any responses.

Now... this is my first post to the LKML concerning anything useful or
practical, so bear with me. I'm trying my best to explain my idea. :)
Also, I'm new (very new) to kernel hacking, so I may have missed
something extremely important.

I want to propose a new base system function (and cooresponding
syscall). I am tentivly calling this function setpeuid(). The function
will be fairly simple:

Only a process with uid 0 may call it. The first argument is a process
id. The second argument is a uid. The function is effictivly the exact
same as seteuid() except that it operates on another process. Very
simple explanation, now here's why.

One of the problems that I've been presented with regularly when working
with Linux (and Unix in particular) is the lack of what other operating
systems call "impersonation". The ability of one process not running as
root to assume the identity (for a limited time) of another user ID.
Securely.

My most recent experience I've been confronted with involving this is
with Apache hosting a WebDAV server. WebDAV is sort of a remote file
system hosted through HTTP. Apache sends and receives HTTP posts, to
alter remote files. Most of you probably know this.

The problem is when accessing a multiuser WebDAV file system over HTTP,
Apache on the server must either a) run as root, or b) do some really
weird suid stuff. This is because it must have access to all files that
the requesting user would have access to. This causing a number of
problems: Apache has more access than it needs. Files are edited as
root, sometimes this doesn't work such as if those files are available
over NFS or another similar situation. Files are created as root,
probably with the wrong umask. There are a lot of problems. ;)

These problems would be solved if Apache could run as the user that was
requesting access on the server: given shared user accounts. It would
only have access to what it needs to have access to.

So, that's what's broken now. Here's the situation I'd like to be able
to put myself into.

Apache runs as a low privledge user, but can obtain the permissions of
the user that requested the service. Apache can't give itself access, so
it relies on a seperate process to do so. A request is received to
Apache. The request comes with authentication information (in a number
of forms, Basic, Kerberos (GSSAPI), CRAM, NTLM, whatever). The
authentication information is received by the Apache module that handles
the specific authentication type. This module passes the security
information to a seperate stand alone daemon, which is running as root.
This daemon is highly audited and does one purpose, and does it well.
The daemon processes the security crediantials, validates them, uses
whatever policy is neccassary to determine if the user is authorized,
and then setpeuid's the calling process (Apache). The apache module now
returns, the request proceeds. When the request is over, the process
goes back to the user it was previously (either by signaling the daemon
it is done, or calling yet another new function: resetpeuid()).

That's just one use case... there are a number of others. Such as a
secure "Run As" feature for desktop users... FTP servers, SSH could even
use it to totally remove the need for any root presence. There are a
number of possibilities. Too many to list. Use your imagination.

Anyways, the function required is pretty simple. I'd like some of you
wizzes to tell me what's wrong with my thinking.

In the mean time, I'm working on implementing this right now to see how
it goes. But this is my first actual kernel hacking, so we'll see. ;)

Thanks for your time.


Jerry Haltom <wasabi@larvalstage.net>



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: setpeuid(pid_t, uid_t) proposal
  2004-08-24  4:50 setpeuid(pid_t, uid_t) proposal Jerry Haltom
@ 2004-08-24  5:58 ` Valdis.Kletnieks
  2004-08-24  6:27   ` Jerry Haltom
  2004-08-24 13:30 ` Gianni Tedesco
  2004-08-28 19:15 ` Alan Cox
  2 siblings, 1 reply; 6+ messages in thread
From: Valdis.Kletnieks @ 2004-08-24  5:58 UTC (permalink / raw)
  To: Jerry Haltom; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1067 bytes --]

On Mon, 23 Aug 2004 23:50:05 CDT, Jerry Haltom said:

> Apache runs as a low privledge user, but can obtain the permissions of
> the user that requested the service. Apache can't give itself access, so
> it relies on a seperate process to do so. A request is received to
> Apache. The request comes with authentication information (in a number
> of forms, Basic, Kerberos (GSSAPI), CRAM, NTLM, whatever). The
> authentication information is received by the Apache module that handles
> the specific authentication type. This module passes the security
> information to a seperate stand alone daemon, which is running as root.
> This daemon is highly audited and does one purpose, and does it well.

What does this buy you that having the separate daemon just do
a fork/seteuid/exec to do the work, and passing the results back via a
Unix socket or shared mem or what-have-you?

Alternatively, what would this give you that isn't already done by
the SELinux support for cron, or Apache suexec, which already allow
"run the following in another context" functionality?

[-- Attachment #2: Type: application/pgp-signature, Size: 226 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: setpeuid(pid_t, uid_t) proposal
  2004-08-24  5:58 ` Valdis.Kletnieks
@ 2004-08-24  6:27   ` Jerry Haltom
  2004-08-24 12:01     ` Valdis.Kletnieks
  0 siblings, 1 reply; 6+ messages in thread
From: Jerry Haltom @ 2004-08-24  6:27 UTC (permalink / raw)
  To: Valdis.Kletnieks; +Cc: linux-kernel

> What does this buy you that having the separate daemon just do
> a fork/seteuid/exec to do the work, and passing the results back via a
> Unix socket or shared mem or what-have-you?

To do a seteuid the daemon would need to be root. This means it would be
processing remote information of a sensitive nature, such as Kerberos
ticket acquisition, SASL stuff, etc, as root. Something I'm trying to
avoid. It has to first determine what uid before it can call setuid and
the process of determining this uid is very sensitive in many
situations.

> Alternatively, what would this give you that isn't already done by
> the SELinux support for cron, or Apache suexec, which already allow
> "run the following in another context" functionality?

I don't know about this SELinux thing you speak of yet, I'll look into
it. Apache suexec spawns a seperate process for each individual request.
It cannot function properly with in process modules, such as mod_webdav,
mod_php, and... all the others. Being able to function in process is the
main idea behind this.


Jerry Haltom <wasabi@larvalstage.net>


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: setpeuid(pid_t, uid_t) proposal
  2004-08-24  6:27   ` Jerry Haltom
@ 2004-08-24 12:01     ` Valdis.Kletnieks
  0 siblings, 0 replies; 6+ messages in thread
From: Valdis.Kletnieks @ 2004-08-24 12:01 UTC (permalink / raw)
  To: Jerry Haltom; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 887 bytes --]

On Tue, 24 Aug 2004 01:27:50 CDT, Jerry Haltom said:
> > What does this buy you that having the separate daemon just do
> > a fork/seteuid/exec to do the work, and passing the results back via a
> > Unix socket or shared mem or what-have-you?
> 
> To do a seteuid the daemon would need to be root.

And how is this different from:

> Only a process with uid 0 may call it. The first argument is a process
> id. The second argument is a uid. The function is effictivly the exact
> same as seteuid() except that it operates on another process. Very
> simple explanation, now here's why.
.....
> Apache runs as a low privledge user, but can obtain the permissions of
> the user that requested the service. Apache can't give itself access, so
> it relies on a seperate process to do so. A request is received to

You've already stated that the separate process has to be running as root....

[-- Attachment #2: Type: application/pgp-signature, Size: 226 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: setpeuid(pid_t, uid_t) proposal
  2004-08-24  4:50 setpeuid(pid_t, uid_t) proposal Jerry Haltom
  2004-08-24  5:58 ` Valdis.Kletnieks
@ 2004-08-24 13:30 ` Gianni Tedesco
  2004-08-28 19:15 ` Alan Cox
  2 siblings, 0 replies; 6+ messages in thread
From: Gianni Tedesco @ 2004-08-24 13:30 UTC (permalink / raw)
  To: Jerry Haltom; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 813 bytes --]

On Mon, 2004-08-23 at 23:50 -0500, Jerry Haltom wrote:
> I want to propose a new base system function (and cooresponding
> syscall). I am tentivly calling this function setpeuid(). The function
> will be fairly simple:
> 
> Only a process with uid 0 may call it. The first argument is a process
> id. The second argument is a uid. The function is effictivly the exact
> same as seteuid() except that it operates on another process. Very
> simple explanation, now here's why.

LOL pid_t? What if task calling the server dies before the server calls
setpeuid()? Some other users task may now get new credentials.

-- 
// Gianni Tedesco (gianni at scaramanga dot co dot uk)
lynx --source www.scaramanga.co.uk/scaramanga.asc | gpg --import
8646BE7D: 6D9F 2287 870E A2C9 8F60 3A3C 91B5 7669 8646 BE7D

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: setpeuid(pid_t, uid_t) proposal
  2004-08-24  4:50 setpeuid(pid_t, uid_t) proposal Jerry Haltom
  2004-08-24  5:58 ` Valdis.Kletnieks
  2004-08-24 13:30 ` Gianni Tedesco
@ 2004-08-28 19:15 ` Alan Cox
  2 siblings, 0 replies; 6+ messages in thread
From: Alan Cox @ 2004-08-28 19:15 UTC (permalink / raw)
  To: Jerry Haltom; +Cc: Linux Kernel Mailing List

On Maw, 2004-08-24 at 05:50, Jerry Haltom wrote:
> One of the problems that I've been presented with regularly when working
> with Linux (and Unix in particular) is the lack of what other operating
> systems call "impersonation". The ability of one process not running as
> root to assume the identity (for a limited time) of another user ID.
> Securely.

For the file system case there is setfsuid. You can also make use
of seperate effective/real/saved uids through setreuid() and friends.
setfsuid() also addresses the other problem - if a process switches
fully to my ID then I can play with it - kill it etc.

> These problems would be solved if Apache could run as the user that was
> requesting access on the server: given shared user accounts. It would
> only have access to what it needs to have access to.

This is actually not hard to do if your server is designed to be a
little smarter. The apache model doesn't fit it well although apache
could make some use of setfsuid() as unfsd (user mode nfsd does) and it
does support doing this through suexec.

One little non-obvious trick that might make this work faster would be 
to keep track of running webdav servers for each active user and use 
a redirect from the main server to communicate with it, and when the 
client has idled out to reclaim it and hand the port back to the main
server instance so that users get redirected again

> That's just one use case... there are a number of others. Such as a
> secure "Run As" feature for desktop users... FTP servers, SSH could even
> use it to totally remove the need for any root presence. There are a
> number of possibilities. Too many to list. Use your imagination.

sshd can already do this. The "run as root" desktop feature already
exists using the existing auth functionality (see "usermode")

> Anyways, the function required is pretty simple. I'd like some of you
> wizzes to tell me what's wrong with my thinking.

Actually its easy to implement and horrible to get right - there is no
locking on uid changes. When a task is in a syscall the entire syscall
knows that the security for the process will not be changing.

> In the mean time, I'm working on implementing this right now to see how
> it goes. But this is my first actual kernel hacking, so we'll see. ;)

Have fun - the security stuff is hard but getting something working as
you describe for learning purposes and armwaving that issue should be
nice little project.

Alan


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2004-08-28 20:37 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-08-24  4:50 setpeuid(pid_t, uid_t) proposal Jerry Haltom
2004-08-24  5:58 ` Valdis.Kletnieks
2004-08-24  6:27   ` Jerry Haltom
2004-08-24 12:01     ` Valdis.Kletnieks
2004-08-24 13:30 ` Gianni Tedesco
2004-08-28 19:15 ` Alan Cox

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox