https://bugs.openldap.org/show_bug.cgi?id=10473
Issue ID: 10473 Summary: syncprov leaks response controls Product: OpenLDAP Version: unspecified Hardware: All OS: All Status: UNCONFIRMED Keywords: needs_review Severity: normal Priority: --- Component: overlays Assignee: bugs@openldap.org Reporter: ondra@mistotebe.net Target Milestone: ---
syncprov_state_ctrl and syncprov_done_ctrl add controls to the response, but noone cares to free them afterwards assuming they are allocated from the slab. If there are many messages sent in a single run, this takes up fresh memory that's leaked eventually.
See its8800 regression test for an example where this happens.
https://bugs.openldap.org/show_bug.cgi?id=10473
Quanah Gibson-Mount quanah@openldap.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Target Milestone|--- |2.6.14 Assignee|bugs@openldap.org |ondra@mistotebe.net Keywords|needs_review |
https://bugs.openldap.org/show_bug.cgi?id=10473
Quanah Gibson-Mount quanah@openldap.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |RESOLVED Resolution|--- |TEST
--- Comment #1 from Quanah Gibson-Mount quanah@openldap.org --- head:
• 87197f91 by Ondřej Kuzník at 2026-04-10T03:15:42+00:00 ITS#10473 Make sure sync control data gets freed
RE26:
• 7d9b5999 by Ondřej Kuzník at 2026-04-21T15:57:19+00:00 ITS#10473 Make sure sync control data gets freed
https://bugs.openldap.org/show_bug.cgi?id=10473
Quanah Gibson-Mount quanah@openldap.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |VERIFIED Resolution|TEST |FIXED
https://bugs.openldap.org/show_bug.cgi?id=10473
--- Comment #2 from HAMANO Tsukasa hamano@osstech.co.jp ---
The fix for this ticket (RE26: 7d9b599982, master: 87197f91fc) causes the sync state controls to be freed twice in OpenLDAP 2.6.14 and later, and in master.
## Details
Three of the four callers of `syncprov_state_ctrl()` / `syncprov_done_ctrl()` have set `REP_CTRLS_MUSTBEFREED` since ITS#6795 and ITS#7292, so the frontend (`send_ldap_response()` / `slap_send_search_entry()` / `slap_send_search_reference()`) already frees each control individually with `slap_free_ctrls()` after `slap_cleanup_play()`.
With this fix, the control lives in the same allocation as a `slap_callback`. After `slap_freeself_cb` has freed the callback (and the control with it), `slap_free_ctrls()` passes a pointer into the middle of the freed callback (`&cb[1]`) to `o_tmpfree()` again.
The only leak in the original report is the `no_change:` path, which uses a controls array on the stack and does not set `REP_CTRLS_MUSTBEFREED`. Also, `slap_add_ctrls()` copies the pointers of an existing `sr_ctrls` into a new array and sets `REP_CTRLS_MUSTBEFREED`, so `slap_free_ctrls()` relies on each control being allocated on its own. Embedding the control in a callback is not compatible with that.
## Impact
When the allocation did not fit in the slab and fell back to `ber_memalloc_x()` (for example a long replay of a persistent search, or a refresh of large entries), or when `o_tmpmemctx` is NULL, the interior pointer reaches libc `free()` and the provider slapd aborts with `free(): invalid pointer`.
## Proposed fix
1. Revert this fix (87197f91fc / 7d9b599982) so that the control is allocated on its own again, as before. 2. In the `no_change:` path, free the control after `send_ldap_result()`.
https://bugs.openldap.org/show_bug.cgi?id=10473
--- Comment #3 from HAMANO Tsukasa hamano@osstech.co.jp --- https://git.openldap.org/openldap/openldap/-/merge_requests/953
https://bugs.openldap.org/show_bug.cgi?id=10473
--- Comment #4 from Howard Chu hyc@openldap.org --- Since this ticket was already closed and released, you should open a new ticket for your fix.
https://bugs.openldap.org/show_bug.cgi?id=10473
--- Comment #5 from HAMANO Tsukasa hamano@osstech.co.jp --- new: https://bugs.openldap.org/show_bug.cgi?id=10663