[SCM] Samba Shared Repository - branch v3-0-test updated - release-3-0-32-6-g91dcce0

Jeremy Allison jra at samba.org
Tue Aug 26 17:00:35 GMT 2008


The branch, v3-0-test has been updated
       via  91dcce0e4deb87c6d5e491eb9dbb09fd04981d28 (commit)
       via  5f30f87dcbeaf30713fadeb130193cb86021e87f (commit)
       via  5e3b978c51e741d413b856adafa1b1090ed8dd7b (commit)
      from  1e1449afba5d37fcfd26e0ca7edde05715bc48f7 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-0-test


- Log -----------------------------------------------------------------
commit 91dcce0e4deb87c6d5e491eb9dbb09fd04981d28
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Aug 26 09:59:54 2008 -0700

    become root for AIO operations
    
    We need to become root for AIO read and write to allow the AIO thread
    to send a completion signal to the parent process when the IO
    completes

commit 5f30f87dcbeaf30713fadeb130193cb86021e87f
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Aug 26 09:59:20 2008 -0700

    EINVAL is also a valid error return, meaning "this filesystem
    cannot do sendfile for this file"

commit 5e3b978c51e741d413b856adafa1b1090ed8dd7b
Author: Andrew Tridgell <tridge at samba.org>
Date:   Sun Aug 24 13:56:59 2008 +1000

    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.

-----------------------------------------------------------------------

Summary of changes:
 source/configure.in |   24 +++++++++++++-----------
 source/smbd/aio.c   |    6 ++++++
 source/smbd/reply.c |    5 +++--
 3 files changed, 22 insertions(+), 13 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/configure.in b/source/configure.in
index 7f8a97f..dcdad47 100644
--- a/source/configure.in
+++ b/source/configure.in
@@ -2869,30 +2869,32 @@ fi
 ################################################
 # 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
 
diff --git a/source/smbd/aio.c b/source/smbd/aio.c
index 2559dc9..21b6efb 100644
--- a/source/smbd/aio.c
+++ b/source/smbd/aio.c
@@ -253,12 +253,15 @@ BOOL schedule_aio_read_and_X(connection_struct *conn,
 	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",
@@ -343,12 +346,15 @@ BOOL schedule_aio_write_and_X(connection_struct *conn,
 	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();
 
 	if (!write_through && !lp_syncalways(SNUM(fsp->conn))
 	    && fsp->aio_write_behind) {
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
index faeb90d..bccd116 100644
--- a/source/smbd/reply.c
+++ b/source/smbd/reply.c
@@ -2213,8 +2213,9 @@ void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T st
 		header.free = NULL;
 
 		if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fh->fd, &header, startpos, nread) == -1) {
-			/* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
-			if (errno == ENOSYS) {
+			/* Returning ENOSYS or EINVAL means no data at all was sent.
+			   Do this as a normal read. */
+			if (errno == ENOSYS || errno == EINVAL) {
 				goto normal_readbraw;
 			}
 


-- 
Samba Shared Repository


More information about the samba-cvs mailing list