Patchset to add asynchronous open/close to master

Jeremy Allison jra at samba.org
Wed Jun 20 18:25:33 MDT 2012


On Wed, Jun 20, 2012 at 03:47:13PM -0700, Jeremy Allison wrote:
> 
> PS. There is an *evil* Linux-specific
> way to cause the uid of the async open
> thread to be pinned to the initial uid
> it was invoked as, but I really don't
> want to have to use that :-). Still it's
> available..

I've been doing more research on this, and
at least on Linux all the checks may be
completely redundent, and we may not be
hitting the uid-change/root race issue
at *ALL* in the aio open code.

Here's a note from tridge's junk code
aio_uid.c, developed to test an issue
with the glibc pthread-based aio implementation
and Samba.

Read the following :

/*
  test program to demonstrate race between AIO and setresuid()

  tridge at samba.org August 2008

  The race condition is in setresuid(), which in glibc tries to be
  smart about threads and change the euid of threads when the euid of
  the main program changes. The problem is that this makes setresuid()
  non-atomic, which means that if an IO completes during the complex
  series of system calls that setresuid() becomes, then the thread
  completing the IO may get -1/EPERM back from the rt_sigqueueinfo()
  call that it uses to notify its parent of the completing IO. In that
  case two things happen:

    1) the signal is never delivered, so the caller never is told that
    the IO has completed

    2) if the caller polls for completion using aio_error() then it
    will see a -1/EPERM result, rather than the real result of the IO

  The simplest fix in existing code that mixes uid changing with AIO
  (such as Samba) is to not use setresuid() and use setreuid()
  instead, which in glibc doesn't try to play any games with the euid
  of threads. That does mean that you will need to manually gain root
  privileges before calling aio_read() or aio_write() to ensure that
  the thread has permission to send signals to the main thread
 */

And lo and behold, look inside modules/vfs_default.c at
aio_read().

        /*
         * aio_read must be done as root, because in the glibc aio
         * implementation the helper thread needs to be able to send a signal
         * to the main thread, even when it has done a seteuid() to a
         * different user.
         */
        become_root();
        ret = sys_aio_read(aiocb);
        unbecome_root();

What this means is that WE ALREADY DEPEND (at least on Linux)
on pthreads having a different effective uid from their parent
thread, and deliberately select USE_SETREUID in our waf and
autoconf configure tests on Linux, as using that function 
doesn't change the euid or egid of Linux spawned pthreads :-).

So if this is true, I can make the aio_open call be a Linux-only
part of the module, and just remove the fixup code as the spawned
thread can never be raced :-). I'm ok with that BTW (Linux is
our primary platform after all).

I'll do some more investigation. But watch this space.. :-).

Jeremy.


More information about the samba-technical mailing list