diff options
author | Michal Zidek <mzidek@redhat.com> | 2013-08-05 20:59:33 +0200 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2013-08-11 22:21:17 +0200 |
commit | b5d6a9dc1ad63e8567de4c2805fc5baad54dc456 (patch) | |
tree | 4ee3d0db415ba34b1817570d9a9008e3e3e0e8fc /src/responder/nss/nsssrv_mmap_cache.c | |
parent | 29b9dbc96370b85e460156e528cb2542c160cfd3 (diff) | |
download | sssd-b5d6a9dc1ad63e8567de4c2805fc5baad54dc456.tar.gz sssd-b5d6a9dc1ad63e8567de4c2805fc5baad54dc456.tar.xz sssd-b5d6a9dc1ad63e8567de4c2805fc5baad54dc456.zip |
mmap_cache: Check if slot and name_ptr are not invalid.sssd-1.9.2-118.el6
This patch prevents jumping outside of allocated memory in
case of corrupted slot or name_ptr values. It is not proper
solution, just hotfix until we find out what is the root cause
of ticket https://fedorahosted.org/sssd/ticket/2018
Diffstat (limited to 'src/responder/nss/nsssrv_mmap_cache.c')
-rw-r--r-- | src/responder/nss/nsssrv_mmap_cache.c | 54 |
1 files changed, 52 insertions, 2 deletions
diff --git a/src/responder/nss/nsssrv_mmap_cache.c b/src/responder/nss/nsssrv_mmap_cache.c index 8cf27ca69..02527dac4 100644 --- a/src/responder/nss/nsssrv_mmap_cache.c +++ b/src/responder/nss/nsssrv_mmap_cache.c @@ -374,8 +374,23 @@ static struct sss_mc_rec *sss_mc_find_record(struct sss_mc_ctx *mcc, } while (slot != MC_INVALID_VAL) { + if (slot > MC_SIZE_TO_SLOTS(mcc->dt_size)) { + DEBUG(SSSDBG_FATAL_FAILURE, + ("Corrupted fastcache. Slot number too big.\n")); + sss_mmap_cache_reset(mcc); + return NULL; + } + rec = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec); name_ptr = *((rel_ptr_t *)rec->data); + /* FIXME: This check relies on fact that offset of member strs + * is the same in structures sss_mc_pwd_data and sss_mc_group_data. */ + if (name_ptr != offsetof(struct sss_mc_pwd_data, strs)) { + DEBUG(SSSDBG_FATAL_FAILURE, + ("Corrupted fastcache. name_ptr value is %u.\n", name_ptr)); + sss_mmap_cache_reset(mcc); + return NULL; + } t_key = (char *)rec->data + name_ptr; if (strcmp(key->str, t_key) == 0) { @@ -579,6 +594,13 @@ errno_t sss_mmap_cache_pw_invalidate_uid(struct sss_mc_ctx *mcc, uid_t uid) } while (slot != MC_INVALID_VAL) { + if (slot > MC_SIZE_TO_SLOTS(mcc->dt_size)) { + DEBUG(SSSDBG_FATAL_FAILURE, ("Corrupted fastcache.\n")); + sss_mmap_cache_reset(mcc); + ret = ENOENT; + goto done; + } + rec = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec); data = (struct sss_mc_pwd_data *)(&rec->data); @@ -705,6 +727,13 @@ errno_t sss_mmap_cache_gr_invalidate_gid(struct sss_mc_ctx *mcc, gid_t gid) } while (slot != MC_INVALID_VAL) { + if (slot > MC_SIZE_TO_SLOTS(mcc->dt_size)) { + DEBUG(SSSDBG_FATAL_FAILURE, ("Corrupted fastcache.\n")); + sss_mmap_cache_reset(mcc); + ret = ENOENT; + goto done; + } + rec = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec); data = (struct sss_mc_grp_data *)(&rec->data); @@ -852,8 +881,9 @@ static void sss_mc_header_update(struct sss_mc_ctx *mc_ctx, int status) /* update header using barriers */ h = (struct sss_mc_header *)mc_ctx->mmap_base; MC_RAISE_BARRIER(h); - if (status != SSS_MC_HEADER_RECYCLED) { - /* no reason to update anything else if the file is recycled */ + if (status == SSS_MC_HEADER_ALIVE) { + /* no reason to update anything else if the file is recycled or + * right before reset */ h->hash_table = MC_PTR_DIFF(mc_ctx->hash_table, mc_ctx->mmap_base); h->free_table = MC_PTR_DIFF(mc_ctx->free_table, mc_ctx->mmap_base); h->data_table = MC_PTR_DIFF(mc_ctx->data_table, mc_ctx->mmap_base); @@ -1076,3 +1106,23 @@ done: talloc_free(tmp_ctx); return ret; } + +/* Erase all contents of the mmap cache. This will bring the cache + * to the same state as if it was just initialized. */ +void sss_mmap_cache_reset(struct sss_mc_ctx *mc_ctx) +{ + if (mc_ctx == NULL) { + DEBUG(SSSDBG_TRACE_FUNC, + ("Fastcache not initialized. Nothing to do.\n")); + return; + } + + sss_mc_header_update(mc_ctx, SSS_MC_HEADER_UNINIT); + + /* Reset the mmaped area */ + memset(mc_ctx->data_table, 0xff, mc_ctx->dt_size); + memset(mc_ctx->free_table, 0x00, mc_ctx->ft_size); + memset(mc_ctx->hash_table, 0xff, mc_ctx->ht_size); + + sss_mc_header_update(mc_ctx, SSS_MC_HEADER_ALIVE); +} |