aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--recipes-security/sssd/files/CVE-2023-3758.patch221
-rw-r--r--recipes-security/sssd/sssd_2.5.2.bb1
2 files changed, 222 insertions, 0 deletions
diff --git a/recipes-security/sssd/files/CVE-2023-3758.patch b/recipes-security/sssd/files/CVE-2023-3758.patch
new file mode 100644
index 0000000..b604d64
--- /dev/null
+++ b/recipes-security/sssd/files/CVE-2023-3758.patch
@@ -0,0 +1,221 @@
+From f4ebe1408e0bc67abfbfb5f0ca2ea13803b36726 Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Wed, 8 Nov 2023 14:50:24 +0100
+Subject: [PATCH] ad-gpo: use hash to store intermediate results
+
+Currently after the evaluation of a single GPO file the intermediate
+results are stored in the cache and this cache entry is updated until
+all applicable GPO files are evaluated. Finally the data in the cache is
+used to make the decision of access is granted or rejected.
+
+If there are two or more access-control request running in parallel one
+request might overwrite the cache object with intermediate data while
+another request reads the cached data for the access decision and as a
+result will do this decision based on intermediate data.
+
+To avoid this the intermediate results are not stored in the cache
+anymore but in hash tables which are specific to the request. Only the
+final result is written to the cache to have it available for offline
+authentication.
+
+Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
+Reviewed-by: Tomáš Halman <thalman@redhat.com>
+(cherry picked from commit d7db7971682da2dbf7642ac94940d6b0577ec35a)
+
+CVE: CVE-2023-3758
+
+Upstream-Status: Backport [https://github.com/SSSD/sssd/commit/f4ebe1408e0bc67abfbfb5f0ca2ea13803b36726]
+
+Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
+---
+ src/providers/ad/ad_gpo.c | 118 +++++++++++++++++++++++++++++++++-----
+ 1 file changed, 103 insertions(+), 15 deletions(-)
+
+diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c
+index 219f398..fc9691e 100644
+--- a/src/providers/ad/ad_gpo.c
++++ b/src/providers/ad/ad_gpo.c
+@@ -1314,6 +1314,33 @@ ad_gpo_extract_policy_setting(TALLOC_CTX *mem_ctx,
+ return ret;
+ }
+
++static errno_t
++add_result_to_hash(hash_table_t *hash, const char *key, char *value)
++{
++ int hret;
++ hash_key_t k;
++ hash_value_t v;
++
++ if (hash == NULL || key == NULL || value == NULL) {
++ return EINVAL;
++ }
++
++ k.type = HASH_KEY_CONST_STRING;
++ k.c_str = key;
++
++ v.type = HASH_VALUE_PTR;
++ v.ptr = value;
++
++ hret = hash_enter(hash, &k, &v);
++ if (hret != HASH_SUCCESS) {
++ DEBUG(SSSDBG_OP_FAILURE, "Failed to add [%s][%s] to hash: [%s].\n",
++ key, value, hash_error_string(hret));
++ return EIO;
++ }
++
++ return EOK;
++}
++
+ /*
+ * This function parses the cse-specific (GP_EXT_GUID_SECURITY) filename,
+ * and stores the allow_key and deny_key of all of the gpo_map_types present
+@@ -1321,6 +1348,7 @@ ad_gpo_extract_policy_setting(TALLOC_CTX *mem_ctx,
+ */
+ static errno_t
+ ad_gpo_store_policy_settings(struct sss_domain_info *domain,
++ hash_table_t *allow_maps, hash_table_t *deny_maps,
+ const char *filename)
+ {
+ struct ini_cfgfile *file_ctx = NULL;
+@@ -1454,14 +1482,14 @@ ad_gpo_store_policy_settings(struct sss_domain_info *domain,
+ goto done;
+ } else if (ret != ENOENT) {
+ const char *value = allow_value ? allow_value : empty_val;
+- ret = sysdb_gpo_store_gpo_result_setting(domain,
+- allow_key,
+- value);
+- if (ret != EOK) {
+- DEBUG(SSSDBG_CRIT_FAILURE,
+- "sysdb_gpo_store_gpo_result_setting failed for key:"
+- "'%s' value:'%s' [%d][%s]\n", allow_key, allow_value,
+- ret, sss_strerror(ret));
++ ret = add_result_to_hash(allow_maps, allow_key,
++ talloc_strdup(allow_maps, value));
++ if (ret != EOK) {
++ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to add key: [%s] "
++ "value: [%s] to allow maps "
++ "[%d][%s].\n",
++ allow_key, value, ret,
++ sss_strerror(ret));
+ goto done;
+ }
+ }
+@@ -1481,14 +1509,14 @@ ad_gpo_store_policy_settings(struct sss_domain_info *domain,
+ goto done;
+ } else if (ret != ENOENT) {
+ const char *value = deny_value ? deny_value : empty_val;
+- ret = sysdb_gpo_store_gpo_result_setting(domain,
+- deny_key,
+- value);
++ ret = add_result_to_hash(deny_maps, deny_key,
++ talloc_strdup(deny_maps, value));
+ if (ret != EOK) {
+- DEBUG(SSSDBG_CRIT_FAILURE,
+- "sysdb_gpo_store_gpo_result_setting failed for key:"
+- "'%s' value:'%s' [%d][%s]\n", deny_key, deny_value,
+- ret, sss_strerror(ret));
++ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to add key: [%s] "
++ "value: [%s] to deny maps "
++ "[%d][%s].\n",
++ deny_key, value, ret,
++ sss_strerror(ret));
+ goto done;
+ }
+ }
+@@ -1781,6 +1809,8 @@ struct ad_gpo_access_state {
+ int num_cse_filtered_gpos;
+ int cse_gpo_index;
+ const char *ad_domain;
++ hash_table_t *allow_maps;
++ hash_table_t *deny_maps;
+ };
+
+ static void ad_gpo_connect_done(struct tevent_req *subreq);
+@@ -1903,6 +1933,19 @@ ad_gpo_access_send(TALLOC_CTX *mem_ctx,
+ goto immediately;
+ }
+
++ ret = sss_hash_create(state, 0, &state->allow_maps);
++ if (ret != EOK) {
++ DEBUG(SSSDBG_FATAL_FAILURE, "Could not create allow maps "
++ "hash table [%d]: %s\n", ret, sss_strerror(ret));
++ goto immediately;
++ }
++
++ ret = sss_hash_create(state, 0, &state->deny_maps);
++ if (ret != EOK) {
++ DEBUG(SSSDBG_FATAL_FAILURE, "Could not create deny maps "
++ "hash table [%d]: %s\n", ret, sss_strerror(ret));
++ goto immediately;
++ }
+
+ subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret);
+ if (subreq == NULL) {
+@@ -2722,6 +2765,43 @@ ad_gpo_cse_step(struct tevent_req *req)
+ return EAGAIN;
+ }
+
++static errno_t
++store_hash_maps_in_cache(struct sss_domain_info *domain,
++ hash_table_t *allow_maps, hash_table_t *deny_maps)
++{
++ int ret;
++ struct hash_iter_context_t *iter;
++ hash_entry_t *entry;
++ size_t c;
++ hash_table_t *hash_list[] = { allow_maps, deny_maps, NULL};
++
++
++ for (c = 0; hash_list[c] != NULL; c++) {
++ iter = new_hash_iter_context(hash_list[c]);
++ if (iter == NULL) {
++ DEBUG(SSSDBG_OP_FAILURE, "Failed to create hash iterator.\n");
++ return EINVAL;
++ }
++
++ while ((entry = iter->next(iter)) != NULL) {
++ ret = sysdb_gpo_store_gpo_result_setting(domain,
++ entry->key.c_str,
++ entry->value.ptr);
++ if (ret != EOK) {
++ free(iter);
++ DEBUG(SSSDBG_OP_FAILURE,
++ "sysdb_gpo_store_gpo_result_setting failed for key:"
++ "[%s] value:[%s] [%d][%s]\n", entry->key.c_str,
++ (char *) entry->value.ptr, ret, sss_strerror(ret));
++ return ret;
++ }
++ }
++ talloc_free(iter);
++ }
++
++ return EOK;
++}
++
+ /*
+ * This cse-specific function (GP_EXT_GUID_SECURITY) increments the
+ * cse_gpo_index until the policy settings for all applicable GPOs have been
+@@ -2763,6 +2843,7 @@ ad_gpo_cse_done(struct tevent_req *subreq)
+ * (as part of the GPO Result object in the sysdb cache).
+ */
+ ret = ad_gpo_store_policy_settings(state->host_domain,
++ state->allow_maps, state->deny_maps,
+ cse_filtered_gpo->policy_filename);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+@@ -2776,6 +2857,13 @@ ad_gpo_cse_done(struct tevent_req *subreq)
+
+ if (ret == EOK) {
+ /* ret is EOK only after all GPO policy files have been downloaded */
++ ret = store_hash_maps_in_cache(state->host_domain,
++ state->allow_maps, state->deny_maps);
++ if (ret != EOK) {
++ DEBUG(SSSDBG_OP_FAILURE, "Failed to store evaluated GPO maps "
++ "[%d][%s].\n", ret, sss_strerror(ret));
++ goto done;
++ }
+ ret = ad_gpo_perform_hbac_processing(state,
+ state->gpo_mode,
+ state->gpo_map_type,
+--
+2.40.0
diff --git a/recipes-security/sssd/sssd_2.5.2.bb b/recipes-security/sssd/sssd_2.5.2.bb
index 4c75e0a..c07559c 100644
--- a/recipes-security/sssd/sssd_2.5.2.bb
+++ b/recipes-security/sssd/sssd_2.5.2.bb
@@ -24,6 +24,7 @@ SRC_URI = "https://github.com/SSSD/sssd/releases/download/${PV}/sssd-${PV}.tar.g
file://fix-ldblibdir.patch \
file://musl_fixup.patch \
file://CVE-2021-3621.patch \
+ file://CVE-2023-3758.patch \
"
SRC_URI[sha256sum] = "5e21b3c7b4a2f1063d0fbdd3216d29886b6eaba153b44fb5961698367f399a0f"