You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

158 lines
5.2 KiB

autofs-5.0.7 - fix potential null dereference in lookup_mount()
From: Ian Kent <raven@themaw.net>
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;
}
}