This is very ugly hotfix for ticket: https://fedorahosted.org/sssd/ticket/2018
So far we were not able to find out why the slot or name_ptr values were corrupted, but this should at least prevent segfaults. Comments are highly appreciated. Thanks Michal
>From 6c376710b0dd09fc75d65eba68f22facb31c9aca Mon Sep 17 00:00:00 2001 From: Michal Zidek <mzi...@redhat.com> Date: Mon, 5 Aug 2013 20:59:33 +0200 Subject: [PATCH] mmap_cache: Check if slot and name_ptr are not invalid. 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 --- src/responder/nss/nsssrv_mmap_cache.c | 34 ++++++++++++++++++++++++++++++++++ src/sss_client/nss_mc_group.c | 10 ++++++++++ src/sss_client/nss_mc_passwd.c | 10 ++++++++++ src/util/mmap_cache.h | 2 ++ 4 files changed, 56 insertions(+) diff --git a/src/responder/nss/nsssrv_mmap_cache.c b/src/responder/nss/nsssrv_mmap_cache.c index 49878fc..cee48b1 100644 --- a/src/responder/nss/nsssrv_mmap_cache.c +++ b/src/responder/nss/nsssrv_mmap_cache.c @@ -373,8 +373,24 @@ static struct sss_mc_rec *sss_mc_find_record(struct sss_mc_ctx *mcc, } while (slot != MC_INVALID_VAL) { + /* FIXME: We can remove this check if we find and fix the root cause + * of ticket #2018 */ + if (slot > MC_SIZE_TO_SLOTS(mcc->dt_size)) { + DEBUG(SSSDBG_FATAL_FAILURE, + ("Corrupted fastcache. Slot number too big.\n")); + return NULL; + } + rec = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec); name_ptr = *((rel_ptr_t *)rec->data); + /* FIXME: We can remove this check if we find and fix the root cause + * of ticket #2018. This check relies on fact that offset of strs + * is the same in 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)); + return NULL; + } t_key = (char *)rec->data + name_ptr; if (strcmp(key->str, t_key) == 0) { @@ -608,6 +624,15 @@ errno_t sss_mmap_cache_pw_invalidate_uid(struct sss_mc_ctx *mcc, uid_t uid) } while (slot != MC_INVALID_VAL) { + /* FIXME: We can remove this check if we find and fix the root cause + * of ticket #2018 */ + if (slot > MC_SIZE_TO_SLOTS(mcc->dt_size)) { + DEBUG(SSSDBG_FATAL_FAILURE, ("Corrupted fastcache.\n")); + /* Return ENOENT and try to continue. */ + 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); @@ -739,6 +764,15 @@ errno_t sss_mmap_cache_gr_invalidate_gid(struct sss_mc_ctx *mcc, gid_t gid) } while (slot != MC_INVALID_VAL) { + /* FIXME: We can remove this check if we find and fix the root cause + * of ticket #2018 */ + if (slot > MC_SIZE_TO_SLOTS(mcc->dt_size)) { + DEBUG(SSSDBG_FATAL_FAILURE, ("Corrupted fastcache.\n")); + /* Return ENOENT and try to continue. */ + 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); diff --git a/src/sss_client/nss_mc_group.c b/src/sss_client/nss_mc_group.c index b3e9a8a..6bc0726 100644 --- a/src/sss_client/nss_mc_group.c +++ b/src/sss_client/nss_mc_group.c @@ -116,6 +116,11 @@ errno_t sss_nss_mc_getgrnam(const char *name, size_t name_len, } while (slot != MC_INVALID_VAL) { + /* FIXME: We can remove this check if we find and fix root cause of + * ticket #2018 */ + if (slot > MC_SIZE_TO_SLOTS(gr_mc_ctx.dt_size)) { + return ENOENT; + } ret = sss_nss_mc_get_record(&gr_mc_ctx, slot, &rec); if (ret) { @@ -180,6 +185,11 @@ errno_t sss_nss_mc_getgrgid(gid_t gid, } while (slot != MC_INVALID_VAL) { + /* FIXME: We can remove this check if we find and fix root cause of + * ticket #2018 */ + if (slot > MC_SIZE_TO_SLOTS(gr_mc_ctx.dt_size)) { + return ENOENT; + } ret = sss_nss_mc_get_record(&gr_mc_ctx, slot, &rec); if (ret) { diff --git a/src/sss_client/nss_mc_passwd.c b/src/sss_client/nss_mc_passwd.c index 4acc642..c748938 100644 --- a/src/sss_client/nss_mc_passwd.c +++ b/src/sss_client/nss_mc_passwd.c @@ -117,6 +117,11 @@ errno_t sss_nss_mc_getpwnam(const char *name, size_t name_len, } while (slot != MC_INVALID_VAL) { + /* FIXME: We can remove this check if we find and fix the root cause + * of ticket #2018 */ + if (slot > MC_SIZE_TO_SLOTS(pw_mc_ctx.dt_size)) { + return ENOENT; + } ret = sss_nss_mc_get_record(&pw_mc_ctx, slot, &rec); if (ret) { @@ -181,6 +186,11 @@ errno_t sss_nss_mc_getpwuid(uid_t uid, } while (slot != MC_INVALID_VAL) { + /* FIXME: We can remove this check if we find and fix the root cause + * of ticket #2018 */ + if (slot > MC_SIZE_TO_SLOTS(pw_mc_ctx.dt_size)) { + return ENOENT; + } ret = sss_nss_mc_get_record(&pw_mc_ctx, slot, &rec); if (ret) { diff --git a/src/util/mmap_cache.h b/src/util/mmap_cache.h index 55383c0..a00b771 100644 --- a/src/util/mmap_cache.h +++ b/src/util/mmap_cache.h @@ -109,6 +109,8 @@ struct sss_mc_rec { char data[0]; }; +/* FIXME: Function sss_mc_find_record currently relies on fact that + * offset of strs is the same in both sss_mc_pwd_data and sss_mc_grp_data. */ struct sss_mc_pwd_data { rel_ptr_t name; /* ptr to name string, rel. to struct base addr */ uint32_t uid; -- 1.7.11.2
_______________________________________________ sssd-devel mailing list sssd-devel@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/sssd-devel