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

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