From 225dc6914cdc8920b02a129b98ece1ed97b99c03 Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Thu, 16 Jul 2015 17:00:12 +0200 Subject: mmap_cache: "Override" functions for initgr mmap cache MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Functions sss_mc_get_strs_offset and sss_mc_get_strs_len provides data about strings for individual memory caches (passwd, ...) Their are used in generic responder mmap cache code to find a record in mmap cache (sss_mc_find_record). Data provided from functions sss_mc_get_* are used for checking the validity of record. So in case of corrupted record the whole mmap cache can be invalidated. Functions sss_mc_get_strs_offset and sss_mc_get_strs_len did not provide data for initgroups mmap cache and therefore particular record could not be invalidated. Resolves: https://fedorahosted.org/sssd/ticket/2716 Reviewed-by: Michal Židek --- src/sss_client/nss_mc_initgr.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'src/sss_client') diff --git a/src/sss_client/nss_mc_initgr.c b/src/sss_client/nss_mc_initgr.c index e21b9f40a..153617ea9 100644 --- a/src/sss_client/nss_mc_initgr.c +++ b/src/sss_client/nss_mc_initgr.c @@ -93,6 +93,7 @@ errno_t sss_nss_mc_initgroups_dyn(const char *name, size_t name_len, uint32_t hash; uint32_t slot; int ret; + const size_t data_offset = offsetof(struct sss_mc_initgr_data, gids); uint8_t *max_addr; ret = sss_nss_mc_get_ctx("initgroups", &initgr_mc_ctx); @@ -128,16 +129,21 @@ errno_t sss_nss_mc_initgroups_dyn(const char *name, size_t name_len, } data = (struct sss_mc_initgr_data *)rec->data; + rec_name = (char *)data + data->name; /* Integrity check - * - array with gids must be within data_table - * - string must be within data_table */ - if ((uint8_t *)data->gids > max_addr - || (uint8_t *)data + data->name + name_len > max_addr) { + * - name_len cannot be longer than all strings or data + * - data->name cannot point outside strings + * - all data must be within data_table + * - name must be within data_table */ + if (name_len > data->data_len + || name_len > data->strs_len + || (data->strs + name_len) > (data_offset + data->data_len) + || (uint8_t *)data->gids + data->data_len > max_addr + || (uint8_t *)rec_name + name_len > max_addr) { ret = ENOENT; goto done; } - rec_name = (char *)data + data->name; if (strcmp(name, rec_name) == 0) { break; } -- cgit