autofs-5.0.7 - fix potential null dereference in lookup_mount() From: Ian Kent Updating a negative cache entry should always find an entry but the entry lookup return isn't checked and probably should be. Since this code is duplicated in several modules add it as a function to the cache handling code. --- include/automount.h | 1 + lib/cache.c | 20 ++++++++++++++++++++ modules/lookup_file.c | 11 +---------- modules/lookup_ldap.c | 12 +----------- modules/lookup_sss.c | 12 +----------- modules/lookup_yp.c | 12 ++---------- 6 files changed, 26 insertions(+), 42 deletions(-) diff --git a/include/automount.h b/include/automount.h index 6ced842..71787a5 100644 --- a/include/automount.h +++ b/include/automount.h @@ -189,6 +189,7 @@ struct mapent *cache_lookup_offset(const char *prefix, const char *offset, int s struct mapent *cache_partial_match(struct mapent_cache *mc, const char *prefix); int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age); int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age); +void cache_update_negative(struct mapent_cache *mc, struct map_source *ms, const char *key, time_t timeout); int cache_set_parents(struct mapent *mm); int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age); int cache_delete(struct mapent_cache *mc, const char *key); diff --git a/lib/cache.c b/lib/cache.c index ecace4a..be4917b 100644 --- a/lib/cache.c +++ b/lib/cache.c @@ -680,6 +680,26 @@ done: return ret; } +void cache_update_negative(struct mapent_cache *mc, + struct map_source *ms, const char *key, + time_t timeout) +{ + time_t now = time(NULL); + struct mapent *me; + int rv = CHE_OK; + + me = cache_lookup_distinct(mc, key); + if (!me) + rv = cache_update(mc, ms, key, NULL, now); + if (rv != CHE_FAIL) { + me = cache_lookup_distinct(mc, key); + if (me) + me->status = now + timeout; + } + return; +} + + static struct mapent *get_parent(const char *key, struct list_head *head, struct list_head **pos) { struct list_head *next; diff --git a/modules/lookup_file.c b/modules/lookup_file.c index 2836996..4b4ee89 100644 --- a/modules/lookup_file.c +++ b/modules/lookup_file.c @@ -1130,17 +1130,8 @@ do_cache_lookup: ret = ctxt->parse->parse_mount(ap, key, key_len, mapent, ctxt->parse->context); if (ret) { - time_t now = time(NULL); - int rv = CHE_OK; - cache_writelock(mc); - me = cache_lookup_distinct(mc, key); - if (!me) - rv = cache_update(mc, source, key, NULL, now); - if (rv != CHE_FAIL) { - me = cache_lookup_distinct(mc, key); - me->status = now + ap->negative_timeout; - } + cache_update_negative(mc, source, key, ap->negative_timeout); cache_unlock(mc); return NSS_STATUS_TRYAGAIN; } diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c index a59de92..26481a8 100644 --- a/modules/lookup_ldap.c +++ b/modules/lookup_ldap.c @@ -3011,18 +3011,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * ret = ctxt->parse->parse_mount(ap, key, key_len, mapent, ctxt->parse->context); if (ret) { - time_t now = time(NULL); - int rv = CHE_OK; - - /* Record the the mount fail in the cache */ cache_writelock(mc); - me = cache_lookup_distinct(mc, key); - if (!me) - rv = cache_update(mc, source, key, NULL, now); - if (rv != CHE_FAIL) { - me = cache_lookup_distinct(mc, key); - me->status = now + ap->negative_timeout; - } + cache_update_negative(mc, source, key, ap->negative_timeout); cache_unlock(mc); return NSS_STATUS_TRYAGAIN; } diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c index 5c2ed0a..1fe740b 100644 --- a/modules/lookup_sss.c +++ b/modules/lookup_sss.c @@ -672,18 +672,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * ret = ctxt->parse->parse_mount(ap, key, key_len, mapent, ctxt->parse->context); if (ret) { - time_t now = time(NULL); - int rv = CHE_OK; - - /* Record the the mount fail in the cache */ cache_writelock(mc); - me = cache_lookup_distinct(mc, key); - if (!me) - rv = cache_update(mc, source, key, NULL, now); - if (rv != CHE_FAIL) { - me = cache_lookup_distinct(mc, key); - me->status = now + ap->negative_timeout; - } + cache_update_negative(mc, source, key, ap->negative_timeout); cache_unlock(mc); return NSS_STATUS_TRYAGAIN; } diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c index a716e1f..e99e3c0 100644 --- a/modules/lookup_yp.c +++ b/modules/lookup_yp.c @@ -698,18 +698,10 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * ret = ctxt->parse->parse_mount(ap, key, key_len, mapent, ctxt->parse->context); if (ret) { - time_t now = time(NULL); - int rv = CHE_OK; - cache_writelock(mc); - me = cache_lookup_distinct(mc, key); - if (!me) - rv = cache_update(mc, source, key, NULL, now); - if (rv != CHE_FAIL) { - me = cache_lookup_distinct(mc, key); - me->status = now + ap->negative_timeout; - } + cache_update_negative(mc, source, key, ap->negative_timeout); cache_unlock(mc); + return NSS_STATUS_TRYAGAIN; } }