[SCM] Samba Shared Repository - branch v3-4-test updated

Karolin Seeger kseeger at samba.org
Thu Feb 4 02:07:40 MST 2010


The branch, v3-4-test has been updated
       via  246eba3... Fix bug #7067 - Linux asynchronous IO (aio) can cause smbd to fail to respond to a read or write.
      from  135b67a... Do not segfault in pdb_search_destructor if no real search was started (cherry picked from commit d07464b21fe652e205f5eb2c74d12495bab100ce)

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


- Log -----------------------------------------------------------------
commit 246eba3b807e5ce50ee838c51823a9eb44f6b690
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Jan 26 16:51:57 2010 -0800

    Fix bug #7067 - Linux asynchronous IO (aio) can cause smbd to fail to respond to a read or write.
    
    Only works on Linux kernels 2.6.26 and above. Grants CAP_KILL capability
    to allow Linux threads under different euids to send signals to each other.
    
    Jeremy.
    (cherry picked from commit 899bd0005f56dcc1e95c3988d41ab3f628bb15db)

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

Summary of changes:
 source3/include/smb.h |    3 +-
 source3/lib/system.c  |   65 ++++++++++++++++++++++++++++++++++++++++++++++---
 source3/smbd/server.c |    8 ++++++
 3 files changed, 71 insertions(+), 5 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/smb.h b/source3/include/smb.h
index 2a3c455..29c614b 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -1690,7 +1690,8 @@ minimum length == 24.
 enum smbd_capability {
     KERNEL_OPLOCK_CAPABILITY,
     DMAPI_ACCESS_CAPABILITY,
-    LEASE_CAPABILITY
+    LEASE_CAPABILITY,
+    KILL_CAPABILITY
 };
 
 /*
diff --git a/source3/lib/system.c b/source3/lib/system.c
index e815766..6349af5 100644
--- a/source3/lib/system.c
+++ b/source3/lib/system.c
@@ -592,6 +592,11 @@ char *sys_getwd(char *s)
 
 #if defined(HAVE_POSIX_CAPABILITIES)
 
+/* This define hasn't made it into the glibc capabilities header yet. */
+#ifndef SECURE_NO_SETUID_FIXUP
+#define SECURE_NO_SETUID_FIXUP          2
+#endif
+
 /**************************************************************************
  Try and abstract process capabilities (for systems that have them).
 ****************************************************************************/
@@ -622,6 +627,32 @@ static bool set_process_capability(enum smbd_capability capability,
 	}
 #endif
 
+#if defined(HAVE_PRCTL) && defined(PR_SET_SECUREBITS) && defined(SECURE_NO_SETUID_FIXUP)
+        /* New way of setting capabilities as "sticky". */
+
+	/*
+	 * Use PR_SET_SECUREBITS to prevent setresuid()
+	 * atomically dropping effective capabilities on
+	 * uid change. Only available in Linux kernels
+	 * 2.6.26 and above.
+	 *
+	 * See here:
+	 * http://www.kernel.org/doc/man-pages/online/pages/man7/capabilities.7.html
+	 * for details.
+	 *
+	 * Specifically the CAP_KILL capability we need
+	 * to allow Linux threads under different euids
+	 * to send signals to each other.
+	 */
+
+	if (prctl(PR_SET_SECUREBITS, 1 << SECURE_NO_SETUID_FIXUP)) {
+		DEBUG(0,("set_process_capability: "
+			"prctl PR_SET_SECUREBITS failed with error %s\n",
+			strerror(errno) ));
+		return false;
+	}
+#endif
+
 	cap = cap_get_proc();
 	if (cap == NULL) {
 		DEBUG(0,("set_process_capability: cap_get_proc failed: %s\n",
@@ -650,6 +681,11 @@ static bool set_process_capability(enum smbd_capability capability,
 			cap_vals[num_cap_vals++] = CAP_LEASE;
 #endif
 			break;
+		case KILL_CAPABILITY:
+#ifdef CAP_KILL
+			cap_vals[num_cap_vals++] = CAP_KILL;
+#endif
+			break;
 	}
 
 	SMB_ASSERT(num_cap_vals <= ARRAY_SIZE(cap_vals));
@@ -659,16 +695,37 @@ static bool set_process_capability(enum smbd_capability capability,
 		return True;
 	}
 
-	cap_set_flag(cap, CAP_EFFECTIVE, num_cap_vals, cap_vals,
-		enable ? CAP_SET : CAP_CLEAR);
+	/*
+	 * Ensure the capability is effective. We assume that as a root
+	 * process it's always permitted.
+	 */
+
+	if (cap_set_flag(cap, CAP_EFFECTIVE, num_cap_vals, cap_vals,
+			enable ? CAP_SET : CAP_CLEAR) == -1) {
+		DEBUG(0, ("set_process_capability: cap_set_flag effective "
+			"failed (%d): %s\n",
+			(int)capability,
+			strerror(errno)));
+		cap_free(cap);
+		return false;
+	}
 
 	/* We never want to pass capabilities down to our children, so make
 	 * sure they are not inherited.
 	 */
-	cap_set_flag(cap, CAP_INHERITABLE, num_cap_vals, cap_vals, CAP_CLEAR);
+	if (cap_set_flag(cap, CAP_INHERITABLE, num_cap_vals,
+			cap_vals, CAP_CLEAR) == -1) {
+		DEBUG(0, ("set_process_capability: cap_set_flag inheritable "
+			"failed (%d): %s\n",
+			(int)capability,
+			strerror(errno)));
+		cap_free(cap);
+		return false;
+	}
 
 	if (cap_set_proc(cap) == -1) {
-		DEBUG(0, ("set_process_capability: cap_set_proc failed: %s\n",
+		DEBUG(0, ("set_process_capability: cap_set_flag (%d) failed: %s\n",
+			(int)capability,
 			strerror(errno)));
 		cap_free(cap);
 		return False;
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 2c5ce40..25571a9 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -1027,6 +1027,14 @@ extern void build_options(bool screen);
 	gain_root_privilege();
 	gain_root_group_privilege();
 
+	/*
+	 * Ensure we have CAP_KILL capability set on Linux,
+	 * where we need this to communicate with threads.
+	 * This is inherited by new threads, but not by new
+	 * processes across exec().
+	 */
+	set_effective_capability(KILL_CAPABILITY);
+
 	fault_setup((void (*)(void *))exit_server_fault);
 	dump_core_setup("smbd");
 


-- 
Samba Shared Repository


More information about the samba-cvs mailing list