From: Andrew Tridgell Date: Sun, 24 Aug 2008 03:56:59 +0000 (+1000) Subject: Avoid a race condition in glibc between AIO and setresuid(). X-Git-Tag: samba-4.0.0alpha6~801^2~202^2~8 X-Git-Url: http://git.samba.org/?p=samba.git;a=commitdiff_plain;h=d9f61dbdc91fae6560361f98d981b1f7bea80422;hp=52c39dd55d0a3eda3e9ed9a0981f546ca7b88cff Avoid a race condition in glibc between AIO and setresuid(). See this test: http://samba.org/~tridge/junkcode/aio_uid.c The problem is that setresuid() tries to be clever about threads, and tries to change the euid of any threads that are running. If a AIO read or write completes while this is going on then the signal from the thread where the IO completed is lost, as it gets -1/EPERM from rt_sigqueueinfo() The simplest fix is to try to use setreuid() instead of setresuid(), as setreuid() doesn't try to be clever. Unfortunately this also means we must use become_root()/unbecome_root() in the aio code. (This used to be commit 56c5a6f024875bb79b0104beb36f6b0ec1e1e9f9) --- diff --git a/source3/configure.in b/source3/configure.in index 5508d9b01d5..9436fed1fff 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -2627,30 +2627,32 @@ AC_CHECK_FUNCS(getpagesize) ################################################ # look for a method of setting the effective uid seteuid=no; + if test $seteuid = no; then -AC_CACHE_CHECK([for setresuid],samba_cv_USE_SETRESUID,[ +AC_CACHE_CHECK([for setreuid],samba_cv_USE_SETREUID,[ AC_TRY_RUN([ #define AUTOCONF_TEST 1 -#define USE_SETRESUID 1 +#define USE_SETREUID 1 #include "confdefs.h" #include "${srcdir-.}/lib/util_sec.c"], - samba_cv_USE_SETRESUID=yes,samba_cv_USE_SETRESUID=no,samba_cv_USE_SETRESUID=cross)]) -if test x"$samba_cv_USE_SETRESUID" = x"yes"; then - seteuid=yes;AC_DEFINE(USE_SETRESUID,1,[Whether setresuid() is available]) + samba_cv_USE_SETREUID=yes,samba_cv_USE_SETREUID=no,samba_cv_USE_SETREUID=cross)]) +if test x"$samba_cv_USE_SETREUID" = x"yes"; then + seteuid=yes;AC_DEFINE(USE_SETREUID,1,[Whether setreuid() is available]) fi fi - +# we check for setresuid second as it conflicts with AIO on Linux. +# see http://samba.org/~tridge/junkcode/aio_uid.c if test $seteuid = no; then -AC_CACHE_CHECK([for setreuid],samba_cv_USE_SETREUID,[ +AC_CACHE_CHECK([for setresuid],samba_cv_USE_SETRESUID,[ AC_TRY_RUN([ #define AUTOCONF_TEST 1 -#define USE_SETREUID 1 +#define USE_SETRESUID 1 #include "confdefs.h" #include "${srcdir-.}/lib/util_sec.c"], - samba_cv_USE_SETREUID=yes,samba_cv_USE_SETREUID=no,samba_cv_USE_SETREUID=cross)]) -if test x"$samba_cv_USE_SETREUID" = x"yes"; then - seteuid=yes;AC_DEFINE(USE_SETREUID,1,[Whether setreuid() is available]) + samba_cv_USE_SETRESUID=yes,samba_cv_USE_SETRESUID=no,samba_cv_USE_SETRESUID=cross)]) +if test x"$samba_cv_USE_SETRESUID" = x"yes"; then + seteuid=yes;AC_DEFINE(USE_SETRESUID,1,[Whether setresuid() is available]) fi fi