122 lines
3.6 KiB
Diff
122 lines
3.6 KiB
Diff
|
|
From a2bb5beee82fd9c4c29decc07024057febeaf1b5 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Joseph Sutton <josephsutton@catalyst.net.nz>
|
||
|
|
Date: Wed, 16 Feb 2022 12:35:13 +1300
|
||
|
|
Subject: [PATCH] CVE-2022-32746 ldb: Ensure shallow copy modifications do not
|
||
|
|
affect original message
|
||
|
|
|
||
|
|
Using the newly added ldb flag, we can now detect when a message has
|
||
|
|
been shallow-copied so that its elements share their values with the
|
||
|
|
original message elements. Then when adding values to the copied
|
||
|
|
message, we now make a copy of the shared values array first.
|
||
|
|
|
||
|
|
This should prevent a use-after-free that occurred in LDB modules when
|
||
|
|
new values were added to a shallow copy of a message by calling
|
||
|
|
talloc_realloc() on the original values array, invalidating the 'values'
|
||
|
|
pointer in the original message element. The original values pointer can
|
||
|
|
later be used in the database audit logging module which logs database
|
||
|
|
requests, and potentially cause a crash.
|
||
|
|
|
||
|
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15009
|
||
|
|
|
||
|
|
Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
|
||
|
|
---
|
||
|
|
common/ldb_msg.c | 52 ++++++++++++++++++++++++++++++++------
|
||
|
|
include/ldb.h | 6 +++++
|
||
|
|
2 files changed, 56 insertions(+), 22 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/common/ldb_msg.c b/common/ldb_msg.c
|
||
|
|
index 2a9ce384bb98..44d3b29e9a72 100644
|
||
|
|
--- a/common/ldb_msg.c
|
||
|
|
+++ b/common/ldb_msg.c
|
||
|
|
@@ -417,6 +417,47 @@ int ldb_msg_add(struct ldb_message *msg,
|
||
|
|
return LDB_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
+/*
|
||
|
|
+ * add a value to a message element
|
||
|
|
+ */
|
||
|
|
+int ldb_msg_element_add_value(TALLOC_CTX *mem_ctx,
|
||
|
|
+ struct ldb_message_element *el,
|
||
|
|
+ const struct ldb_val *val)
|
||
|
|
+{
|
||
|
|
+ struct ldb_val *vals;
|
||
|
|
+
|
||
|
|
+ if (el->flags & LDB_FLAG_INTERNAL_SHARED_VALUES) {
|
||
|
|
+ /*
|
||
|
|
+ * Another message is using this message element's values array,
|
||
|
|
+ * so we don't want to make any modifications to the original
|
||
|
|
+ * message, or potentially invalidate its own values by calling
|
||
|
|
+ * talloc_realloc(). Make a copy instead.
|
||
|
|
+ */
|
||
|
|
+ el->flags &= ~LDB_FLAG_INTERNAL_SHARED_VALUES;
|
||
|
|
+
|
||
|
|
+ vals = talloc_array(mem_ctx, struct ldb_val,
|
||
|
|
+ el->num_values + 1);
|
||
|
|
+ if (vals == NULL) {
|
||
|
|
+ return LDB_ERR_OPERATIONS_ERROR;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ if (el->values != NULL) {
|
||
|
|
+ memcpy(vals, el->values, el->num_values * sizeof(struct ldb_val));
|
||
|
|
+ }
|
||
|
|
+ } else {
|
||
|
|
+ vals = talloc_realloc(mem_ctx, el->values, struct ldb_val,
|
||
|
|
+ el->num_values + 1);
|
||
|
|
+ if (vals == NULL) {
|
||
|
|
+ return LDB_ERR_OPERATIONS_ERROR;
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+ el->values = vals;
|
||
|
|
+ el->values[el->num_values] = *val;
|
||
|
|
+ el->num_values++;
|
||
|
|
+
|
||
|
|
+ return LDB_SUCCESS;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
/*
|
||
|
|
add a value to a message
|
||
|
|
*/
|
||
|
|
@@ -426,7 +467,6 @@ int ldb_msg_add_value(struct ldb_message *msg,
|
||
|
|
struct ldb_message_element **return_el)
|
||
|
|
{
|
||
|
|
struct ldb_message_element *el;
|
||
|
|
- struct ldb_val *vals;
|
||
|
|
int ret;
|
||
|
|
|
||
|
|
el = ldb_msg_find_element(msg, attr_name);
|
||
|
|
@@ -437,14 +477,10 @@ int ldb_msg_add_value(struct ldb_message *msg,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
- vals = talloc_realloc(msg->elements, el->values, struct ldb_val,
|
||
|
|
- el->num_values+1);
|
||
|
|
- if (!vals) {
|
||
|
|
- return LDB_ERR_OPERATIONS_ERROR;
|
||
|
|
+ ret = ldb_msg_element_add_value(msg->elements, el, val);
|
||
|
|
+ if (ret != LDB_SUCCESS) {
|
||
|
|
+ return ret;
|
||
|
|
}
|
||
|
|
- el->values = vals;
|
||
|
|
- el->values[el->num_values] = *val;
|
||
|
|
- el->num_values++;
|
||
|
|
|
||
|
|
if (return_el) {
|
||
|
|
*return_el = el;
|
||
|
|
diff --git a/include/ldb.h b/include/ldb.h
|
||
|
|
index bc44157eaf47..129beefeaf56 100644
|
||
|
|
--- a/include/ldb.h
|
||
|
|
+++ b/include/ldb.h
|
||
|
|
@@ -1981,6 +1981,12 @@ int ldb_msg_add_empty(struct ldb_message *msg,
|
||
|
|
int flags,
|
||
|
|
struct ldb_message_element **return_el);
|
||
|
|
|
||
|
|
+/**
|
||
|
|
+ add a value to a message element
|
||
|
|
+*/
|
||
|
|
+int ldb_msg_element_add_value(TALLOC_CTX *mem_ctx,
|
||
|
|
+ struct ldb_message_element *el,
|
||
|
|
+ const struct ldb_val *val);
|
||
|
|
/**
|
||
|
|
add a element to a ldb_message
|
||
|
|
*/
|