Blob Blame History Raw
From 27ef368b4105f19382360fe62f944b36ca74adb7 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Wed, 6 Sep 2017 12:20:25 +0200
Subject: [PATCH 194/194] certmap: make sure eku_oid_list is always allocated
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

If there are only OIDs in a <EKU> part of a matching rule a NULL pointer
dereference might occur.

Related to https://pagure.io/SSSD/sssd/issue/3508

Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit f5a8cd60c6f377af1954b58f007d16cf3f6dc846)
---
 src/lib/certmap/sss_certmap_krb5_match.c | 21 ++++++++++++---------
 src/tests/cmocka/test_certmap.c          | 17 +++++++++++++++++
 2 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/src/lib/certmap/sss_certmap_krb5_match.c b/src/lib/certmap/sss_certmap_krb5_match.c
index e40f17b8ace46e61087e0a2fa570a362a84cead2..0a77ac225d73f3506e102fdbdc9084faa0f19cf0 100644
--- a/src/lib/certmap/sss_certmap_krb5_match.c
+++ b/src/lib/certmap/sss_certmap_krb5_match.c
@@ -179,19 +179,17 @@ static int parse_krb5_get_eku_value(TALLOC_CTX *mem_ctx,
         goto done;
     }
 
+    comp->eku_oid_list = talloc_zero_array(comp, const char *,
+                                           eku_list_size + 1);
+    if (comp->eku_oid_list == NULL) {
+        ret = ENOMEM;
+        goto done;
+    }
+
     for (c = 0; eku_list[c] != NULL; c++) {
         for (k = 0; ext_key_usage[k].name != NULL; k++) {
 CM_DEBUG(ctx, "[%s][%s].", eku_list[c], ext_key_usage[k].name);
             if (strcasecmp(eku_list[c], ext_key_usage[k].name) == 0) {
-                if (comp->eku_oid_list == NULL) {
-                    comp->eku_oid_list = talloc_zero_array(comp, const char *,
-                                                           eku_list_size + 1);
-                    if (comp->eku_oid_list == NULL) {
-                        ret = ENOMEM;
-                        goto done;
-                    }
-                }
-
                 comp->eku_oid_list[e] = talloc_strdup(comp->eku_oid_list,
                                                       ext_key_usage[k].oid);
                 if (comp->eku_oid_list[e] == NULL) {
@@ -225,6 +223,11 @@ CM_DEBUG(ctx, "[%s][%s].", eku_list[c], ext_key_usage[k].name);
         }
     }
 
+    if (e == 0) {
+        talloc_free(comp->eku_oid_list);
+        comp->eku_oid_list = NULL;
+    }
+
     ret = 0;
 
 done:
diff --git a/src/tests/cmocka/test_certmap.c b/src/tests/cmocka/test_certmap.c
index c998443d086eaa72cc2a05c38ddfc5ba590a1ce7..e732bb214476943d0f723b318ab64d3b4156cace 100644
--- a/src/tests/cmocka/test_certmap.c
+++ b/src/tests/cmocka/test_certmap.c
@@ -445,6 +445,23 @@ static void test_sss_certmap_add_matching_rule(void **state)
     assert_null(
             ctx->prio_list->rule_list->parsed_match_rule->eku->eku_oid_list[3]);
 
+    ret = sss_certmap_add_rule(ctx, 96,
+                               "KRB5:<EKU>1.2.3",
+                               NULL, NULL);
+    assert_int_equal(ret, 0);
+    assert_non_null(ctx->prio_list);
+    assert_non_null(ctx->prio_list->rule_list);
+    assert_non_null(ctx->prio_list->rule_list->parsed_match_rule);
+    assert_int_equal(ctx->prio_list->rule_list->parsed_match_rule->r,
+                     relation_and);
+    assert_non_null(ctx->prio_list->rule_list->parsed_match_rule->eku);
+    assert_true(string_in_list("1.2.3",
+              discard_const(
+               ctx->prio_list->rule_list->parsed_match_rule->eku->eku_oid_list),
+              true));
+    assert_null(
+            ctx->prio_list->rule_list->parsed_match_rule->eku->eku_oid_list[1]);
+
     /* SAN tests */
     ret = sss_certmap_add_rule(ctx, 89, "KRB5:<SAN>abc", NULL, NULL);
     assert_int_equal(ret, 0);
-- 
2.13.5