Loop in talloc

idra at samba.org idra at samba.org
Thu Apr 17 08:24:23 GMT 2008


The following patch shows how to create a loop in _talloc_free() when we
have a hierarchy loop created through talloc_steal()

What happen is that if we have a memory reference on the child we are
trying to free we start searching if that referenced talloc chunk have
other references to us by walking it's parents with tc_is_parent()
Problem is this function (and others that have similar if not identical
loops in the code) do not check for loops, so we end up looping there
forever.

The test implemented in the patch, as it is, until the code is fixed, will never exit and will loop forever (so please do not coimmit it until we decide how to fix the problem). 

Simo.

-- 
Simo Sorce       idra at samba.org
-------------------------------
Samba Team http://www.samba.org
-------------- next part --------------
diff --git a/source/lib/talloc/testsuite.c b/source/lib/talloc/testsuite.c
index fedbda9..46d0ad0 100644
--- a/source/lib/talloc/testsuite.c
+++ b/source/lib/talloc/testsuite.c
@@ -915,6 +915,33 @@ static bool test_loop(void)
 	return true;
 }
 
+static bool test_loop_2(void)
+{
+	void *top = talloc_new(NULL);
+	char *parent;
+	struct req1 {
+		char *req3;
+	} *req1;
+	char *nonchild;
+
+	printf("test: loop 2\n# TALLOC LOOP CHECK\n");
+
+	parent = talloc_strdup(top, "parent");
+	nonchild = talloc_strdup(top, "not a child");
+	req1 = talloc(parent, struct req1);
+	req1->req3 = talloc_strdup(req1, "req3");
+	(void)talloc_reference(parent, nonchild);
+	(void)talloc_steal(req1->req3, parent);
+	talloc_report_full(parent, stderr);
+	talloc_free(nonchild);
+	talloc_free(req1);
+	talloc_report_full(NULL, stderr);
+	talloc_free(top);
+
+	printf("success: loop 2\n");
+	return true;
+}
+
 static int fail_destructor_str(char *ptr)
 {
 	return -1;
@@ -1127,6 +1154,7 @@ bool torture_local_talloc(struct torture_context *tctx)
 	ret &= test_type();
 	ret &= test_lifeless(); 
 	ret &= test_loop();
+	ret &= test_loop_2();
 	ret &= test_free_parent_deny_child(); 
 	ret &= test_talloc_ptrtype();
 	ret &= test_talloc_free_in_destructor();


More information about the samba-technical mailing list