- add fixes for bz2147491.
This commit is contained in:
parent
2b852f1510
commit
4c6235a8ea
32
autofs-5.1.8-coverity-fix-for-invalid-access.patch
Normal file
32
autofs-5.1.8-coverity-fix-for-invalid-access.patch
Normal file
@ -0,0 +1,32 @@
|
||||
autofs-5.1.8 - coverity fix for invalid access
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Fix invalid access in modules/parse_amd.c:do_host_mount().
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
modules/parse_amd.c | 1 -
|
||||
2 files changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- autofs-5.1.7.orig/CHANGELOG
|
||||
+++ autofs-5.1.7/CHANGELOG
|
||||
@@ -106,6 +106,7 @@
|
||||
- fix missing unlock in sasl_do_kinit_ext_cc().
|
||||
- fix parse module instance mutex naming.
|
||||
- serialise lookup module open and reinit.
|
||||
+- coverity fix for invalid access.
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
--- autofs-5.1.7.orig/modules/parse_amd.c
|
||||
+++ autofs-5.1.7/modules/parse_amd.c
|
||||
@@ -1366,7 +1366,6 @@ static int do_host_mount(struct autofs_p
|
||||
if (!instance) {
|
||||
error(ap->logopt, MODPREFIX
|
||||
"failed to create source instance for hosts map");
|
||||
- close_lookup(lookup);
|
||||
goto out;
|
||||
}
|
||||
}
|
169
autofs-5.1.8-fix-deadlock-with-hosts-map-reload.patch
Normal file
169
autofs-5.1.8-fix-deadlock-with-hosts-map-reload.patch
Normal file
@ -0,0 +1,169 @@
|
||||
autofs-5.1.8 - fix deadlock with hosts map reload
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
When reloading maps the hosts map calls lookup method ->parse_mount()
|
||||
for each multi-mount root entry in the map (each host) while holding
|
||||
the cache read lock which leads to a cache lock deadlock.
|
||||
|
||||
Remove the need to hold the cache read lock by creating an independent
|
||||
list of entries for the update so the lock doesn't need to be taken.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1
|
||||
modules/lookup_hosts.c | 100 ++++++++++++++++++++++++++++++++++++++++---------
|
||||
2 files changed, 83 insertions(+), 18 deletions(-)
|
||||
|
||||
--- autofs-5.1.7.orig/CHANGELOG
|
||||
+++ autofs-5.1.7/CHANGELOG
|
||||
@@ -108,6 +108,7 @@
|
||||
- serialise lookup module open and reinit.
|
||||
- coverity fix for invalid access.
|
||||
- fix hosts map deadlock on restart.
|
||||
+- fix deadlock with hosts map reload.
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
--- autofs-5.1.7.orig/modules/lookup_hosts.c
|
||||
+++ autofs-5.1.7/modules/lookup_hosts.c
|
||||
@@ -201,10 +201,72 @@ static int do_parse_mount(struct autofs_
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
+struct update_context {
|
||||
+ char *key;
|
||||
+ int key_len;
|
||||
+ char *entry;
|
||||
+ struct update_context *next;
|
||||
+};
|
||||
+
|
||||
+static int add_update_entry(struct update_context **entries, struct mapent *me)
|
||||
+{
|
||||
+ struct update_context *upd;
|
||||
+ char *key, *ent;
|
||||
+
|
||||
+ key = strdup(me->key);
|
||||
+ if (!key)
|
||||
+ return 0;
|
||||
+
|
||||
+ ent = strdup(me->mapent);
|
||||
+ if (!ent) {
|
||||
+ free(key);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ upd = malloc(sizeof(struct update_context));
|
||||
+ if (!upd) {
|
||||
+ free(ent);
|
||||
+ free(key);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ upd->key = key;
|
||||
+ upd->key_len = me->len;
|
||||
+ upd->entry = ent;
|
||||
+ upd->next = NULL;
|
||||
+ if (*entries)
|
||||
+ (*entries)->next = upd;
|
||||
+ *entries = upd;
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static void free_update_entries(struct update_context *entries)
|
||||
+{
|
||||
+ struct update_context *this = entries;
|
||||
+
|
||||
+ while (this) {
|
||||
+ struct update_context *next = this->next;
|
||||
+ free(this->key);
|
||||
+ free(this->entry);
|
||||
+ free(this);
|
||||
+ this = next;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void entries_cleanup(void *arg)
|
||||
+{
|
||||
+ struct update_context *entries = arg;
|
||||
+
|
||||
+ free_update_entries(entries);
|
||||
+}
|
||||
+
|
||||
static void update_hosts_mounts(struct autofs_point *ap,
|
||||
struct map_source *source, time_t age,
|
||||
struct lookup_context *ctxt)
|
||||
{
|
||||
+ struct update_context *head = NULL;
|
||||
+ struct update_context *entries = NULL;
|
||||
struct mapent_cache *mc;
|
||||
struct mapent *me;
|
||||
char *mapent;
|
||||
@@ -212,6 +274,8 @@ static void update_hosts_mounts(struct a
|
||||
|
||||
mc = source->mc;
|
||||
|
||||
+ pthread_cleanup_push(entries_cleanup, head);
|
||||
+
|
||||
pthread_cleanup_push(cache_lock_cleanup, mc);
|
||||
cache_writelock(mc);
|
||||
me = cache_lookup_first(mc);
|
||||
@@ -224,39 +288,39 @@ static void update_hosts_mounts(struct a
|
||||
|
||||
mapent = get_exports(ap, me->key);
|
||||
if (mapent) {
|
||||
- cache_update(mc, source, me->key, mapent, age);
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = cache_update(mc, source, me->key, mapent, age);
|
||||
free(mapent);
|
||||
+ if (!IS_MM_ROOT(me))
|
||||
+ goto next;
|
||||
+ if (ret != CHE_FAIL) {
|
||||
+ if (!add_update_entry(&entries, me))
|
||||
+ warn(ap->logopt, MODPREFIX
|
||||
+ "failed to add update entry for %s", me->key);
|
||||
+ else if (!head)
|
||||
+ head = entries;
|
||||
+ }
|
||||
}
|
||||
next:
|
||||
me = cache_lookup_next(mc, me);
|
||||
}
|
||||
pthread_cleanup_pop(1);
|
||||
|
||||
- pthread_cleanup_push(cache_lock_cleanup, mc);
|
||||
- cache_readlock(mc);
|
||||
- me = cache_lookup_first(mc);
|
||||
- while (me) {
|
||||
- /*
|
||||
- * Hosts map entry not yet expanded, already expired
|
||||
- * or not the base of the tree
|
||||
- */
|
||||
- if (!IS_MM(me) || !IS_MM_ROOT(me))
|
||||
- goto cont;
|
||||
-
|
||||
+ while (head) {
|
||||
debug(ap->logopt, MODPREFIX
|
||||
- "attempt to update exports for %s", me->key);
|
||||
+ "attempt to update exports for %s", head->key);
|
||||
|
||||
master_source_current_wait(ap->entry);
|
||||
ap->entry->current = source;
|
||||
ap->flags |= MOUNT_FLAG_REMOUNT;
|
||||
- ret = ctxt->parse->parse_mount(ap, me->key, strlen(me->key),
|
||||
- me->mapent, ctxt->parse->context);
|
||||
+ ret = ctxt->parse->parse_mount(ap, head->key, strlen(head->key),
|
||||
+ head->entry, ctxt->parse->context);
|
||||
if (ret)
|
||||
warn(ap->logopt, MODPREFIX
|
||||
- "failed to parse mount %s", me->mapent);
|
||||
+ "failed to parse mount %s", head->entry);
|
||||
ap->flags &= ~MOUNT_FLAG_REMOUNT;
|
||||
-cont:
|
||||
- me = cache_lookup_next(mc, me);
|
||||
+ head = head->next;
|
||||
}
|
||||
pthread_cleanup_pop(1);
|
||||
}
|
97
autofs-5.1.8-fix-hosts-map-deadlock-on-restart.patch
Normal file
97
autofs-5.1.8-fix-hosts-map-deadlock-on-restart.patch
Normal file
@ -0,0 +1,97 @@
|
||||
autofs-5.1.8 - fix hosts map deadlock on restart
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
When starting automount(8) with a hosts map that has mounts that were
|
||||
in use at the last exit a deadlock can occur.
|
||||
|
||||
In this case automount(8) will perform the same steps but not actually
|
||||
perform the mount to re-construct the context of each mount. But, with
|
||||
the hosts map, that leads to calling back into the sun parse module
|
||||
while holding the map module read lock which will again try and take
|
||||
the write lock.
|
||||
|
||||
Fix this by only taking the write lock in the mount code path if the
|
||||
module handle has not already been opened.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
daemon/lookup.c | 22 ++++++++++++----------
|
||||
modules/parse_amd.c | 18 ++++++++++--------
|
||||
3 files changed, 23 insertions(+), 18 deletions(-)
|
||||
|
||||
--- autofs-5.1.7.orig/CHANGELOG
|
||||
+++ autofs-5.1.7/CHANGELOG
|
||||
@@ -107,6 +107,7 @@
|
||||
- fix parse module instance mutex naming.
|
||||
- serialise lookup module open and reinit.
|
||||
- coverity fix for invalid access.
|
||||
+- fix hosts map deadlock on restart.
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
--- autofs-5.1.7.orig/daemon/lookup.c
|
||||
+++ autofs-5.1.7/daemon/lookup.c
|
||||
@@ -807,19 +807,21 @@ int do_lookup_mount(struct autofs_point
|
||||
struct lookup_mod *lookup;
|
||||
int status;
|
||||
|
||||
- map_module_writelock(map);
|
||||
if (!map->lookup) {
|
||||
- status = open_lookup(map->type, "",
|
||||
- map->format, map->argc, map->argv, &lookup);
|
||||
- if (status != NSS_STATUS_SUCCESS) {
|
||||
- map_module_unlock(map);
|
||||
- debug(ap->logopt,
|
||||
- "lookup module %s open failed", map->type);
|
||||
- return status;
|
||||
+ map_module_writelock(map);
|
||||
+ if (!map->lookup) {
|
||||
+ status = open_lookup(map->type, "",
|
||||
+ map->format, map->argc, map->argv, &lookup);
|
||||
+ if (status != NSS_STATUS_SUCCESS) {
|
||||
+ map_module_unlock(map);
|
||||
+ debug(ap->logopt,
|
||||
+ "lookup module %s open failed", map->type);
|
||||
+ return status;
|
||||
+ }
|
||||
+ map->lookup = lookup;
|
||||
}
|
||||
- map->lookup = lookup;
|
||||
+ map_module_unlock(map);
|
||||
}
|
||||
- map_module_unlock(map);
|
||||
|
||||
master_source_current_wait(ap->entry);
|
||||
ap->entry->current = map;
|
||||
--- autofs-5.1.7.orig/modules/parse_amd.c
|
||||
+++ autofs-5.1.7/modules/parse_amd.c
|
||||
@@ -1370,17 +1370,19 @@ static int do_host_mount(struct autofs_p
|
||||
}
|
||||
}
|
||||
|
||||
- map_module_writelock(instance);
|
||||
if (!instance->lookup) {
|
||||
- status = open_lookup("hosts", MODPREFIX, NULL, argc, pargv, &lookup);
|
||||
- if (status != NSS_STATUS_SUCCESS) {
|
||||
- map_module_unlock(instance);
|
||||
- debug(ap->logopt, "open lookup module hosts failed");
|
||||
- goto out;
|
||||
+ map_module_writelock(instance);
|
||||
+ if (!instance->lookup) {
|
||||
+ status = open_lookup("hosts", MODPREFIX, NULL, argc, pargv, &lookup);
|
||||
+ if (status != NSS_STATUS_SUCCESS) {
|
||||
+ map_module_unlock(instance);
|
||||
+ debug(ap->logopt, "open lookup module hosts failed");
|
||||
+ goto out;
|
||||
+ }
|
||||
+ instance->lookup = lookup;
|
||||
}
|
||||
- instance->lookup = lookup;
|
||||
+ map_module_unlock(instance);
|
||||
}
|
||||
- map_module_unlock(instance);
|
||||
|
||||
cache_writelock(source->mc);
|
||||
me = cache_lookup_distinct(source->mc, name);
|
53
autofs-5.1.8-fix-memory-leak-in-update_hosts_mounts.patch
Normal file
53
autofs-5.1.8-fix-memory-leak-in-update_hosts_mounts.patch
Normal file
@ -0,0 +1,53 @@
|
||||
autofs-5.1.8 - fix memory leak in update_hosts_mounts()
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Coverity has reported a memory leak in update_hosts_mounts() introduced
|
||||
by the map reload deadlock fix.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
modules/lookup_hosts.c | 13 +++++++------
|
||||
2 files changed, 8 insertions(+), 6 deletions(-)
|
||||
|
||||
--- autofs-5.1.7.orig/CHANGELOG
|
||||
+++ autofs-5.1.7/CHANGELOG
|
||||
@@ -109,6 +109,7 @@
|
||||
- coverity fix for invalid access.
|
||||
- fix hosts map deadlock on restart.
|
||||
- fix deadlock with hosts map reload.
|
||||
+- fix memory leak in update_hosts_mounts().
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
--- autofs-5.1.7.orig/modules/lookup_hosts.c
|
||||
+++ autofs-5.1.7/modules/lookup_hosts.c
|
||||
@@ -307,20 +307,21 @@ next:
|
||||
}
|
||||
pthread_cleanup_pop(1);
|
||||
|
||||
- while (head) {
|
||||
+ entries = head;
|
||||
+ while (entries) {
|
||||
debug(ap->logopt, MODPREFIX
|
||||
- "attempt to update exports for %s", head->key);
|
||||
+ "attempt to update exports for %s", entries->key);
|
||||
|
||||
master_source_current_wait(ap->entry);
|
||||
ap->entry->current = source;
|
||||
ap->flags |= MOUNT_FLAG_REMOUNT;
|
||||
- ret = ctxt->parse->parse_mount(ap, head->key, strlen(head->key),
|
||||
- head->entry, ctxt->parse->context);
|
||||
+ ret = ctxt->parse->parse_mount(ap, entries->key, strlen(entries->key),
|
||||
+ entries->entry, ctxt->parse->context);
|
||||
if (ret)
|
||||
warn(ap->logopt, MODPREFIX
|
||||
- "failed to parse mount %s", head->entry);
|
||||
+ "failed to parse mount %s", entries->entry);
|
||||
ap->flags &= ~MOUNT_FLAG_REMOUNT;
|
||||
- head = head->next;
|
||||
+ entries = entries->next;
|
||||
}
|
||||
pthread_cleanup_pop(1);
|
||||
}
|
183
autofs-5.1.8-fix-parse-module-instance-mutex-naming.patch
Normal file
183
autofs-5.1.8-fix-parse-module-instance-mutex-naming.patch
Normal file
@ -0,0 +1,183 @@
|
||||
autofs-5.1.8 - fix parse module instance mutex naming
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
The naming used for parse module instance locks is the same as that
|
||||
used for map lookup instances. Rename these to make it clear they
|
||||
are being used in the parse modules.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
modules/parse_amd.c | 28 ++++++++++++++--------------
|
||||
modules/parse_sun.c | 20 ++++++++++----------
|
||||
3 files changed, 25 insertions(+), 24 deletions(-)
|
||||
|
||||
--- autofs-5.1.7.orig/CHANGELOG
|
||||
+++ autofs-5.1.7/CHANGELOG
|
||||
@@ -104,6 +104,7 @@
|
||||
- dont use initgroups() at spawn.
|
||||
- fix invalid tsv access.
|
||||
- fix missing unlock in sasl_do_kinit_ext_cc().
|
||||
+- fix parse module instance mutex naming.
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
--- autofs-5.1.7.orig/modules/parse_amd.c
|
||||
+++ autofs-5.1.7/modules/parse_amd.c
|
||||
@@ -39,18 +39,18 @@ int parse_version = AUTOFS_PARSE_VERSION
|
||||
|
||||
static struct mount_mod *mount_nfs = NULL;
|
||||
static int init_ctr = 0;
|
||||
-static pthread_mutex_t instance_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
+static pthread_mutex_t parse_instance_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
-static void instance_mutex_lock(void)
|
||||
+static void parse_instance_mutex_lock(void)
|
||||
{
|
||||
- int status = pthread_mutex_lock(&instance_mutex);
|
||||
+ int status = pthread_mutex_lock(&parse_instance_mutex);
|
||||
if (status)
|
||||
fatal(status);
|
||||
}
|
||||
|
||||
-static void instance_mutex_unlock(void)
|
||||
+static void parse_instance_mutex_unlock(void)
|
||||
{
|
||||
- int status = pthread_mutex_unlock(&instance_mutex);
|
||||
+ int status = pthread_mutex_unlock(&parse_instance_mutex);
|
||||
if (status)
|
||||
fatal(status);
|
||||
}
|
||||
@@ -112,7 +112,7 @@ int parse_init(int argc, const char *con
|
||||
|
||||
/* We only need this once. NFS mounts are so common that we cache
|
||||
this module. */
|
||||
- instance_mutex_lock();
|
||||
+ parse_instance_mutex_lock();
|
||||
if (mount_nfs)
|
||||
init_ctr++;
|
||||
else {
|
||||
@@ -121,11 +121,11 @@ int parse_init(int argc, const char *con
|
||||
} else {
|
||||
kill_context(ctxt);
|
||||
*context = NULL;
|
||||
- instance_mutex_unlock();
|
||||
+ parse_instance_mutex_unlock();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
- instance_mutex_unlock();
|
||||
+ parse_instance_mutex_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1358,11 +1358,11 @@ static int do_host_mount(struct autofs_p
|
||||
argc = 1;
|
||||
}
|
||||
|
||||
- instance_mutex_lock();
|
||||
+ parse_instance_mutex_lock();
|
||||
status = open_lookup("hosts", MODPREFIX, NULL, argc, pargv, &lookup);
|
||||
if (status != NSS_STATUS_SUCCESS) {
|
||||
debug(ap->logopt, "open lookup module hosts failed");
|
||||
- instance_mutex_unlock();
|
||||
+ parse_instance_mutex_unlock();
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1374,13 +1374,13 @@ static int do_host_mount(struct autofs_p
|
||||
if (!instance) {
|
||||
error(ap->logopt, MODPREFIX
|
||||
"failed to create source instance for hosts map");
|
||||
- instance_mutex_unlock();
|
||||
+ parse_instance_mutex_unlock();
|
||||
close_lookup(lookup);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
instance->lookup = lookup;
|
||||
- instance_mutex_unlock();
|
||||
+ parse_instance_mutex_unlock();
|
||||
|
||||
cache_writelock(source->mc);
|
||||
me = cache_lookup_distinct(source->mc, name);
|
||||
@@ -2373,12 +2373,12 @@ int parse_done(void *context)
|
||||
int rv = 0;
|
||||
struct parse_context *ctxt = (struct parse_context *) context;
|
||||
|
||||
- instance_mutex_lock();
|
||||
+ parse_instance_mutex_lock();
|
||||
if (--init_ctr == 0) {
|
||||
rv = close_mount(mount_nfs);
|
||||
mount_nfs = NULL;
|
||||
}
|
||||
- instance_mutex_unlock();
|
||||
+ parse_instance_mutex_unlock();
|
||||
if (ctxt)
|
||||
kill_context(ctxt);
|
||||
|
||||
--- autofs-5.1.7.orig/modules/parse_sun.c
|
||||
+++ autofs-5.1.7/modules/parse_sun.c
|
||||
@@ -41,18 +41,18 @@ int parse_version = AUTOFS_PARSE_VERSION
|
||||
|
||||
static struct mount_mod *mount_nfs = NULL;
|
||||
static int init_ctr = 0;
|
||||
-static pthread_mutex_t instance_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
+static pthread_mutex_t parse_instance_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
-static void instance_mutex_lock(void)
|
||||
+static void parse_instance_mutex_lock(void)
|
||||
{
|
||||
- int status = pthread_mutex_lock(&instance_mutex);
|
||||
+ int status = pthread_mutex_lock(&parse_instance_mutex);
|
||||
if (status)
|
||||
fatal(status);
|
||||
}
|
||||
|
||||
-static void instance_mutex_unlock(void)
|
||||
+static void parse_instance_mutex_unlock(void)
|
||||
{
|
||||
- int status = pthread_mutex_unlock(&instance_mutex);
|
||||
+ int status = pthread_mutex_unlock(&parse_instance_mutex);
|
||||
if (status)
|
||||
fatal(status);
|
||||
}
|
||||
@@ -424,7 +424,7 @@ int parse_init(int argc, const char *con
|
||||
|
||||
/* We only need this once. NFS mounts are so common that we cache
|
||||
this module. */
|
||||
- instance_mutex_lock();
|
||||
+ parse_instance_mutex_lock();
|
||||
if (mount_nfs)
|
||||
init_ctr++;
|
||||
else {
|
||||
@@ -432,11 +432,11 @@ int parse_init(int argc, const char *con
|
||||
init_ctr++;
|
||||
} else {
|
||||
kill_context(ctxt);
|
||||
- instance_mutex_unlock();
|
||||
+ parse_instance_mutex_unlock();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
- instance_mutex_unlock();
|
||||
+ parse_instance_mutex_unlock();
|
||||
|
||||
*context = (void *) ctxt;
|
||||
|
||||
@@ -1728,12 +1728,12 @@ int parse_done(void *context)
|
||||
int rv = 0;
|
||||
struct parse_context *ctxt = (struct parse_context *) context;
|
||||
|
||||
- instance_mutex_lock();
|
||||
+ parse_instance_mutex_lock();
|
||||
if (--init_ctr == 0) {
|
||||
rv = close_mount(mount_nfs);
|
||||
mount_nfs = NULL;
|
||||
}
|
||||
- instance_mutex_unlock();
|
||||
+ parse_instance_mutex_unlock();
|
||||
if (ctxt)
|
||||
kill_context(ctxt);
|
||||
|
272
autofs-5.1.8-serialise-lookup-module-open-and-reinit.patch
Normal file
272
autofs-5.1.8-serialise-lookup-module-open-and-reinit.patch
Normal file
@ -0,0 +1,272 @@
|
||||
autofs-5.1.8 - serialise lookup module open and reinit
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Add a map source lock to serialise map setting and use of module
|
||||
structure fields such as the context.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
daemon/lookup.c | 35 +++++++++++++++++++++--------------
|
||||
daemon/master.c | 43 +++++++++++++++++++++++++++++++++++++++++++
|
||||
include/master.h | 5 +++++
|
||||
modules/parse_amd.c | 26 +++++++++++++++-----------
|
||||
5 files changed, 85 insertions(+), 25 deletions(-)
|
||||
|
||||
--- autofs-5.1.7.orig/CHANGELOG
|
||||
+++ autofs-5.1.7/CHANGELOG
|
||||
@@ -105,6 +105,7 @@
|
||||
- fix invalid tsv access.
|
||||
- fix missing unlock in sasl_do_kinit_ext_cc().
|
||||
- fix parse module instance mutex naming.
|
||||
+- serialise lookup module open and reinit.
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
--- autofs-5.1.7.orig/daemon/lookup.c
|
||||
+++ autofs-5.1.7/daemon/lookup.c
|
||||
@@ -318,28 +318,27 @@ static int do_read_map(struct autofs_poi
|
||||
struct lookup_mod *lookup;
|
||||
int status;
|
||||
|
||||
- lookup = NULL;
|
||||
- master_source_writelock(ap->entry);
|
||||
+ pthread_cleanup_push(map_module_lock_cleanup, map);
|
||||
+ map_module_writelock(map);
|
||||
if (!map->lookup) {
|
||||
status = open_lookup(map->type, "", map->format,
|
||||
map->argc, map->argv, &lookup);
|
||||
- if (status != NSS_STATUS_SUCCESS) {
|
||||
- master_source_unlock(ap->entry);
|
||||
+ if (status == NSS_STATUS_SUCCESS)
|
||||
+ map->lookup = lookup;
|
||||
+ else
|
||||
debug(ap->logopt,
|
||||
"lookup module %s open failed", map->type);
|
||||
- return status;
|
||||
- }
|
||||
- map->lookup = lookup;
|
||||
} else {
|
||||
- lookup = map->lookup;
|
||||
- status = lookup->lookup_reinit(map->format,
|
||||
- map->argc, map->argv,
|
||||
- &lookup->context);
|
||||
+ status = map->lookup->lookup_reinit(map->format,
|
||||
+ map->argc, map->argv,
|
||||
+ &map->lookup->context);
|
||||
if (status)
|
||||
warn(ap->logopt,
|
||||
"lookup module %s reinit failed", map->type);
|
||||
}
|
||||
- master_source_unlock(ap->entry);
|
||||
+ pthread_cleanup_pop(1);
|
||||
+ if (status != NSS_STATUS_SUCCESS)
|
||||
+ return status;
|
||||
|
||||
if (!map->stale)
|
||||
return NSS_STATUS_SUCCESS;
|
||||
@@ -347,7 +346,11 @@ static int do_read_map(struct autofs_poi
|
||||
master_source_current_wait(ap->entry);
|
||||
ap->entry->current = map;
|
||||
|
||||
+ pthread_cleanup_push(map_module_lock_cleanup, map);
|
||||
+ map_module_readlock(map);
|
||||
+ lookup = map->lookup;
|
||||
status = lookup->lookup_read_map(ap, age, lookup->context);
|
||||
+ pthread_cleanup_pop(1);
|
||||
|
||||
if (status != NSS_STATUS_SUCCESS)
|
||||
map->stale = 0;
|
||||
@@ -804,23 +807,27 @@ int do_lookup_mount(struct autofs_point
|
||||
struct lookup_mod *lookup;
|
||||
int status;
|
||||
|
||||
+ map_module_writelock(map);
|
||||
if (!map->lookup) {
|
||||
status = open_lookup(map->type, "",
|
||||
map->format, map->argc, map->argv, &lookup);
|
||||
if (status != NSS_STATUS_SUCCESS) {
|
||||
+ map_module_unlock(map);
|
||||
debug(ap->logopt,
|
||||
"lookup module %s open failed", map->type);
|
||||
return status;
|
||||
}
|
||||
map->lookup = lookup;
|
||||
}
|
||||
-
|
||||
- lookup = map->lookup;
|
||||
+ map_module_unlock(map);
|
||||
|
||||
master_source_current_wait(ap->entry);
|
||||
ap->entry->current = map;
|
||||
|
||||
+ map_module_readlock(map);
|
||||
+ lookup = map->lookup;
|
||||
status = lookup->lookup_mount(ap, name, name_len, lookup->context);
|
||||
+ map_module_unlock(map);
|
||||
|
||||
return status;
|
||||
}
|
||||
--- autofs-5.1.7.orig/daemon/master.c
|
||||
+++ autofs-5.1.7/daemon/master.c
|
||||
@@ -65,6 +65,34 @@ void master_mutex_lock_cleanup(void *arg
|
||||
return;
|
||||
}
|
||||
|
||||
+void map_module_writelock(struct map_source *map)
|
||||
+{
|
||||
+ int status = pthread_rwlock_wrlock(&map->module_lock);
|
||||
+ if (status)
|
||||
+ fatal(status);
|
||||
+}
|
||||
+
|
||||
+void map_module_readlock(struct map_source *map)
|
||||
+{
|
||||
+ int status = pthread_rwlock_rdlock(&map->module_lock);
|
||||
+ if (status)
|
||||
+ fatal(status);
|
||||
+}
|
||||
+
|
||||
+void map_module_unlock(struct map_source *map)
|
||||
+{
|
||||
+ int status = pthread_rwlock_unlock(&map->module_lock);
|
||||
+ if (status)
|
||||
+ fatal(status);
|
||||
+}
|
||||
+
|
||||
+void map_module_lock_cleanup(void *arg)
|
||||
+{
|
||||
+ struct map_source *map = (struct map_source *) arg;
|
||||
+
|
||||
+ map_module_unlock(map);
|
||||
+}
|
||||
+
|
||||
int master_add_autofs_point(struct master_mapent *entry, unsigned logopt,
|
||||
unsigned nobind, unsigned ghost, int submount)
|
||||
{
|
||||
@@ -155,6 +183,7 @@ master_add_map_source(struct master_mape
|
||||
struct map_source *source;
|
||||
char *ntype, *nformat;
|
||||
const char **tmpargv;
|
||||
+ int status;
|
||||
|
||||
source = malloc(sizeof(struct map_source));
|
||||
if (!source)
|
||||
@@ -241,6 +270,10 @@ master_add_map_source(struct master_mape
|
||||
|
||||
master_source_unlock(entry);
|
||||
|
||||
+ status = pthread_rwlock_init(&source->module_lock, NULL);
|
||||
+ if (status)
|
||||
+ fatal(status);
|
||||
+
|
||||
return source;
|
||||
}
|
||||
|
||||
@@ -330,6 +363,8 @@ master_get_map_source(struct master_mape
|
||||
|
||||
static void __master_free_map_source(struct map_source *source, unsigned int free_cache)
|
||||
{
|
||||
+ int status;
|
||||
+
|
||||
/* instance map sources are not ref counted */
|
||||
if (source->ref && --source->ref)
|
||||
return;
|
||||
@@ -365,6 +400,10 @@ static void __master_free_map_source(str
|
||||
}
|
||||
}
|
||||
|
||||
+ status = pthread_rwlock_destroy(&source->module_lock);
|
||||
+ if (status)
|
||||
+ fatal(status);
|
||||
+
|
||||
free(source);
|
||||
|
||||
return;
|
||||
@@ -496,6 +535,10 @@ master_add_source_instance(struct map_so
|
||||
if (status)
|
||||
fatal(status);
|
||||
|
||||
+ status = pthread_rwlock_init(&new->module_lock, NULL);
|
||||
+ if (status)
|
||||
+ fatal(status);
|
||||
+
|
||||
return new;
|
||||
}
|
||||
|
||||
--- autofs-5.1.7.orig/include/master.h
|
||||
+++ autofs-5.1.7/include/master.h
|
||||
@@ -35,6 +35,7 @@ struct map_source {
|
||||
unsigned int stale;
|
||||
unsigned int recurse;
|
||||
unsigned int depth;
|
||||
+ pthread_rwlock_t module_lock;
|
||||
struct lookup_mod *lookup;
|
||||
int argc;
|
||||
const char **argv;
|
||||
@@ -126,5 +127,9 @@ int __master_list_empty(struct master *)
|
||||
int master_list_empty(struct master *);
|
||||
int master_done(struct master *);
|
||||
int master_kill(struct master *);
|
||||
+void map_module_writelock(struct map_source *map);
|
||||
+void map_module_readlock(struct map_source *map);
|
||||
+void map_module_unlock(struct map_source *map);
|
||||
+void map_module_lock_cleanup(void *arg);
|
||||
|
||||
#endif
|
||||
--- autofs-5.1.7.orig/modules/parse_amd.c
|
||||
+++ autofs-5.1.7/modules/parse_amd.c
|
||||
@@ -1358,14 +1358,6 @@ static int do_host_mount(struct autofs_p
|
||||
argc = 1;
|
||||
}
|
||||
|
||||
- parse_instance_mutex_lock();
|
||||
- status = open_lookup("hosts", MODPREFIX, NULL, argc, pargv, &lookup);
|
||||
- if (status != NSS_STATUS_SUCCESS) {
|
||||
- debug(ap->logopt, "open lookup module hosts failed");
|
||||
- parse_instance_mutex_unlock();
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
instance = master_find_source_instance(source,
|
||||
"hosts", "sun", argc, pargv);
|
||||
if (!instance) {
|
||||
@@ -1374,13 +1366,22 @@ static int do_host_mount(struct autofs_p
|
||||
if (!instance) {
|
||||
error(ap->logopt, MODPREFIX
|
||||
"failed to create source instance for hosts map");
|
||||
- parse_instance_mutex_unlock();
|
||||
close_lookup(lookup);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
- instance->lookup = lookup;
|
||||
- parse_instance_mutex_unlock();
|
||||
+
|
||||
+ map_module_writelock(instance);
|
||||
+ if (!instance->lookup) {
|
||||
+ status = open_lookup("hosts", MODPREFIX, NULL, argc, pargv, &lookup);
|
||||
+ if (status != NSS_STATUS_SUCCESS) {
|
||||
+ map_module_unlock(instance);
|
||||
+ debug(ap->logopt, "open lookup module hosts failed");
|
||||
+ goto out;
|
||||
+ }
|
||||
+ instance->lookup = lookup;
|
||||
+ }
|
||||
+ map_module_unlock(instance);
|
||||
|
||||
cache_writelock(source->mc);
|
||||
me = cache_lookup_distinct(source->mc, name);
|
||||
@@ -1391,8 +1392,11 @@ static int do_host_mount(struct autofs_p
|
||||
master_source_current_wait(ap->entry);
|
||||
ap->entry->current = source;
|
||||
|
||||
+ map_module_readlock(instance);
|
||||
+ lookup = instance->lookup;
|
||||
ret = lookup->lookup_mount(ap, entry->rhost,
|
||||
strlen(entry->rhost), lookup->context);
|
||||
+ map_module_unlock(instance);
|
||||
|
||||
if (!strcmp(name, entry->rhost))
|
||||
goto out;
|
25
autofs.spec
25
autofs.spec
@ -12,7 +12,7 @@
|
||||
Summary: A tool for automatically mounting and unmounting filesystems
|
||||
Name: autofs
|
||||
Version: 5.1.7
|
||||
Release: 33%{?dist}
|
||||
Release: 34%{?dist}
|
||||
Epoch: 1
|
||||
License: GPLv2+
|
||||
Source: https://www.kernel.org/pub/linux/daemons/autofs/v5/autofs-%{version}-2.tar.gz
|
||||
@ -130,6 +130,12 @@ Patch102: autofs-5.1.8-fix-nfsv4-only-mounts-should-not-use-rpcbind.patch
|
||||
Patch103: autofs-5.1.8-dont-use-initgroups-at-spawn.patch
|
||||
Patch104: autofs-5.1.8-fix-invalid-tsv-access.patch
|
||||
Patch105: autofs-5.1.8-fix-missing-unlock-in-sasl_do_kinit_ext_cc.patch
|
||||
Patch106: autofs-5.1.8-fix-parse-module-instance-mutex-naming.patch
|
||||
Patch107: autofs-5.1.8-serialise-lookup-module-open-and-reinit.patch
|
||||
Patch108: autofs-5.1.8-coverity-fix-for-invalid-access.patch
|
||||
Patch109: autofs-5.1.8-fix-hosts-map-deadlock-on-restart.patch
|
||||
Patch110: autofs-5.1.8-fix-deadlock-with-hosts-map-reload.patch
|
||||
Patch111: autofs-5.1.8-fix-memory-leak-in-update_hosts_mounts.patch
|
||||
|
||||
%if %{with_systemd}
|
||||
BuildRequires: systemd-units
|
||||
@ -304,6 +310,12 @@ echo %{version}-%{release} > .version
|
||||
%patch103 -p1
|
||||
%patch104 -p1
|
||||
%patch105 -p1
|
||||
%patch106 -p1
|
||||
%patch107 -p1
|
||||
%patch108 -p1
|
||||
%patch109 -p1
|
||||
%patch110 -p1
|
||||
%patch111 -p1
|
||||
|
||||
%build
|
||||
LDFLAGS=-Wl,-z,now
|
||||
@ -412,6 +424,17 @@ fi
|
||||
%dir /etc/auto.master.d
|
||||
|
||||
%changelog
|
||||
* Tue Nov 29 2022 Ian Kent <ikent@redhat.com> - 1:5.1.7-34
|
||||
- bz2147491 - segfault due to lookup_mod->context address being freed
|
||||
and reused while multiple threads were using it
|
||||
- fix parse module instance mutex naming.
|
||||
- serialise lookup module open and reinit.
|
||||
- coverity fix for invalid access.
|
||||
- fix hosts map deadlock on restart.
|
||||
- fix deadlock with hosts map reload.
|
||||
- fix memory leak in update_hosts_mounts().
|
||||
- Resolves: rhbz#2147491
|
||||
|
||||
* Mon Oct 31 2022 Ian Kent <ikent@redhat.com> - 1:5.1.7-33
|
||||
- bz2131907 - autofs: missing unlock in sasl_do_kinit_ext_cc()
|
||||
- fix missing unlock in sasl_do_kinit_ext_cc().
|
||||
|
Loading…
Reference in New Issue
Block a user