Blame SOURCES/autofs-5.0.7-fix-potential-null-dereference-in-lookup_mount.patch

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