Skip to content

Commit 685016b

Browse files
ipa: fix memory leak in ipa_s2n_get_list iteration
Per-step temporaries (retoid, retdata, parsed names, encoded requests) were allocated on the long-lived state context and never freed between iterations. Use a per-step talloc context and free retoid/retdata immediately after consumption. Implementation assisted-by: Claude Code (Opus 4.6)
1 parent 233db39 commit 685016b

1 file changed

Lines changed: 24 additions & 11 deletions

File tree

src/providers/ipa/ipa_s2n_exop.c

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,6 +1248,7 @@ struct ipa_s2n_get_list_state {
12481248
struct sss_domain_info *obj_domain;
12491249
struct sysdb_attrs *override_attrs;
12501250
struct sysdb_attrs *mapped_attrs;
1251+
TALLOC_CTX *step_ctx;
12511252
};
12521253

12531254
static errno_t ipa_s2n_get_list_step(struct tevent_req *req);
@@ -1331,11 +1332,18 @@ static errno_t ipa_s2n_get_list_step(struct tevent_req *req)
13311332
struct dp_id_data *ar;
13321333
char *stat_info = NULL;
13331334

1335+
talloc_zfree(state->step_ctx);
1336+
talloc_zfree(state->override_attrs);
1337+
state->step_ctx = talloc_new(state);
1338+
if (state->step_ctx == NULL) {
1339+
return ENOMEM;
1340+
}
1341+
13341342
parent_domain = get_domains_head(state->dom);
13351343
switch (state->req_input.type) {
13361344
case REQ_INP_NAME:
13371345

1338-
ret = sss_parse_name(state, state->dom->names, state->list[state->list_idx],
1346+
ret = sss_parse_name(state->step_ctx, state->dom->names, state->list[state->list_idx],
13391347
&domain_name, &short_name);
13401348
if (ret != EOK) {
13411349
DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse name '%s' [%d]: %s\n",
@@ -1362,7 +1370,7 @@ static errno_t ipa_s2n_get_list_step(struct tevent_req *req)
13621370
DEBUG(SSSDBG_TRACE_INTERNAL,
13631371
"Looking up IPA object [%s] from LDAP.\n",
13641372
state->list[state->list_idx]);
1365-
ret = get_dp_id_data_for_user_name(state,
1373+
ret = get_dp_id_data_for_user_name(state->step_ctx,
13661374
state->list[state->list_idx],
13671375
state->obj_domain->name,
13681376
&ar);
@@ -1374,7 +1382,7 @@ static errno_t ipa_s2n_get_list_step(struct tevent_req *req)
13741382
}
13751383
ar->entry_type = state->entry_type;
13761384

1377-
subreq = ipa_id_get_account_info_send(state, state->ev,
1385+
subreq = ipa_id_get_account_info_send(state->step_ctx, state->ev,
13781386
state->ipa_ctx, ar);
13791387
if (subreq == NULL) {
13801388
DEBUG(SSSDBG_OP_FAILURE,
@@ -1416,9 +1424,10 @@ static errno_t ipa_s2n_get_list_step(struct tevent_req *req)
14161424
return EINVAL;
14171425
}
14181426

1419-
ret = s2n_encode_request(state, state->obj_domain->name, state->entry_type,
1420-
state->request_type, &state->req_input,
1421-
state->protocol, &bv_req, &stat_info);
1427+
ret = s2n_encode_request(state->step_ctx, state->obj_domain->name,
1428+
state->entry_type, state->request_type,
1429+
&state->req_input, state->protocol,
1430+
&bv_req, &stat_info);
14221431
if (ret != EOK) {
14231432
DEBUG(SSSDBG_OP_FAILURE, "s2n_encode_request failed.\n");
14241433
return ret;
@@ -1437,8 +1446,9 @@ static errno_t ipa_s2n_get_list_step(struct tevent_req *req)
14371446
state->list[state->list_idx]);
14381447
}
14391448

1440-
subreq = ipa_s2n_exop_send(state, state->ev, state->sh, state->protocol,
1441-
state->exop_timeout, bv_req, stat_info);
1449+
subreq = ipa_s2n_exop_send(state->step_ctx, state->ev, state->sh,
1450+
state->protocol, state->exop_timeout,
1451+
bv_req, stat_info);
14421452
if (subreq == NULL) {
14431453
DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_exop_send failed.\n");
14441454
return ENOMEM;
@@ -1463,7 +1473,7 @@ static void ipa_s2n_get_list_next(struct tevent_req *subreq)
14631473

14641474
req_inp = &state->req_input;
14651475

1466-
ret = ipa_s2n_exop_recv(subreq, state, &retoid, &retdata);
1476+
ret = ipa_s2n_exop_recv(subreq, state->step_ctx, &retoid, &retdata);
14671477
talloc_zfree(subreq);
14681478
if (ret != EOK) {
14691479
DEBUG(SSSDBG_OP_FAILURE, "s2n exop request failed.\n");
@@ -1473,6 +1483,8 @@ static void ipa_s2n_get_list_next(struct tevent_req *subreq)
14731483
talloc_zfree(state->attrs);
14741484
ret = s2n_response_to_attrs(state, state->dom, retoid, retdata,
14751485
&state->attrs);
1486+
talloc_zfree(retoid);
1487+
talloc_zfree(retdata);
14761488
if (ret != EOK) {
14771489
DEBUG(SSSDBG_OP_FAILURE, "s2n_response_to_attrs failed.\n");
14781490
goto fail;
@@ -1516,13 +1528,14 @@ static void ipa_s2n_get_list_next(struct tevent_req *subreq)
15161528
}
15171529
}
15181530

1519-
ret = get_dp_id_data_for_sid(state, sid_str, state->obj_domain->name, &ar);
1531+
ret = get_dp_id_data_for_sid(state->step_ctx, sid_str,
1532+
state->obj_domain->name, &ar);
15201533
if (ret != EOK) {
15211534
DEBUG(SSSDBG_OP_FAILURE, "get_dp_id_data_for_sid failed.\n");
15221535
goto fail;
15231536
}
15241537

1525-
subreq = ipa_get_trusted_override_send(state, state->ev,
1538+
subreq = ipa_get_trusted_override_send(state->step_ctx, state->ev,
15261539
state->ipa_ctx->sdap_id_ctx,
15271540
state->ipa_ctx->ipa_options,
15281541
dp_opt_get_string(state->ipa_ctx->ipa_options->basic,

0 commit comments

Comments
 (0)