pyldb: Avoid use-after-free in msg_diff()
authorJoseph Sutton <josephsutton@catalyst.net.nz>
Sun, 12 Sep 2021 23:15:17 +0000 (11:15 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 15 Sep 2021 07:59:31 +0000 (07:59 +0000)
Make a deep copy of the message elements in msg_diff() so that if either
of the input messages are deallocated early, the result does not refer
to non-existing elements.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14642
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14836

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
lib/ldb/pyldb.c
selftest/knownfail.d/python-segfaults

index f849e7eb8e6f86289171a4c50f2f3acd631a6cba..f1538b37c6b069cebaabd8feaba2eaf7105b32ef 100644 (file)
@@ -1804,6 +1804,7 @@ static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
        struct ldb_message *diff;
        struct ldb_context *ldb;
        PyObject *py_ret;
+       TALLOC_CTX *mem_ctx = NULL;
 
        if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
                return NULL;
@@ -1818,19 +1819,32 @@ static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
                return NULL;
        }
 
+       mem_ctx = talloc_new(NULL);
+       if (mem_ctx == NULL) {
+               PyErr_NoMemory();
+               return NULL;
+       }
+
        ldb = pyldb_Ldb_AS_LDBCONTEXT(self);
-       ldb_ret = ldb_msg_difference(ldb, ldb,
+       ldb_ret = ldb_msg_difference(ldb, mem_ctx,
                                     pyldb_Message_AsMessage(py_msg_old),
                                     pyldb_Message_AsMessage(py_msg_new),
                                     &diff);
        if (ldb_ret != LDB_SUCCESS) {
+               talloc_free(mem_ctx);
                PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
                return NULL;
        }
 
+       diff = ldb_msg_copy(mem_ctx, diff);
+       if (diff == NULL) {
+               PyErr_NoMemory();
+               return NULL;
+       }
+
        py_ret = PyLdbMessage_FromMessage(diff);
 
-       talloc_unlink(ldb, diff);
+       talloc_free(mem_ctx);
 
        return py_ret;
 }
index da21b68b425b9e8daf1eb28bf7415c8188b99c7c..d129dab7d474d0d121521c8529c7701fc90badef 100644 (file)
@@ -1,4 +1,3 @@
 samba.tests.segfault.samba.tests.segfault.SegfaultTests.test_net_replicate_init__3
 samba.tests.segfault.samba.tests.segfault.SegfaultTests.test_dnsp_string_list
 samba.tests.segfault.samba.tests.segfault.SegfaultTests.test_dns_record
-samba.tests.segfault.samba.tests.segfault.SegfaultTests.test_ldb_msg_diff