Blame SOURCES/0039-mmap_cache-Override-functions-for-initgr-mmap-cache.patch

6cf099
From 8ca168c6f459d77cdf8f46d27a392d0847343703 Mon Sep 17 00:00:00 2001
6cf099
From: Lukas Slebodnik <lslebodn@redhat.com>
6cf099
Date: Thu, 16 Jul 2015 17:00:12 +0200
6cf099
Subject: [PATCH 39/47] mmap_cache: "Override" functions for initgr mmap cache
6cf099
MIME-Version: 1.0
6cf099
Content-Type: text/plain; charset=UTF-8
6cf099
Content-Transfer-Encoding: 8bit
6cf099
6cf099
Functions sss_mc_get_strs_offset and sss_mc_get_strs_len provides
6cf099
data about strings for individual memory caches (passwd, ...)
6cf099
Their are used in generic responder mmap cache code to find a record
6cf099
in mmap cache (sss_mc_find_record). Data provided from functions sss_mc_get_*
6cf099
are used for checking the validity of record. So in case of corrupted record
6cf099
the whole mmap cache can be invalidated.
6cf099
6cf099
Functions sss_mc_get_strs_offset and sss_mc_get_strs_len did not provide
6cf099
data for initgroups mmap cache and therefore particular record could not be
6cf099
invalidated.
6cf099
6cf099
Resolves:
6cf099
https://fedorahosted.org/sssd/ticket/2716
6cf099
6cf099
Reviewed-by: Michal Židek <mzidek@redhat.com>
6cf099
(cherry picked from commit 225dc6914cdc8920b02a129b98ece1ed97b99c03)
6cf099
---
6cf099
 src/responder/nss/nsssrv_mmap_cache.c | 15 ++++++++++++---
6cf099
 src/sss_client/nss_mc_initgr.c        | 16 +++++++++++-----
6cf099
 src/util/mmap_cache.h                 |  6 +++++-
6cf099
 3 files changed, 28 insertions(+), 9 deletions(-)
6cf099
6cf099
diff --git a/src/responder/nss/nsssrv_mmap_cache.c b/src/responder/nss/nsssrv_mmap_cache.c
6cf099
index 16bc926f3ba4f5ab096bd0fb43895edef2b57c50..ab9e769b1f4d5d17a8c41429afce292298239bc5 100644
6cf099
--- a/src/responder/nss/nsssrv_mmap_cache.c
6cf099
+++ b/src/responder/nss/nsssrv_mmap_cache.c
6cf099
@@ -475,6 +475,9 @@ static errno_t sss_mc_get_strs_offset(struct sss_mc_ctx *mcc,
6cf099
     case SSS_MC_GROUP:
6cf099
         *_offset = offsetof(struct sss_mc_grp_data, strs);
6cf099
         return EOK;
6cf099
+    case SSS_MC_INITGROUPS:
6cf099
+        *_offset = offsetof(struct sss_mc_initgr_data, gids);
6cf099
+        return EOK;
6cf099
     default:
6cf099
         DEBUG(SSSDBG_FATAL_FAILURE, "Unknown memory cache type.\n");
6cf099
         return EINVAL;
6cf099
@@ -492,6 +495,9 @@ static errno_t sss_mc_get_strs_len(struct sss_mc_ctx *mcc,
6cf099
     case SSS_MC_GROUP:
6cf099
         *_len = ((struct sss_mc_grp_data *)&rec->data)->strs_len;
6cf099
         return EOK;
6cf099
+    case SSS_MC_INITGROUPS:
6cf099
+        *_len = ((struct sss_mc_initgr_data *)&rec->data)->data_len;
6cf099
+        return EOK;
6cf099
     default:
6cf099
         DEBUG(SSSDBG_FATAL_FAILURE, "Unknown memory cache type.\n");
6cf099
         return EINVAL;
6cf099
@@ -974,8 +980,8 @@ errno_t sss_mmap_cache_initgr_store(struct sss_mc_ctx **_mcc,
6cf099
         return EINVAL;
6cf099
     }
6cf099
 
6cf099
-    /* num_groups + reserved + array of gids + name*/
6cf099
-    data_len = (2 + num_groups) * sizeof(uint32_t) + name->len;
6cf099
+    /* array of gids + name */
6cf099
+    data_len = num_groups * sizeof(uint32_t) + name->len;
6cf099
     rec_len = sizeof(struct sss_mc_rec) + sizeof(struct sss_mc_initgr_data)
6cf099
               + data_len;
6cf099
     if (rec_len > mcc->dt_size) {
6cf099
@@ -998,10 +1004,13 @@ errno_t sss_mmap_cache_initgr_store(struct sss_mc_ctx **_mcc,
6cf099
                             name->str, name->len, name->str, name->len);
6cf099
 
6cf099
     /* initgroups struct */
6cf099
+    data->strs_len = name->len;
6cf099
+    data->data_len = data_len;
6cf099
+    data->reserved = MC_INVALID_VAL32;
6cf099
     data->num_groups = num_groups;
6cf099
     memcpy(data->gids, gids_buf, num_groups * sizeof(uint32_t));
6cf099
     memcpy(&data->gids[num_groups], name->str, name->len);
6cf099
-    data->name = MC_PTR_DIFF(&data->gids[num_groups], data);
6cf099
+    data->strs = data->name = MC_PTR_DIFF(&data->gids[num_groups], data);
6cf099
 
6cf099
     MC_LOWER_BARRIER(rec);
6cf099
 
6cf099
diff --git a/src/sss_client/nss_mc_initgr.c b/src/sss_client/nss_mc_initgr.c
6cf099
index e21b9f40aba00f9cc2385a561fc2bcc163c5791a..153617ea9c6489b7439b9676904b42b042f6697c 100644
6cf099
--- a/src/sss_client/nss_mc_initgr.c
6cf099
+++ b/src/sss_client/nss_mc_initgr.c
6cf099
@@ -93,6 +93,7 @@ errno_t sss_nss_mc_initgroups_dyn(const char *name, size_t name_len,
6cf099
     uint32_t hash;
6cf099
     uint32_t slot;
6cf099
     int ret;
6cf099
+    const size_t data_offset = offsetof(struct sss_mc_initgr_data, gids);
6cf099
     uint8_t *max_addr;
6cf099
 
6cf099
     ret = sss_nss_mc_get_ctx("initgroups", &initgr_mc_ctx);
6cf099
@@ -128,16 +129,21 @@ errno_t sss_nss_mc_initgroups_dyn(const char *name, size_t name_len,
6cf099
         }
6cf099
 
6cf099
         data = (struct sss_mc_initgr_data *)rec->data;
6cf099
+        rec_name = (char *)data + data->name;
6cf099
         /* Integrity check
6cf099
-         * - array with gids must be within data_table
6cf099
-         * - string must be within data_table */
6cf099
-        if ((uint8_t *)data->gids > max_addr
6cf099
-                || (uint8_t *)data + data->name + name_len > max_addr) {
6cf099
+         * - name_len cannot be longer than all strings or data
6cf099
+         * - data->name cannot point outside strings
6cf099
+         * - all data must be within data_table
6cf099
+         * - name must be within data_table */
6cf099
+        if (name_len > data->data_len
6cf099
+            || name_len > data->strs_len
6cf099
+            || (data->strs + name_len) > (data_offset + data->data_len)
6cf099
+            || (uint8_t *)data->gids + data->data_len > max_addr
6cf099
+            || (uint8_t *)rec_name + name_len > max_addr) {
6cf099
             ret = ENOENT;
6cf099
             goto done;
6cf099
         }
6cf099
 
6cf099
-        rec_name = (char *)data + data->name;
6cf099
         if (strcmp(name, rec_name) == 0) {
6cf099
             break;
6cf099
         }
6cf099
diff --git a/src/util/mmap_cache.h b/src/util/mmap_cache.h
6cf099
index a8703d5da4022e11c4bc2f3e2f8710e7f9d982bf..b5917b3c0973276e43e9fe160cec7528b1224f8f 100644
6cf099
--- a/src/util/mmap_cache.h
6cf099
+++ b/src/util/mmap_cache.h
6cf099
@@ -79,7 +79,7 @@ typedef uint32_t rel_ptr_t;
6cf099
 
6cf099
 
6cf099
 #define SSS_MC_MAJOR_VNO    1
6cf099
-#define SSS_MC_MINOR_VNO    0
6cf099
+#define SSS_MC_MINOR_VNO    1
6cf099
 
6cf099
 #define SSS_MC_HEADER_UNINIT    0   /* after ftruncate or before reset */
6cf099
 #define SSS_MC_HEADER_ALIVE     1   /* current and in use */
6cf099
@@ -139,6 +139,10 @@ struct sss_mc_grp_data {
6cf099
 
6cf099
 struct sss_mc_initgr_data {
6cf099
     rel_ptr_t name;         /* ptr to name string, rel. to struct base addr */
6cf099
+    rel_ptr_t strs;         /* ptr to concatenation of all strings */
6cf099
+    uint32_t reserved;
6cf099
+    uint32_t strs_len;      /* length of strs */
6cf099
+    uint32_t data_len;      /* all initgroups data len */
6cf099
     uint32_t num_groups;    /* number of groups */
6cf099
     uint32_t gids[0];       /* array of all groups
6cf099
                              * string with name is stored after gids */
6cf099
-- 
6cf099
2.4.3
6cf099