mirror of
https://github.com/samba-team/samba.git
synced 2025-01-11 05:18:09 +03:00
repl: Avoid excessive stack use and instead sort the links in the heap
The two large stack-based arrays would overflow the stack, this avoids a duplicate of the struct drsuapi_DsReplicaLinkedAttribute array BUG: https://bugzilla.samba.org/show_bug.cgi?id=11960 Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Garming Sam <garming@catalyst.net.nz>
This commit is contained in:
parent
8dc3110a5f
commit
a896a92444
@ -53,15 +53,15 @@ struct drsuapi_getncchanges_state {
|
||||
struct drsuapi_DsReplicaCursor2CtrEx *final_udv;
|
||||
struct drsuapi_DsReplicaLinkedAttribute *la_list;
|
||||
uint32_t la_count;
|
||||
bool la_sorted;
|
||||
struct la_for_sorting *la_sorted;
|
||||
uint32_t la_idx;
|
||||
};
|
||||
|
||||
/* We must keep the GUIDs in NDR form for sorting */
|
||||
struct la_for_sorting {
|
||||
struct drsuapi_DsReplicaLinkedAttribute *link;
|
||||
DATA_BLOB target_guid;
|
||||
DATA_BLOB source_guid;
|
||||
uint8_t target_guid[16];
|
||||
uint8_t source_guid[16];
|
||||
};
|
||||
|
||||
static int drsuapi_DsReplicaHighWaterMark_cmp(const struct drsuapi_DsReplicaHighWaterMark *h1,
|
||||
@ -638,8 +638,8 @@ static int linked_attribute_compare(const struct la_for_sorting *la1,
|
||||
void *opaque)
|
||||
{
|
||||
int c;
|
||||
c = data_blob_cmp(&la1->source_guid,
|
||||
&la2->source_guid);
|
||||
c = memcmp(la1->source_guid,
|
||||
la2->source_guid, sizeof(la2->source_guid));
|
||||
if (c != 0) {
|
||||
return c;
|
||||
}
|
||||
@ -654,7 +654,8 @@ static int linked_attribute_compare(const struct la_for_sorting *la1,
|
||||
DRSUAPI_DS_LINKED_ATTRIBUTE_FLAG_ACTIVE)? 1:-1;
|
||||
}
|
||||
|
||||
return data_blob_cmp(&la1->target_guid, &la2->target_guid);
|
||||
return memcmp(la1->target_guid,
|
||||
la2->target_guid, sizeof(la2->target_guid));
|
||||
}
|
||||
|
||||
struct drsuapi_changed_objects {
|
||||
@ -1594,7 +1595,7 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
|
||||
{
|
||||
struct drsuapi_DsReplicaObjectIdentifier *ncRoot;
|
||||
int ret;
|
||||
uint32_t i;
|
||||
uint32_t i, k;
|
||||
struct dsdb_schema *schema;
|
||||
struct drsuapi_DsReplicaOIDMapping_Ctr *ctr;
|
||||
struct drsuapi_DsReplicaObjectListItemEx **currentObject;
|
||||
@ -2198,11 +2199,13 @@ allowed:
|
||||
r->out.ctr->ctr6.more_data = true;
|
||||
} else {
|
||||
/* sort the whole array the first time */
|
||||
if (!getnc_state->la_sorted) {
|
||||
if (getnc_state->la_sorted == NULL) {
|
||||
int j;
|
||||
struct la_for_sorting guid_array[getnc_state->la_count];
|
||||
struct drsuapi_DsReplicaLinkedAttribute tmp_array[getnc_state->la_count];
|
||||
TALLOC_CTX *tmp_ctx = talloc_new(sam_ctx);
|
||||
struct la_for_sorting *guid_array = talloc_array(getnc_state, struct la_for_sorting, getnc_state->la_count);
|
||||
if (guid_array == NULL) {
|
||||
DEBUG(0, ("Out of memory allocating %u linked attributes for sorting", getnc_state->la_count));
|
||||
return WERR_NOMEM;
|
||||
}
|
||||
for (j = 0; j < getnc_state->la_count; j++) {
|
||||
/* we need to get the target GUIDs to compare */
|
||||
struct dsdb_dn *dn;
|
||||
@ -2210,59 +2213,62 @@ allowed:
|
||||
const struct dsdb_attribute *schema_attrib;
|
||||
const struct ldb_val *target_guid;
|
||||
DATA_BLOB source_guid;
|
||||
TALLOC_CTX *frame = talloc_stackframe();
|
||||
|
||||
schema_attrib = dsdb_attribute_by_attributeID_id(schema, la->attid);
|
||||
|
||||
werr = dsdb_dn_la_from_blob(sam_ctx, schema_attrib, schema, tmp_ctx, la->value.blob, &dn);
|
||||
werr = dsdb_dn_la_from_blob(sam_ctx, schema_attrib, schema, frame, la->value.blob, &dn);
|
||||
if (!W_ERROR_IS_OK(werr)) {
|
||||
DEBUG(0,(__location__ ": Bad la blob in sort\n"));
|
||||
talloc_free(tmp_ctx);
|
||||
TALLOC_FREE(frame);
|
||||
return werr;
|
||||
}
|
||||
|
||||
/* Extract the target GUID in NDR form */
|
||||
target_guid = ldb_dn_get_extended_component(dn->dn, "GUID");
|
||||
if (target_guid == NULL) {
|
||||
if (target_guid == NULL
|
||||
|| target_guid->length != sizeof(guid_array[0].target_guid)) {
|
||||
status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
} else {
|
||||
/* Repack the source GUID as NDR for sorting */
|
||||
status = GUID_to_ndr_blob(&la->identifier->guid,
|
||||
tmp_ctx,
|
||||
frame,
|
||||
&source_guid);
|
||||
}
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
if (!NT_STATUS_IS_OK(status)
|
||||
|| source_guid.length != sizeof(guid_array[0].source_guid)) {
|
||||
DEBUG(0,(__location__ ": Bad la guid in sort\n"));
|
||||
talloc_free(tmp_ctx);
|
||||
TALLOC_FREE(frame);
|
||||
return ntstatus_to_werror(status);
|
||||
}
|
||||
|
||||
guid_array[j] = (struct la_for_sorting)
|
||||
{
|
||||
.source_guid = source_guid,
|
||||
.target_guid = *target_guid,
|
||||
.link = &getnc_state->la_list[j]
|
||||
};
|
||||
guid_array[j].link = &getnc_state->la_list[j];
|
||||
memcpy(guid_array[j].target_guid, target_guid->data,
|
||||
sizeof(guid_array[j].target_guid));
|
||||
memcpy(guid_array[j].source_guid, source_guid.data,
|
||||
sizeof(guid_array[j].source_guid));
|
||||
TALLOC_FREE(frame);
|
||||
}
|
||||
|
||||
LDB_TYPESAFE_QSORT(guid_array, getnc_state->la_count, NULL, linked_attribute_compare);
|
||||
|
||||
/* apply the sort to the original list */
|
||||
for (j = 0; j < getnc_state->la_count; j++) {
|
||||
tmp_array[j] = *guid_array[j].link;
|
||||
}
|
||||
memcpy(getnc_state->la_list, tmp_array,
|
||||
getnc_state->la_count * sizeof(struct drsuapi_DsReplicaLinkedAttribute));
|
||||
|
||||
getnc_state->la_sorted = true;
|
||||
TALLOC_FREE(tmp_ctx);
|
||||
getnc_state->la_sorted = guid_array;
|
||||
}
|
||||
|
||||
link_count = getnc_state->la_count - getnc_state->la_idx;
|
||||
link_count = MIN(max_links, link_count);
|
||||
|
||||
r->out.ctr->ctr6.linked_attributes_count = link_count;
|
||||
r->out.ctr->ctr6.linked_attributes = getnc_state->la_list + getnc_state->la_idx;
|
||||
r->out.ctr->ctr6.linked_attributes = talloc_array(r->out.ctr, struct drsuapi_DsReplicaLinkedAttribute, link_count);
|
||||
if (r->out.ctr->ctr6.linked_attributes == NULL) {
|
||||
DEBUG(0, ("Out of memory allocating %u linked attributes for output", link_count));
|
||||
return WERR_NOMEM;
|
||||
}
|
||||
|
||||
for (k = 0; k < link_count; k++) {
|
||||
r->out.ctr->ctr6.linked_attributes[k]
|
||||
= *getnc_state->la_sorted[getnc_state->la_idx + k].link;
|
||||
}
|
||||
|
||||
getnc_state->la_idx += link_count;
|
||||
link_given = getnc_state->la_idx;
|
||||
|
Loading…
Reference in New Issue
Block a user