Samba hangs (pthread?)

Rainer Weikusat rainer.weikusat at sncag.com
Sun Jun 11 19:29:01 GMT 2006


Jeremy Allison <jra at samba.org> writes:
> On Sun, Jun 11, 2006 at 06:25:30PM +0200, Rainer Weikusat wrote:
>> For LinuxThreads (ie not NPTL) it decidedly should (and will), because
>> Samba changes its uid on oaccasion, which may result in some threads
>> running with uid 0 and some other threads with a non-priviledged one,
>> which in turn can cause the pthread sleep/ wakeup-mechanism, which
>> relies on the ability of a thread to send a signal to any other thread
>> within the same process, to fail (the signal isn't delivered to the
>> target thread due to EPERM and the sending thread "hangs", waiting for
>> some action to be taken because of the signal).
>> 
>> NPTL appears[*] to use signals for something, too, so it may be
>> affected by the same issue, considering that setuid is still not per
>> process.
>> 
>> 	[*] the code is mostly incomprehensible, due to unbounded
>> 	over-abstraction 
>> 
>> NB: This is just an issue I happen to know of. There is an easy
>> kernel-level workaround for that: allow signals among threads running
>> in the same address space.

[...]

> What kernel API should we use to ensure we can allow signals 
> between threads in the same address space ? It's ok if it's
> Linux-specific, we can add a configure test for it.

The Right Thing[tm] would be to fix the kernel, so that setuid() is
per-process and not per-thread (if this hasn't been done in the
meantime). Otherwise, I fear, its the kernel source API called patch.

This is what I am using on the embedded target (2.4 based) where this
affects me:

int bad_signal(int sig, struct siginfo *info, struct task_struct *t)
{
        return
                (!info || ((unsigned long)info != 1 && SI_FROMUSER(info)))
                && ((sig != SIGCONT) || (current->session != t->session))
                && (current->euid ^ t->suid)
                && (current->euid ^ t->uid)
                && (current->uid ^ t->suid)
                && (current->uid ^ t->uid)
                && !capable(CAP_KILL)
                && (current->active_mm != t->active_mm);
}

[.../linux/kernel/signal.c, last line]

Disclaimer: I think this is a reasonably sane thing do, considering that
the threads can likely muck with each others state at will if they
share a mm, anyway. But as I am only running this in a controlled
(single-CPU) environment, I haven't bothered to check very thoroughly
and I am decidedly not an expert for this area of the kernel.


More information about the samba-technical mailing list