Skip to content

[autobackport: sssd-2-9] memberOf plugin :: mbof_add_operation() optimizations#8507

Merged
alexey-tikhonov merged 3 commits into
SSSD:sssd-2-9from
sssd-bot:SSSD-sssd-backport-pr8464-to-sssd-2-9
Mar 10, 2026
Merged

[autobackport: sssd-2-9] memberOf plugin :: mbof_add_operation() optimizations#8507
alexey-tikhonov merged 3 commits into
SSSD:sssd-2-9from
sssd-bot:SSSD-sssd-backport-pr8464-to-sssd-2-9

Conversation

@sssd-bot

@sssd-bot sssd-bot commented Mar 9, 2026

Copy link
Copy Markdown
Contributor

This is an automatic backport of PR#8464 memberOf plugin :: mbof_add_operation() optimizations to branch sssd-2-9, created by @alexey-tikhonov.

Please make sure this backport is correct.

Note

The commits were cherry-picked without conflicts.

You can push changes to this pull request

git remote add sssd-bot [email protected]:sssd-bot/sssd.git
git fetch sssd-bot refs/heads/SSSD-sssd-backport-pr8464-to-sssd-2-9
git checkout SSSD-sssd-backport-pr8464-to-sssd-2-9
git push sssd-bot SSSD-sssd-backport-pr8464-to-sssd-2-9 --force

Original commits
c1eced6 - memberOf plugin: redundant comparison removed
7a7480e - memberOf plugin: swap instead of a shift
704c31d - memberOf plugin: avoid ldb_dn_compare() in mbof_add_operation()

Backported commits

  • b9df78a - memberOf plugin: redundant comparison removed
  • d56c208 - memberOf plugin: swap instead of a shift
  • c06e5b8 - memberOf plugin: avoid ldb_dn_compare() in mbof_add_operation()

Original Pull Request Body

Using the same test case as described in #8454 and testing on top of that PR:

  • users tu1 and tu2 are members of the same 5k LDAP groups (RFC2307 case, no nested groups)
  • SSSD stared with an empty cache
  • time id [email protected] | tr ',' '\n' | wc -l and then time id [email protected] | tr ',' '\n' | wc -l are executed

This patch set reduces time spent by id tu1 from 27 to 8 seconds and by consequent id tu2 from 23 to 5 seconds on my laptop.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request aims to improve performance by introducing several optimizations to mbof_add_operation() in the memberOf plugin, including replacing ldb_dn operations with string-based functions, optimizing array element removal, and removing a redundant check. However, a critical security vulnerability has been identified: the new helper functions, sss_get_linearized_dn_from_ldb_val and sss_linearized_dn_match, incorrectly assume that data within ldb_val structures is NULL-terminated. This assumption, when combined with functions like strstr and strcasecmp, can lead to buffer over-reads, potentially causing process crashes (Denial of Service) or information disclosure. It is crucial to address this by using length-limited memory functions and respecting the length field of the ldb_val structure.

Comment on lines +775 to +784
if (data[0] == '<') {
const char *p_save = data;
const char *p = data;
do {
p_save = p;
p = strstr(p, ">;");
if (p) {
p = p + 2;
}
} while (p);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

The function sss_get_linearized_dn_from_ldb_val incorrectly assumes that the input ldb_val data is NULL-terminated, which is not guaranteed by the LDB API. Using strstr on strdn->data without respecting the ldb_val's length field can lead to a buffer over-read if the value is not null-terminated within its allocated length. This vulnerability is propagated to sss_linearized_dn_match and can result in a process crash (Denial of Service) or information disclosure. It is essential to use length-aware functions like memmem instead of strstr and memcmp or strncasecmp with verified lengths, always respecting the length field of the ldb_val structure.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the same code as in ldb_dn_from_ldb_val() that was used previously

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well... actually, original code has a check:

(strnlen((const char*)strdn->data, strdn->length) != strdn->length)) {
                /* The RDN must not contain a character with value 0x0 */
                return NULL;

but it didn't protect against non-NULL terminated strings.

It was other way around - to protect against strings containing 0x0 in the payload.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://www.samba.org/ftp/unpacked/ldb/include/ldb.h

   \note the data is null (0x00) terminated, but the length does not
   include the terminator.
*/
struct ldb_val {
	uint8_t *data; /*!< result data */
	size_t length; /*!< length of data */
};

Comment thread src/ldb_modules/memberof.c
@alexey-tikhonov
alexey-tikhonov force-pushed the SSSD-sssd-backport-pr8464-to-sssd-2-9 branch from c06e5b8 to 22f5a7a Compare March 9, 2026 19:27
@alexey-tikhonov alexey-tikhonov added the no-backport This should go to target branch only. label Mar 9, 2026
@alexey-tikhonov

Copy link
Copy Markdown
Member

Had to add #define _GNU_SOURCE to get strchrnul() on C9S.

@ikerexxe ikerexxe left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

'msg->dn' (== 'addop->entry_dn') is already filtered out from 'parents->dns[i]'
at the beginning of `mbof_add_operation()`

Reviewed-by: Iker Pedrosa <[email protected]>
Reviewed-by: Sumit Bose <[email protected]>
(cherry picked from commit c1eced6)
when removing a duplicate. DNs order doesn't matter.

Reviewed-by: Iker Pedrosa <[email protected]>
Reviewed-by: Sumit Bose <[email protected]>
(cherry picked from commit 7a7480e)
`ldb_dn_compare()` here is heavy because when DNs are not equal (vast majority of cases),
it performs `ldb_dn_casefold_internal()` to return -1 or 1, but it's not important in
this context.

Note that in general using `str*cmp()` instead of `ldb_dn_get_linearized()` might yield
incorrect results due to different DN representations.
But since all 'memberof' DNs originate from sysdb cache / memberof plugin itself, it
should be safe replacement in this context.

Reviewed-by: Iker Pedrosa <[email protected]>
Reviewed-by: Sumit Bose <[email protected]>
(cherry picked from commit 704c31d)
@sssd-bot

Copy link
Copy Markdown
Contributor Author

The pull request was accepted by @alexey-tikhonov with the following PR CI status:


🟢 CodeQL (success)
🟢 rpm-build:centos-stream-9-x86_64:upstream (success)
🟢 Build / make-distcheck (success)
🟢 ci / prepare (success)
🟢 ci / system (centos-9) (success)
🟢 Static code analysis / codeql (success)
🟢 Static code analysis / pre-commit (success)
🟢 Static code analysis / python-system-tests (success)


There are unsuccessful or unfinished checks. Make sure that the failures are not related to this pull request before merging.

@sssd-bot
sssd-bot force-pushed the SSSD-sssd-backport-pr8464-to-sssd-2-9 branch from 22f5a7a to ba83ef9 Compare March 10, 2026 10:18
@alexey-tikhonov
alexey-tikhonov merged commit 999afa2 into SSSD:sssd-2-9 Mar 10, 2026
7 of 8 checks passed
@alexey-tikhonov alexey-tikhonov added the Performance Performance related patches label Mar 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Accepted no-backport This should go to target branch only. Performance Performance related patches

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants