diff options
author | Lukas Slebodnik <lslebodn@redhat.com> | 2015-07-16 17:00:12 +0200 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2015-08-05 11:28:19 +0200 |
commit | 225dc6914cdc8920b02a129b98ece1ed97b99c03 (patch) | |
tree | 39ef3e048f6460b4f70001197e25b1b8d14b4193 /src/sss_client | |
parent | 39b31427e2d11ca318df11fd48db33a7cc610aa7 (diff) | |
download | sssd-225dc6914cdc8920b02a129b98ece1ed97b99c03.tar.gz sssd-225dc6914cdc8920b02a129b98ece1ed97b99c03.tar.xz sssd-225dc6914cdc8920b02a129b98ece1ed97b99c03.zip |
mmap_cache: "Override" functions for initgr mmap cache
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 <mzidek@redhat.com>
Diffstat (limited to 'src/sss_client')
-rw-r--r-- | src/sss_client/nss_mc_initgr.c | 16 |
1 files changed, 11 insertions, 5 deletions
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; } |