2002-02-14 15:52:23

by bert hubert

[permalink] [raw]
Subject: setuid/pthread interaction broken? 'clone_with_uid()?'

When a process first issues setuid() and then goes on to create threads,
those threads run under the setuid() uid - all is well.

However, once the first thread is created, only the thread calling setuid()
gets setuid in fact. All new threads continue to be created as root.

This behaviour exists under 2.2.18 with glibc 2.1.3 and under 2.4.17 with
glibc 2.2.5, and is shown using the brief program attached.

Is this by design? It appears that all threads created get the uid of the
thread manager process.

>From our standpoint as an application developer, this is nasty. It means
that we have to do everything that needs root before creating the first
thread. This behaviour is also highly non obvious.

A fix would appear to need a 'clone with uid' syscall, other solutions will
probably cause race condition.

Regards,

bert

--
http://www.PowerDNS.com Versatile DNS Software & Services
http://www.tk the dot in .tk
Netherlabs BV / Rent-a-Nerd.nl - Nerd Available -
Linux Advanced Routing & Traffic Control: http://ds9a.nl/lartc


Attachments:
(No filename) (1.06 kB)
testcase.c (805.00 B)
Download all attachments

2002-02-14 16:01:23

by Dave McCracken

[permalink] [raw]
Subject: Re: setuid/pthread interaction broken? 'clone_with_uid()?'


--On Thursday, February 14, 2002 16:51:43 +0100 bert hubert <[email protected]>
wrote:

> When a process first issues setuid() and then goes on to create threads,
> those threads run under the setuid() uid - all is well.
>
> However, once the first thread is created, only the thread calling
> setuid() gets setuid in fact. All new threads continue to be created as
> root.
>
> This behaviour exists under 2.2.18 with glibc 2.1.3 and under 2.4.17 with
> glibc 2.2.5, and is shown using the brief program attached.
>
> Is this by design? It appears that all threads created get the uid of the
> thread manager process.

It's the expected behavior for a task-based model like Linux. Each task is
independent and inherits the uid/gid from whoever called clone(). It's
just one of several resources that are specified as process-wide in POSIX,
but are per-task in Linux.

I've been working on a patch to allow clone() to specify shared
credentials, but it's been on the back burner.

Dave McCracken

======================================================================
Dave McCracken IBM Linux Base Kernel Team 1-512-838-3059
[email protected] T/L 678-3059

2002-02-14 16:08:23

by bert hubert

[permalink] [raw]
Subject: Re: setuid/pthread interaction broken? 'clone_with_uid()?'

On Thu, Feb 14, 2002 at 04:03:47PM +0000, Dave McCracken wrote:

> It's the expected behavior for a task-based model like Linux. Each task is
> independent and inherits the uid/gid from whoever called clone(). It's
> just one of several resources that are specified as process-wide in POSIX,
> but are per-task in Linux.

Could this also be solved by making threads call 'clone' themselves?

> I've been working on a patch to allow clone() to specify shared
> credentials, but it's been on the back burner.

Would be much appreciated.

Regards,

bert hubert

--
http://www.PowerDNS.com Versatile DNS Software & Services
http://www.tk the dot in .tk
Netherlabs BV / Rent-a-Nerd.nl - Nerd Available -
Linux Advanced Routing & Traffic Control: http://ds9a.nl/lartc

2002-02-14 16:20:05

by Dave McCracken

[permalink] [raw]
Subject: Re: setuid/pthread interaction broken? 'clone_with_uid()?'


--On Thursday, February 14, 2002 17:07:48 +0100 bert hubert <[email protected]>
wrote:

>> It's the expected behavior for a task-based model like Linux. Each task
>> is independent and inherits the uid/gid from whoever called clone().
>> It's just one of several resources that are specified as process-wide in
>> POSIX, but are per-task in Linux.
>
> Could this also be solved by making threads call 'clone' themselves?

The only workaround I can think of is, as you discovered, to do the
setuid() call before you create any threads, and thus create underlying
kernel tasks. Once the kernel tasks have been created each one has its own
credentials and has to be changed separately.

Dave McCracken

======================================================================
Dave McCracken IBM Linux Base Kernel Team 1-512-838-3059
[email protected] T/L 678-3059

2002-02-14 17:05:36

by bert hubert

[permalink] [raw]
Subject: Re: setuid/pthread interaction broken? 'clone_with_uid()?'

On Thu, Feb 14, 2002 at 04:21:52PM +0000, Dave McCracken wrote:

> The only workaround I can think of is, as you discovered, to do the
> setuid() call before you create any threads, and thus create underlying
> kernel tasks. Once the kernel tasks have been created each one has its own
> credentials and has to be changed separately.

I'm wondering what the right semantics are. POSIX is one thing, but having
the ability to have threads with different uids in one VM would have its
uses too.

Regards,

bert

--
http://www.PowerDNS.com Versatile DNS Software & Services
http://www.tk the dot in .tk
Netherlabs BV / Rent-a-Nerd.nl - Nerd Available -
Linux Advanced Routing & Traffic Control: http://ds9a.nl/lartc

2002-02-14 17:14:47

by Dave McCracken

[permalink] [raw]
Subject: Re: setuid/pthread interaction broken? 'clone_with_uid()?'


--On Thursday, February 14, 2002 18:05:07 +0100 bert hubert <[email protected]>
wrote:

> I'm wondering what the right semantics are. POSIX is one thing, but having
> the ability to have threads with different uids in one VM would have its
> uses too.

That's the idea behind the patch I've been working on. It would be an
option to clone(), just like sharing address space, signals, and files.
The pthread libraries could turn it on for POSIX behavior, and programs
that wanted something different could call clone() with their own flags.

Dave McCracken

======================================================================
Dave McCracken IBM Linux Base Kernel Team 1-512-838-3059
[email protected] T/L 678-3059