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