From fbc22ccc53a9c8509715a953c9385e0211a60b7d Mon Sep 17 00:00:00 2001 From: Alexey Tikhonov Date: Wed, 8 Jul 2026 19:55:42 +0200 Subject: [PATCH] Resolves: RHEL-168415 - [Addition] Crash in 'sss_client/autofs/sss_autofs.c' [rhel-8.10.z] Resolves: RHEL-168363 - sss_override does not work on AD UPN [rhel-8.10.z] Resolves: RHEL-192053 - CVE-2026-14474: sudo LDAP provider searches entire directory tree for sudoRole objects by default, enabling privilege escalation [rhel-8.10.z] Resolves: RHEL-192076 - CVE-2026-14476: GPO cache path traversal via unsanitized gPCFileSysPath allows Kerberos authentication bypass [rhel-8.10.z] --- 0027-Add-missing-include.patch | 36 ++++ ...sdb_search_user_by_upn_with_view_res.patch | 88 +++++++++ ...sdb_search_user_by_upn_with_view_res.patch | 48 +++++ 0030-sysdb-remove-sysdb_getpwupn.patch | 95 ++++++++++ ...reat-missing-id-override-as-an-error.patch | 31 +++ ...dap_sudo_search_base-falls-back-to-r.patch | 67 +++++++ ...ect-path-traversal-in-gPCFileSysPath.patch | 176 ++++++++++++++++++ sssd.spec | 15 +- 8 files changed, 555 insertions(+), 1 deletion(-) create mode 100644 0027-Add-missing-include.patch create mode 100644 0028-sysdb-add-sysdb_search_user_by_upn_with_view_res.patch create mode 100644 0029-cache_req-use-sysdb_search_user_by_upn_with_view_res.patch create mode 100644 0030-sysdb-remove-sysdb_getpwupn.patch create mode 100644 0031-sysdb-do-not-treat-missing-id-override-as-an-error.patch create mode 100644 0032-sudo-warn-when-ldap_sudo_search_base-falls-back-to-r.patch create mode 100644 0033-gpo-reject-path-traversal-in-gPCFileSysPath.patch diff --git a/0027-Add-missing-include.patch b/0027-Add-missing-include.patch new file mode 100644 index 0000000..eab1b1c --- /dev/null +++ b/0027-Add-missing-include.patch @@ -0,0 +1,36 @@ +From a41b84d7bf42846aa2b5f265741edba9a1f7e0c1 Mon Sep 17 00:00:00 2001 +From: Alexey Tikhonov +Date: Wed, 15 Apr 2026 09:42:34 +0200 +Subject: [PATCH] Add missing include +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Original patch f3af8c89af656767333410b0e94da9288dd8ade8 didn't include +"config.h" that provides `HAVE_PTHREAD_EXT` +It works in some branches accidentally because of transitive include +via "sss_cli.h" but that's fragile (and in some branches "sss_cli.h" +doesn't include "config.h") + +Reviewed-by: Tomáš Halman +(cherry picked from commit a809b9236250e6f20e9a9ff1452708cd288b705f) +--- + src/sss_client/autofs/sss_autofs.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/sss_client/autofs/sss_autofs.c b/src/sss_client/autofs/sss_autofs.c +index f5986767f..45e2ce460 100644 +--- a/src/sss_client/autofs/sss_autofs.c ++++ b/src/sss_client/autofs/sss_autofs.c +@@ -18,6 +18,8 @@ + along with this program. If not, see . + */ + ++#include "config.h" ++ + #include + #include + #include +-- +2.54.0 + diff --git a/0028-sysdb-add-sysdb_search_user_by_upn_with_view_res.patch b/0028-sysdb-add-sysdb_search_user_by_upn_with_view_res.patch new file mode 100644 index 0000000..fc332f9 --- /dev/null +++ b/0028-sysdb-add-sysdb_search_user_by_upn_with_view_res.patch @@ -0,0 +1,88 @@ +From 5ca4b84efd03d6b2add6d82d92cea7ef58bc4ca9 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Thu, 12 Jun 2025 19:49:10 +0200 +Subject: [PATCH 28/32] sysdb: add sysdb_search_user_by_upn_with_view_res() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The new call will apply overrides to a user object which was searched by +UPN or email address before returning it. + +Reviewed-by: Alexey Tikhonov +Reviewed-by: Pavel Březina +(cherry picked from commit 794e80f4f155cd5d97e70ee015909cd9f3b918b3) +--- + src/db/sysdb.h | 7 +++++++ + src/db/sysdb_ops.c | 37 +++++++++++++++++++++++++++++++++++++ + 2 files changed, 44 insertions(+) + +diff --git a/src/db/sysdb.h b/src/db/sysdb.h +index cedbd4eab..3a0259ec9 100644 +--- a/src/db/sysdb.h ++++ b/src/db/sysdb.h +@@ -1047,6 +1047,13 @@ int sysdb_search_user_by_upn_res(TALLOC_CTX *mem_ctx, + const char **attrs, + struct ldb_result **out_res); + ++int sysdb_search_user_by_upn_with_view_res(TALLOC_CTX *mem_ctx, ++ struct sss_domain_info *domain, ++ bool domain_scope, ++ const char *upn, ++ const char **attrs, ++ struct ldb_result **out_res); ++ + int sysdb_search_user_by_upn(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + bool domain_scope, +diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c +index 744e6e879..b0e8060f9 100644 +--- a/src/db/sysdb_ops.c ++++ b/src/db/sysdb_ops.c +@@ -712,6 +712,43 @@ done: + return ret; + } + ++int sysdb_search_user_by_upn_with_view_res(TALLOC_CTX *mem_ctx, ++ struct sss_domain_info *domain, ++ bool domain_scope, ++ const char *upn, ++ const char **attrs, ++ struct ldb_result **out_res) ++{ ++ int ret; ++ struct ldb_result *orig_obj = NULL; ++ ++ /* The UPN or the email address cannot be overwritten and we can search ++ * directly the original object. */ ++ ret = sysdb_search_user_by_upn_res(mem_ctx, domain, domain_scope, upn, ++ attrs, &orig_obj); ++ if (ret != EOK) { ++ DEBUG(ret == ENOENT ? SSSDBG_MINOR_FAILURE : SSSDBG_OP_FAILURE, ++ "Failed to find UPN [%s] in cache [%d][%s].\n", ++ upn, ret, sss_strerror(ret)); ++ return ret; ++ } ++ ++ /* If there are views we have to check if override values must be added to ++ * the original object. */ ++ if (DOM_HAS_VIEWS(domain)) { ++ ret = sysdb_add_overrides_to_object(domain, orig_obj->msgs[0], NULL, ++ attrs); ++ if (ret != EOK && ret != ENOENT) { ++ talloc_free(orig_obj); ++ DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_overrides_to_object failed.\n"); ++ return ret; ++ } ++ } ++ ++ *out_res = orig_obj; ++ return ret; ++} ++ + int sysdb_search_user_by_upn(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + bool domain_scope, +-- +2.54.0 + diff --git a/0029-cache_req-use-sysdb_search_user_by_upn_with_view_res.patch b/0029-cache_req-use-sysdb_search_user_by_upn_with_view_res.patch new file mode 100644 index 0000000..dc1b980 --- /dev/null +++ b/0029-cache_req-use-sysdb_search_user_by_upn_with_view_res.patch @@ -0,0 +1,48 @@ +From 5f53949d3fcc3bd8b02b2d79327a3cf303c76d38 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Thu, 12 Jun 2025 19:49:42 +0200 +Subject: [PATCH 29/32] cache_req: use sysdb_search_user_by_upn_with_view_res() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +To make sure any overrides are applied to the user even when searched by +UPN or email address sysdb_search_user_by_upn_with_view_res() is now +used in the cache request code. + +Reviewed-by: Alexey Tikhonov +Reviewed-by: Pavel Březina +(cherry picked from commit 43f22b968a48c4e1f1e7cb885e68428baa7cc7be) +--- + .../cache_req/plugins/cache_req_user_by_upn.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/src/responder/common/cache_req/plugins/cache_req_user_by_upn.c b/src/responder/common/cache_req/plugins/cache_req_user_by_upn.c +index 037994c8c..cfcaf4916 100644 +--- a/src/responder/common/cache_req/plugins/cache_req_user_by_upn.c ++++ b/src/responder/common/cache_req/plugins/cache_req_user_by_upn.c +@@ -84,13 +84,14 @@ cache_req_user_by_upn_lookup(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + struct ldb_result **_result) + { +- if (data->attrs == NULL) { +- return sysdb_getpwupn(mem_ctx, domain, true, data->name.lookup, _result); +- } +- +- return sysdb_search_user_by_upn_res(mem_ctx, domain, true, +- data->name.lookup, data->attrs, +- _result); ++ static const char *def_attrs[] = SYSDB_PW_ATTRS; ++ ++ return sysdb_search_user_by_upn_with_view_res(mem_ctx, domain, true, ++ data->name.lookup, ++ data->attrs == NULL ++ ? def_attrs ++ : data->attrs, ++ _result); + } + + static struct tevent_req * +-- +2.54.0 + diff --git a/0030-sysdb-remove-sysdb_getpwupn.patch b/0030-sysdb-remove-sysdb_getpwupn.patch new file mode 100644 index 0000000..a536c8b --- /dev/null +++ b/0030-sysdb-remove-sysdb_getpwupn.patch @@ -0,0 +1,95 @@ +From 9937664e29e45706100b2b6ea5fd6570b848089b Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Thu, 12 Jun 2025 19:52:10 +0200 +Subject: [PATCH 30/32] sysdb:: remove sysdb_getpwupn() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Alexey Tikhonov +Reviewed-by: Pavel Březina +(cherry picked from commit fe61b85b440380bd88d5859819a1111878ca36ea) +--- + src/db/sysdb.h | 6 ------ + src/db/sysdb_search.c | 30 -------------------------- + src/tests/cmocka/test_sysdb_ts_cache.c | 6 ------ + 3 files changed, 42 deletions(-) + +diff --git a/src/db/sysdb.h b/src/db/sysdb.h +index 3a0259ec9..8c030bd07 100644 +--- a/src/db/sysdb.h ++++ b/src/db/sysdb.h +@@ -852,12 +852,6 @@ int sysdb_getpwuid(TALLOC_CTX *mem_ctx, + uid_t uid, + struct ldb_result **res); + +-int sysdb_getpwupn(TALLOC_CTX *mem_ctx, +- struct sss_domain_info *domain, +- bool domain_scope, +- const char *upn, +- struct ldb_result **res); +- + int sysdb_enumpwent(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + struct ldb_result **res); +diff --git a/src/db/sysdb_search.c b/src/db/sysdb_search.c +index f59312b72..49362beb0 100644 +--- a/src/db/sysdb_search.c ++++ b/src/db/sysdb_search.c +@@ -598,36 +598,6 @@ static char *enum_filter(TALLOC_CTX *mem_ctx, + return filter; + } + +-int sysdb_getpwupn(TALLOC_CTX *mem_ctx, +- struct sss_domain_info *domain, +- bool domain_scope, +- const char *upn, +- struct ldb_result **_res) +-{ +- TALLOC_CTX *tmp_ctx; +- struct ldb_result *res; +- static const char *attrs[] = SYSDB_PW_ATTRS; +- errno_t ret; +- +- tmp_ctx = talloc_new(NULL); +- if (tmp_ctx == NULL) { +- DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); +- return ENOMEM; +- } +- +- ret = sysdb_search_user_by_upn_res(tmp_ctx, domain, domain_scope, upn, attrs, &res); +- if (ret != EOK && ret != ENOENT) { +- DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_user_by_upn_res() failed.\n"); +- goto done; +- } +- +- *_res = talloc_steal(mem_ctx, res); +- +-done: +- talloc_free(tmp_ctx); +- return ret; +-} +- + errno_t sysdb_search_ts_matches(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + const char *attrs[], +diff --git a/src/tests/cmocka/test_sysdb_ts_cache.c b/src/tests/cmocka/test_sysdb_ts_cache.c +index f349b7061..531de72ab 100644 +--- a/src/tests/cmocka/test_sysdb_ts_cache.c ++++ b/src/tests/cmocka/test_sysdb_ts_cache.c +@@ -1303,12 +1303,6 @@ static void test_user_byupn(void **state) + TEST_NOW_2); + assert_int_equal(ret, EOK); + +- ret = sysdb_getpwupn(test_ctx, test_ctx->tctx->dom, false, TEST_USER_UPN, &res); +- assert_int_equal(ret, EOK); +- assert_int_equal(res->count, 1); +- assert_ts_attrs_res(res, TEST_NOW_2 + TEST_CACHE_TIMEOUT, TEST_NOW_2); +- talloc_free(res); +- + ret = sysdb_search_user_by_upn_res(test_ctx, test_ctx->tctx->dom, + false, TEST_USER_UPN, pw_fetch_attrs, + &res); +-- +2.54.0 + diff --git a/0031-sysdb-do-not-treat-missing-id-override-as-an-error.patch b/0031-sysdb-do-not-treat-missing-id-override-as-an-error.patch new file mode 100644 index 0000000..3c9221e --- /dev/null +++ b/0031-sysdb-do-not-treat-missing-id-override-as-an-error.patch @@ -0,0 +1,31 @@ +From a13fcb20a9b8d1d0e7727d7793c7a6d2f0a696dd Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Mon, 5 Jan 2026 10:17:27 +0100 +Subject: [PATCH 32/32] sysdb: do not treat missing id-override as an error + +In sysdb_search_user_by_upn_with_view_res() +sysdb_add_overrides_to_object() can return ENOENT if there is no +id-override for the given user. This is expected and should not be +treated as an error. + +Reviewed-by: Alexey Tikhonov +(cherry picked from commit 72a42d5cbb969f61698f7403fe6e7cf6a8abf957) +--- + src/db/sysdb_ops.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c +index b0e8060f9..dec1572f5 100644 +--- a/src/db/sysdb_ops.c ++++ b/src/db/sysdb_ops.c +@@ -743,6 +743,7 @@ int sysdb_search_user_by_upn_with_view_res(TALLOC_CTX *mem_ctx, + DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_overrides_to_object failed.\n"); + return ret; + } ++ ret = EOK; + } + + *out_res = orig_obj; +-- +2.54.0 + diff --git a/0032-sudo-warn-when-ldap_sudo_search_base-falls-back-to-r.patch b/0032-sudo-warn-when-ldap_sudo_search_base-falls-back-to-r.patch new file mode 100644 index 0000000..a55796a --- /dev/null +++ b/0032-sudo-warn-when-ldap_sudo_search_base-falls-back-to-r.patch @@ -0,0 +1,67 @@ +From 8b58a80ffedf80ff44f9fe003db5a76bdba88a0d Mon Sep 17 00:00:00 2001 +From: Alexey Tikhonov +Date: Fri, 3 Jul 2026 13:25:08 +0200 +Subject: [PATCH] sudo: warn when ldap_sudo_search_base falls back to root DN +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When ldap_sudo_search_base is not explicitly configured, SSSD falls back +to the domain's naming context (root DN) and searches the entire LDAP +directory tree for sudoRole objects. Any LDAP principal with write access +to any subtree can inject a sudoRole granting arbitrary sudo privileges +on every enrolled host. + +This patch adds a warning log when the fallback occurs, alerting +administrators that their configuration searches the entire directory +tree for sudo rules. A future hardening step would be to default to +ou=sudoers, instead of the root DN. + +The warning approach preserves backwards compatibility while ensuring +administrators are aware of the security implications. + +Based on the patch by: Ian Murphy +Amended by: Alexey Tikhonov + +:fixes: CVE-2026-14474 + +Reviewed-by: Sumit Bose +Reviewed-by: Tomáš Halman +(cherry picked from commit ff8c1b19bcdbf79b733b052a7d926bd920b1205d) +--- + src/providers/ldap/sdap.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c +index 956eba93a..1dd5182bf 100644 +--- a/src/providers/ldap/sdap.c ++++ b/src/providers/ldap/sdap.c +@@ -1309,6 +1309,25 @@ errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse, + + /* Sudo */ + if (!sdom->sudo_search_bases) { ++ /* At some point make this option mandatory, ++ * i.e. disable sudo rules lookup if 'sudo_search_bases' not set. ++ */ ++ DEBUG(SSSDBG_IMPORTANT_INFO, ++ "`ldap_sudo_search_base` is not set. SSSD will search the entire " ++ "directory tree (%s) for sudoRole objects. This may allow any " ++ "LDAP principal with write access to any subtree to inject " ++ "sudo rules granting arbitrary privileges. Set " ++ "`ldap_sudo_search_base` to restrict the search scope " ++ "(e.g., 'ou=sudoers,dc=example,dc=com').\n", ++ sdom->naming_context); ++ sss_log(SSS_LOG_ALERT, ++ "`ldap_sudo_search_base` is not set. SSSD will search the entire " ++ "directory tree (%s) for sudoRole objects. This may allow any " ++ "LDAP principal with write access to any subtree to inject " ++ "sudo rules granting arbitrary privileges. Set " ++ "`ldap_sudo_search_base` to restrict the search scope " ++ "(e.g., 'ou=sudoers,dc=example,dc=com').", ++ sdom->naming_context); + ret = sdap_set_search_base(opts, sdom, + SDAP_SUDO_SEARCH_BASE, + sdom->naming_context); +-- +2.54.0 + diff --git a/0033-gpo-reject-path-traversal-in-gPCFileSysPath.patch b/0033-gpo-reject-path-traversal-in-gPCFileSysPath.patch new file mode 100644 index 0000000..5ff351d --- /dev/null +++ b/0033-gpo-reject-path-traversal-in-gPCFileSysPath.patch @@ -0,0 +1,176 @@ +From 080693ec86737ce3748aff4164b502de3f5d518f Mon Sep 17 00:00:00 2001 +From: Alexey Tikhonov +Date: Thu, 2 Jul 2026 17:29:51 +0200 +Subject: [PATCH] gpo: reject path traversal in gPCFileSysPath +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The gPCFileSysPath LDAP attribute from AD Group Policy Objects is parsed +by ad_gpo_extract_smb_components() which converts backslashes to forward +slashes but does not reject ".." path traversal sequences. The resulting +smb_path is used directly in gpo_cache_store_file() to construct a local +filesystem path under GPO_CACHE_PATH, allowing an attacker with GPO +write access to write files outside the cache directory. + +Due to differential path resolution between libsmbclient (which clamps +".." at the SMB share root) and the kernel (which resolves ".." fully), +the SMB download succeeds while the local file write escapes the cache. +On systems with SELinux enforcing, this enables Kerberos configuration +injection via /var/lib/sss/pubconf/krb5.include.d/ (sssd_public_t, +writable by sssd_t). On systems without SELinux, this enables arbitrary +file writes including cron job injection for root code execution. + +This patch adds two layers of defense: + +1. Reject ".." as a path component in smb_path at parse time in + ad_gpo_extract_smb_components(). Uses component-aware validation + that checks for "/..", "../", and exact ".." — not substring matching + which would false-positive on legitimate names containing "..". + +2. Validate the resolved cache path stays within GPO_CACHE_PATH in + gpo_cache_store_file() using realpath(), with a trailing-slash + prefix check to prevent prefix-collision attacks (e.g., + /var/lib/sss/gpo_cache_evil/ matching /var/lib/sss/gpo_cache). + +Based on the patch by: Ian Murphy +Amended by: Alexey Tikhonov + +:fixes: CVE-2026-14476 + +Reviewed-by: Sumit Bose +Reviewed-by: Tomáš Halman +(cherry picked from commit ba207eab76ff5253662a763b9b6e9ea42f03d31b) +--- + src/providers/ad/ad_gpo.c | 47 +++++++++++++++++++++++++++++++ + src/providers/ad/ad_gpo_child.c | 49 +++++++++++++++++++++++++++++++++ + 2 files changed, 96 insertions(+) + +diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c +index 4e2f06b0d..c4988e6a7 100644 +--- a/src/providers/ad/ad_gpo.c ++++ b/src/providers/ad/ad_gpo.c +@@ -3838,6 +3838,43 @@ ad_gpo_populate_candidate_gpos(TALLOC_CTX *mem_ctx, + return ret; + } + ++/* ++ * Check whether a path contains ".." as a path component. ++ * Returns true if traversal is detected, false if the path is safe. ++ * ++ * Checks for: ++ * - "/.." anywhere in the path (component starting with ..) ++ * - "../" at the start of the path ++ * - exact match ".." (path is just "..") ++ * - "/.." at the end of the path ++ * ++ * Does NOT match ".." as a substring of a longer component ++ * (e.g., "my..file" is allowed). ++ */ ++static bool gpo_path_has_traversal(const char *path) ++{ ++ const char *p; ++ ++ if (path == NULL) { ++ return false; ++ } ++ ++ /* Exact match */ ++ if (strcmp(path, "..") == 0) return true; ++ ++ /* Starts with ../ */ ++ if (strncmp(path, "../", 3) == 0) return true; ++ ++ /* Contains /../ or ends with /.. */ ++ p = path; ++ while ((p = strstr(p, "/..")) != NULL) { ++ if (p[3] == '/' || p[3] == '\0') return true; ++ p += 3; ++ } ++ ++ return false; ++} ++ + /* + * This function parses the input_path into its components, replaces each + * back slash ('\') with a forward slash ('/'), and populates the output params. +@@ -3914,6 +3951,16 @@ ad_gpo_extract_smb_components(TALLOC_CTX *mem_ctx, + goto done; + } + ++ /* Reject path traversal. See function comment for what is matched. */ ++ if (gpo_path_has_traversal(smb_path)) { ++ DEBUG(SSSDBG_CRIT_FAILURE, ++ "gPCFileSysPath contains path traversal component '..': " ++ "[%s]. Rejecting to prevent cache directory escape.\n", ++ smb_path); ++ ret = EINVAL; ++ goto done; ++ } ++ + *_smb_server = talloc_asprintf(mem_ctx, "%s%s", + SMB_STANDARD_URI, + server_hostname); +diff --git a/src/providers/ad/ad_gpo_child.c b/src/providers/ad/ad_gpo_child.c +index 2f2807bec..3a72a05b4 100644 +--- a/src/providers/ad/ad_gpo_child.c ++++ b/src/providers/ad/ad_gpo_child.c +@@ -320,6 +320,55 @@ static errno_t gpo_cache_store_file(const char *smb_path, + goto done; + } + ++ /* Defense-in-depth: verify the resolved path stays within the cache ++ * directory (when updating existing files). This catches any bypass ++ * of the ".." check in the parser, including encoding tricks, symlink ++ * attacks, or future regressions. ++ * ++ * The trailing-slash comparison prevents prefix-collision attacks: ++ * without it, a path resolving to "/var/lib/sss/gpo_cache_evil/" ++ * would incorrectly match the prefix "/var/lib/sss/gpo_cache". ++ */ ++ { ++ char *resolved = realpath(filename, NULL); ++ if (resolved != NULL) { ++ /* Resolve GPO_CACHE_PATH too so the comparison works ++ * even when the cache path contains symlinks. */ ++ char *resolved_cache = realpath(GPO_CACHE_PATH, NULL); ++ if (resolved_cache == NULL) { ++ ret = errno; ++ DEBUG(SSSDBG_CRIT_FAILURE, ++ "realpath(\"%s\") failed: [%d][%s]\n", ++ GPO_CACHE_PATH, ret, strerror(ret)); ++ free(resolved); ++ goto done; ++ } ++ ++ /* Check that resolved path starts with resolved cache + "/" */ ++ size_t cache_len = strlen(resolved_cache); ++ bool inside = ((strlen(resolved) >= cache_len) && ++ (strncmp(resolved, resolved_cache, cache_len) == 0) && ++ (resolved[cache_len] == '/' || resolved[cache_len] == '\0')); ++ if (!inside) { ++ DEBUG(SSSDBG_CRIT_FAILURE, ++ "GPO cache path escapes cache directory: [%s] " ++ "resolves to [%s] which is outside [%s]. " ++ "Rejecting.\n", ++ filename, resolved, resolved_cache); ++ free(resolved_cache); ++ free(resolved); ++ ret = EINVAL; ++ goto done; ++ } ++ free(resolved_cache); ++ free(resolved); ++ } ++ /* If realpath returns NULL, the path doesn't exist yet. ++ * prepare_gpo_cache() will create it — the mkdir calls ++ * are validated by SELinux MAC policy. ++ */ ++ } ++ + tmp_name = talloc_asprintf(tmp_ctx, "%sXXXXXX", filename); + if (tmp_name == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); +-- +2.54.0 + diff --git a/sssd.spec b/sssd.spec index b05d107..cc0aa5a 100644 --- a/sssd.spec +++ b/sssd.spec @@ -19,7 +19,7 @@ Name: sssd Version: 2.9.4 -Release: 5%{?dist}.4 +Release: 5%{?dist}.5 Group: Applications/System Summary: System Security Services Daemon License: GPLv3+ @@ -53,6 +53,13 @@ Patch0023: 0023-sbus-defer-notification-callbacks.patch Patch0024: 0024-cache_req-allow-cache_first-mode-only-if-there-is-mo.patch Patch0025: 0025-RESPONDER-use-proper-context-for-getDomains.patch Patch0026: 0026-Enumerate-object-with-escaped-characters-in-name.patch +Patch0027: 0027-Add-missing-include.patch +Patch0028: 0028-sysdb-add-sysdb_search_user_by_upn_with_view_res.patch +Patch0029: 0029-cache_req-use-sysdb_search_user_by_upn_with_view_res.patch +Patch0030: 0030-sysdb-remove-sysdb_getpwupn.patch +Patch0031: 0031-sysdb-do-not-treat-missing-id-override-as-an-error.patch +Patch0032: 0032-sudo-warn-when-ldap_sudo_search_base-falls-back-to-r.patch +Patch0033: 0033-gpo-reject-path-traversal-in-gPCFileSysPath.patch ### Downstream Patches ### @@ -1237,6 +1244,12 @@ fi %systemd_postun_with_restart sssd.service %changelog +* Wed Jul 8 2026 Alexey Tikhonov - 2.9.4-5.5 +- Resolves: RHEL-168415 - [Addition] Crash in 'sss_client/autofs/sss_autofs.c' [rhel-8.10.z] +- Resolves: RHEL-168363 - sss_override does not work on AD UPN [rhel-8.10.z] +- Resolves: RHEL-192053 - CVE-2026-14474: sudo LDAP provider searches entire directory tree for sudoRole objects by default, enabling privilege escalation [rhel-8.10.z] +- Resolves: RHEL-192076 - CVE-2026-14476: GPO cache path traversal via unsanitized gPCFileSysPath allows Kerberos authentication bypass [rhel-8.10.z] + * Mon Jan 26 2026 Alexey Tikhonov - 2.9.4-5.4 - Resolves: RHEL-143731 - Crash in 'sss_client/autofs/sss_autofs.c' [rhel-8.10.z] - Resolves: RHEL-133476 - 'sssd_nss' hangs when looking up an object by ID that has expired cache entry and filtered out by name [rhel-8.10.z]