rpms/samba4/devel 0001-Fix-potential-segfaults-using-freed-memory.patch, NONE, 1.1 samba4.spec, 1.8, 1.9

Simo Sorce simo at fedoraproject.org
Tue Mar 10 00:17:54 UTC 2009


Author: simo

Update of /cvs/pkgs/rpms/samba4/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv9134

Modified Files:
	samba4.spec 
Added Files:
	0001-Fix-potential-segfaults-using-freed-memory.patch 
Log Message:
* Mon Mar 09 2009 Simo Sorce <ssorce at redhat.com> - 4.0.0-11alpha7
- Add upstream patch to fix a problem within ldb


0001-Fix-potential-segfaults-using-freed-memory.patch:

--- NEW FILE 0001-Fix-potential-segfaults-using-freed-memory.patch ---
>From 0b25a1f4547f5fb9124b4d8a03d87aaddf6ca307 Mon Sep 17 00:00:00 2001
From: Simo Sorce <idra at samba.org>
Date: Mon, 9 Mar 2009 18:04:38 -0400
Subject: [PATCH] Fix potential segfaults using freed memory.

In some code paths ltdb_context was still referenced even after we were returned
an error by one of the callbacks. Because the interface assumes that once an
error is returned the ldb_request may be freed, and because the ltdb_context was
allocated as a child of the request, this might cause access to freed memory.
Allocate the ltdb_context on ldb, and keep track of what's going on with the
request by adding a spy children on it. This way even if the request is freed
before the ltdb_callback is called, we will safely free the ctx and just quietly
return.
---
 source4/lib/ldb/ldb_tdb/ldb_index.c  |    2 +-
 source4/lib/ldb/ldb_tdb/ldb_search.c |    6 ++--
 source4/lib/ldb/ldb_tdb/ldb_tdb.c    |   49 ++++++++++++++++++++++++++++++---
 source4/lib/ldb/ldb_tdb/ldb_tdb.h    |    7 ++++-
 4 files changed, 54 insertions(+), 10 deletions(-)

diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c
index ad27c9a..c99c293 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_index.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_index.c
@@ -1055,7 +1055,7 @@ static int ltdb_index_filter(const struct dn_list *dn_list,
 
 		ret = ldb_module_send_entry(ac->req, msg, NULL);
 		if (ret != LDB_SUCCESS) {
-			ac->callback_failed = true;
+			ac->request_terminated = true;
 			return ret;
 		}
 	}
diff --git a/source4/lib/ldb/ldb_tdb/ldb_search.c b/source4/lib/ldb/ldb_tdb/ldb_search.c
index 0f59526..d395c28 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_search.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_search.c
@@ -424,10 +424,10 @@ static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi
 
 	ret = ldb_module_send_entry(ac->req, msg, NULL);
 	if (ret != LDB_SUCCESS) {
-		ac->callback_failed = true;
+		ac->request_terminated = true;
 		/* the callback failed, abort the operation */
 		return -1;
-	}	
+	}
 
 	return 0;
 }
@@ -544,7 +544,7 @@ int ltdb_search(struct ltdb_context *ctx)
 		/* Check if we got just a normal error.
 		 * In that case proceed to a full search unless we got a
 		 * callback error */
-		if ( ! ctx->callback_failed && ret != LDB_SUCCESS) {
+		if ( ! ctx->request_terminated && ret != LDB_SUCCESS) {
 			/* Not indexed, so we need to do a full scan */
 			ret = ltdb_search_full(ctx);
 			if (ret != LDB_SUCCESS) {
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
index 24ec06e..d38cb82 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
@@ -1019,7 +1019,15 @@ static void ltdb_timeout(struct tevent_context *ev,
 	struct ltdb_context *ctx;
 	ctx = talloc_get_type(private_data, struct ltdb_context);
 
-	ltdb_request_done(ctx, LDB_ERR_TIME_LIMIT_EXCEEDED);
+	if (!ctx->request_terminated) {
+		/* neutralize the spy */
+		ctx->spy->ctx = NULL;
+
+		/* request is done now */
+		ltdb_request_done(ctx, LDB_ERR_TIME_LIMIT_EXCEEDED);
+	}
+
+	talloc_free(ctx);
 }
 
 static void ltdb_request_extended_done(struct ltdb_context *ctx,
@@ -1078,6 +1086,11 @@ static void ltdb_callback(struct tevent_context *ev,
 
 	ctx = talloc_get_type(private_data, struct ltdb_context);
 
+	if (!ctx->request_terminated) {
+		/* neutralize the spy */
+		ctx->spy->ctx = NULL;
+	} else goto done;
+
 	switch (ctx->req->operation) {
 	case LDB_SEARCH:
 		ret = ltdb_search(ctx);
@@ -1102,11 +1115,24 @@ static void ltdb_callback(struct tevent_context *ev,
 		ret = LDB_ERR_UNWILLING_TO_PERFORM;
 	}
 
-	if (!ctx->callback_failed) {
-		/* Once we are done, we do not need timeout events */
-		talloc_free(ctx->timeout_event);
+	if (!ctx->request_terminated) {
+		/* request is done now */
 		ltdb_request_done(ctx, ret);
 	}
+
+done:
+	talloc_free(ctx);
+}
+
+static int ltdb_request_destructor(void *ptr)
+{
+	struct ltdb_req_spy *spy = talloc_get_type(ptr, struct ltdb_req_spy);
+
+	if (spy->ctx != NULL) {
+		spy->ctx->request_terminated = true;
+	}
+
+	return 0;
 }
 
 static int ltdb_handle_request(struct ldb_module *module,
@@ -1131,7 +1157,7 @@ static int ltdb_handle_request(struct ldb_module *module,
 
 	ev = ldb_get_event_context(ldb);
 
-	ac = talloc_zero(req, struct ltdb_context);
+	ac = talloc_zero(ldb, struct ltdb_context);
 	if (ac == NULL) {
 		ldb_set_errstring(ldb, "Out of Memory");
 		return LDB_ERR_OPERATIONS_ERROR;
@@ -1144,15 +1170,28 @@ static int ltdb_handle_request(struct ldb_module *module,
 	tv.tv_usec = 0;
 	te = tevent_add_timer(ev, ac, tv, ltdb_callback, ac);
 	if (NULL == te) {
+		talloc_free(ac);
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
 
 	tv.tv_sec = req->starttime + req->timeout;
 	ac->timeout_event = tevent_add_timer(ev, ac, tv, ltdb_timeout, ac);
 	if (NULL == ac->timeout_event) {
+		talloc_free(ac);
 		return LDB_ERR_OPERATIONS_ERROR;
 	}
 
+	/* set a spy so that we do not try to use the request context
+	 * if it is freed before ltdb_callback fires */
+	ac->spy = talloc(req, struct ltdb_req_spy);
+	if (NULL == ac->spy) {
+		talloc_free(ac);
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+	ac->spy->ctx = ac;
+
+	talloc_set_destructor((TALLOC_CTX *)ac->spy, ltdb_request_destructor);
+
 	return LDB_SUCCESS;
 }
 
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h
index 0a06cdb..5a1c8fe 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h
@@ -36,11 +36,16 @@ struct ltdb_private {
   the async local context
   holds also internal search state during a full db search
 */
+struct ltdb_req_spy {
+	struct ltdb_context *ctx;
+};
+
 struct ltdb_context {
 	struct ldb_module *module;
 	struct ldb_request *req;
 
-	bool callback_failed;
+	bool request_terminated;
+	struct ltdb_req_spy *spy;
 
 	/* search stuff */
 	const struct ldb_parse_tree *tree;
-- 
1.6.0.6



Index: samba4.spec
===================================================================
RCS file: /cvs/pkgs/rpms/samba4/devel/samba4.spec,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- samba4.spec	9 Mar 2009 01:39:23 -0000	1.8
+++ samba4.spec	10 Mar 2009 00:17:24 -0000	1.9
@@ -1,4 +1,4 @@
-%define main_release 10
+%define main_release 11
 %define samba4_version 4.0.0
 
 %define talloc_version 1.2.0
@@ -56,6 +56,7 @@
 Source5: %{name}.init
 
 Patch1: samba-4.0.0alpha6-GIT-3508a66-undefined-comparison_fn_t.patch
+Patch2: 0001-Fix-potential-segfaults-using-freed-memory.patch
 
 Requires(pre): /usr/sbin/groupadd
 
@@ -288,6 +289,7 @@
 # copy Red Hat specific scripts
 
 %patch1 -p1 -b .undefined-comparison_fn_t
+%patch2 -p1 -b .potential_ldb_segfault
 
 mv source4/VERSION source4/VERSION.orig
 sed -e 's/SAMBA_VERSION_VENDOR_SUFFIX=$/&%{release}/' < source4/VERSION.orig > source4/VERSION
@@ -833,6 +835,9 @@
 %endif
 
 %changelog
+* Mon Mar 09 2009 Simo Sorce <ssorce at redhat.com> - 4.0.0-11alpha7
+- Add upstream patch to fix a problem within ldb
+
 * Sun Mar 08 2009 Matthew Barnes <mbarnes at redhat.com> - 4.0.0-10alpha7
 - Remove ldb.pc from samba4-devel (RH bug #489186).
 




More information about the fedora-extras-commits mailing list