diff -u samba-3.2.3/debian/changelog samba-3.2.3/debian/changelog --- samba-3.2.3/debian/changelog +++ samba-3.2.3/debian/changelog @@ -1,3 +1,11 @@ +samba (2:3.2.3-1ubuntu3.6) intrepid-proposed; urgency=low + + * debian/patches/fix-race-aio-setresuid.patch: + Fix crashes in assert_uid by avoiding a race condition in glibc between + AIO and setresuid() (LP: #216358) + + -- Thierry Carrez Fri, 20 Mar 2009 11:42:20 +0100 + samba (2:3.2.3-1ubuntu3.5) intrepid-proposed; urgency=low * debian/patches/fix-libnss-sigabrt.patch: Fix sigabort when using diff -u samba-3.2.3/debian/patches/series samba-3.2.3/debian/patches/series --- samba-3.2.3/debian/patches/series +++ samba-3.2.3/debian/patches/series @@ -25,0 +26 @@ +fix-race-aio-setresuid.patch only in patch2: unchanged: --- samba-3.2.3.orig/debian/patches/fix-race-aio-setresuid.patch +++ samba-3.2.3/debian/patches/fix-race-aio-setresuid.patch @@ -0,0 +1,102 @@ +Goal: Fix assert_uid samba crashes by avoiding race condition in glibc between + AIO and setresuid(). + +Fixes: LP: #216358 + +Status wrt upstream: Patch cherrypicked from 3.2.4 release + +Author: Andrew Tridgell + +Note: 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. + +Index: samba-3.2.3/source/configure.in +=================================================================== +--- samba-3.2.3.orig/source/configure.in 2009-03-20 11:09:15.000000000 +0100 ++++ samba-3.2.3/source/configure.in 2009-03-20 11:09:22.000000000 +0100 +@@ -2615,30 +2615,32 @@ + ################################################ + # 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 + +Index: samba-3.2.3/source/smbd/aio.c +=================================================================== +--- samba-3.2.3.orig/source/smbd/aio.c 2009-03-20 11:09:15.000000000 +0100 ++++ samba-3.2.3/source/smbd/aio.c 2009-03-20 11:09:22.000000000 +0100 +@@ -268,12 +268,15 @@ + a->aio_sigevent.sigev_signo = RT_SIGNAL_AIO; + a->aio_sigevent.sigev_value.sival_int = aio_ex->mid; + ++ become_root(); + if (SMB_VFS_AIO_READ(fsp,a) == -1) { + DEBUG(0,("schedule_aio_read_and_X: aio_read failed. " + "Error %s\n", strerror(errno) )); + delete_aio_ex(aio_ex); ++ unbecome_root(); + return False; + } ++ unbecome_root(); + + DEBUG(10,("schedule_aio_read_and_X: scheduled aio_read for file %s, " + "offset %.0f, len = %u (mid = %u)\n", +@@ -366,12 +369,15 @@ + a->aio_sigevent.sigev_signo = RT_SIGNAL_AIO; + a->aio_sigevent.sigev_value.sival_int = aio_ex->mid; + ++ become_root(); + if (SMB_VFS_AIO_WRITE(fsp,a) == -1) { + DEBUG(3,("schedule_aio_wrote_and_X: aio_write failed. " + "Error %s\n", strerror(errno) )); + delete_aio_ex(aio_ex); ++ unbecome_root(); + return False; + } ++ unbecome_root(); + + release_level_2_oplocks_on_change(fsp); +