diff --git a/SOURCES/autofs-5.1.8-coverity-fix-for-invalid-access.patch b/SOURCES/autofs-5.1.8-coverity-fix-for-invalid-access.patch new file mode 100644 index 0000000..d5b8d74 --- /dev/null +++ b/SOURCES/autofs-5.1.8-coverity-fix-for-invalid-access.patch @@ -0,0 +1,32 @@ +autofs-5.1.8 - coverity fix for invalid access + +From: Ian Kent + +Fix invalid access in modules/parse_amd.c:do_host_mount(). + +Signed-off-by: Ian Kent +--- + 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; + } + } diff --git a/SOURCES/autofs-5.1.8-fix-deadlock-with-hosts-map-reload.patch b/SOURCES/autofs-5.1.8-fix-deadlock-with-hosts-map-reload.patch new file mode 100644 index 0000000..0a5ba63 --- /dev/null +++ b/SOURCES/autofs-5.1.8-fix-deadlock-with-hosts-map-reload.patch @@ -0,0 +1,169 @@ +autofs-5.1.8 - fix deadlock with hosts map reload + +From: Ian Kent + +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 +--- + 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); + } diff --git a/SOURCES/autofs-5.1.8-fix-hosts-map-deadlock-on-restart.patch b/SOURCES/autofs-5.1.8-fix-hosts-map-deadlock-on-restart.patch new file mode 100644 index 0000000..2cb65c2 --- /dev/null +++ b/SOURCES/autofs-5.1.8-fix-hosts-map-deadlock-on-restart.patch @@ -0,0 +1,97 @@ +autofs-5.1.8 - fix hosts map deadlock on restart + +From: Ian Kent + +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 +--- + 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); diff --git a/SOURCES/autofs-5.1.8-fix-incorrect-path-for-is_mounted-in-try_remount.patch b/SOURCES/autofs-5.1.8-fix-incorrect-path-for-is_mounted-in-try_remount.patch new file mode 100644 index 0000000..ea4de04 --- /dev/null +++ b/SOURCES/autofs-5.1.8-fix-incorrect-path-for-is_mounted-in-try_remount.patch @@ -0,0 +1,63 @@ +autofs-5.1.8 - fix incorrect path for is_mounted() in try_remount() + +From: Ian Kent + +A regression was introduced when the offset mount handling was rewritten. + +It resulted in an incorrect path sometimes being used in an is_mounted() +check. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 26 +++++++++++++++++++++----- + 2 files changed, 22 insertions(+), 5 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -111,6 +111,7 @@ + - fix deadlock with hosts map reload. + - fix memory leak in update_hosts_mounts(). + - fix minus only option handling in concat_options(). ++- fix incorrect path for is_mounted() in try_remount(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/lib/mounts.c ++++ autofs-5.1.7/lib/mounts.c +@@ -2803,14 +2803,30 @@ int try_remount(struct autofs_point *ap, + ap->flags &= ~MOUNT_FLAG_DIR_CREATED; + else + ap->flags |= MOUNT_FLAG_DIR_CREATED; ++ goto done; ++ } ++ ++ me->flags &= ~MOUNT_FLAG_DIR_CREATED; ++ /* Direct or offset mount, key is full path */ ++ if (MM_PARENT(me)->key[0] == '/') { ++ if (!is_mounted(MM_PARENT(me)->key, MNTS_REAL)) ++ me->flags |= MOUNT_FLAG_DIR_CREATED; + } else { +- me->flags &= ~MOUNT_FLAG_DIR_CREATED; +- if (type == t_offset) { +- if (!is_mounted(MM_PARENT(me)->key, MNTS_REAL)) +- me->flags |= MOUNT_FLAG_DIR_CREATED; ++ char *p_key = MM_PARENT(me)->key; ++ char mp[PATH_MAX + 1]; ++ int len; ++ ++ len = mount_fullpath(mp, PATH_MAX, ap->path, ap->len, p_key); ++ if (len > PATH_MAX) { ++ /* This should never happen due to earlier checks */ ++ error(ap->logopt, "mountpoint path too long"); ++ return 0; + } +- } + ++ if (!is_mounted(mp, MNTS_REAL)) ++ me->flags |= MOUNT_FLAG_DIR_CREATED; ++ } ++done: + /* + * Either we opened the mount or we're re-reading the map. + * If we opened the mount and ioctlfd is not -1 we have diff --git a/SOURCES/autofs-5.1.8-fix-memory-leak-in-update_hosts_mounts.patch b/SOURCES/autofs-5.1.8-fix-memory-leak-in-update_hosts_mounts.patch new file mode 100644 index 0000000..ac02f51 --- /dev/null +++ b/SOURCES/autofs-5.1.8-fix-memory-leak-in-update_hosts_mounts.patch @@ -0,0 +1,53 @@ +autofs-5.1.8 - fix memory leak in update_hosts_mounts() + +From: Ian Kent + +Coverity has reported a memory leak in update_hosts_mounts() introduced +by the map reload deadlock fix. + +Signed-off-by: Ian Kent +--- + 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); + } diff --git a/SOURCES/autofs-5.1.8-fix-minus-only-option-handling-in-concat_options.patch b/SOURCES/autofs-5.1.8-fix-minus-only-option-handling-in-concat_options.patch new file mode 100644 index 0000000..717affd --- /dev/null +++ b/SOURCES/autofs-5.1.8-fix-minus-only-option-handling-in-concat_options.patch @@ -0,0 +1,88 @@ +autofs-5.1.8 - fix minus only option handling in concat_options() + +From: Ian Kent + +While a '-' alone isn't strictly valid it hadn't previously cuased a +parse error. So commit 9047e91ffa69 (autofs-5.1.7 - fix concat_options() +error handling) introduced a regression by no longer allowing this. + +Fix this regression by only failing if errno is set to a non-zero value +on return from concat_options() as well as returning NULL. + +Fixes: 9047e91ffa69 (autofs-5.1.7 - fix concat_options() error handling) +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 25 +++++++++++++++++++------ + 2 files changed, 20 insertions(+), 6 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -110,6 +110,7 @@ + - fix hosts map deadlock on restart. + - fix deadlock with hosts map reload. + - fix memory leak in update_hosts_mounts(). ++- fix minus only option handling in concat_options(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/modules/parse_sun.c ++++ autofs-5.1.7/modules/parse_sun.c +@@ -376,10 +376,16 @@ static int do_init(int argc, const char + if (gbl_options) { + append_options = defaults_get_append_options(); + if (append_options) { +- char *tmp = concat_options(gbl_options, ctxt->optstr); ++ char *tmp; ++ ++ errno = 0; ++ tmp = concat_options(gbl_options, ctxt->optstr); + if (!tmp) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr(MODPREFIX "concat_options: %s", estr); ++ /* Ignore non-error NULL return */ ++ if (errno) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "concat_options: %s", estr); ++ } + /* freed in concat_options */ + ctxt->optstr = NULL; + } else +@@ -1007,9 +1013,12 @@ static int parse_mapent(const char *ent, + free(myoptions); + myoptions = newopt; + } else if (newopt) { ++ errno = 0; + tmp = concat_options(myoptions, newopt); +- if (!tmp) { ++ /* Ignore non-error NULL return */ ++ if (!tmp && errno) { + char *estr; ++ + estr = strerror_r(errno, buf, MAX_ERR_BUF); + error(logopt, MODPREFIX + "concat_options: %s", estr); +@@ -1381,8 +1390,10 @@ dont_expand: + free(mnt_options); + mnt_options = noptions; + } else if (noptions) { ++ errno = 0; + tmp = concat_options(mnt_options, noptions); +- if (!tmp) { ++ /* Ignore non-error NULL return */ ++ if (!tmp && errno) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + error(ap->logopt, + MODPREFIX "concat_options: %s", estr); +@@ -1406,8 +1417,10 @@ dont_expand: + free(options); + options = mnt_options; + } else if (mnt_options) { ++ errno = 0; + tmp = concat_options(options, mnt_options); +- if (!tmp) { ++ /* Ignore non-error NULL return */ ++ if (!tmp && errno) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + error(ap->logopt, MODPREFIX "concat_options: %s", estr); + free(pmapent); diff --git a/SOURCES/autofs-5.1.8-fix-missing-unlock-in-sasl_do_kinit_ext_cc.patch b/SOURCES/autofs-5.1.8-fix-missing-unlock-in-sasl_do_kinit_ext_cc.patch new file mode 100644 index 0000000..81b66dc --- /dev/null +++ b/SOURCES/autofs-5.1.8-fix-missing-unlock-in-sasl_do_kinit_ext_cc.patch @@ -0,0 +1,37 @@ +autofs-5.1.8 - fix missing unlock in sasl_do_kinit_ext_cc() + +From: James Dingwall + +There is a missing mutex unlock in function sasl_do_kinit_ext_cc(), +fix it. + +Signed-off-by: James Dingwall +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/cyrus-sasl.c | 4 ++++ + 2 files changed, 5 insertions(+) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -103,6 +103,7 @@ + - fix nfsv4 only mounts should not use rpcbind. + - dont use initgroups() at spawn. + - fix invalid tsv access. ++- fix missing unlock in sasl_do_kinit_ext_cc(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/modules/cyrus-sasl.c ++++ autofs-5.1.7/modules/cyrus-sasl.c +@@ -721,6 +721,10 @@ sasl_do_kinit_ext_cc(unsigned logopt, st + + debug(logopt, "Kerberos authentication was successful!"); + ++ status = pthread_mutex_unlock(&krb5cc_mutex); ++ if (status) ++ fatal(status); ++ + return 0; + + out_cleanup_def_princ: diff --git a/SOURCES/autofs-5.1.8-fix-parse-module-instance-mutex-naming.patch b/SOURCES/autofs-5.1.8-fix-parse-module-instance-mutex-naming.patch new file mode 100644 index 0000000..2f929d8 --- /dev/null +++ b/SOURCES/autofs-5.1.8-fix-parse-module-instance-mutex-naming.patch @@ -0,0 +1,183 @@ +autofs-5.1.8 - fix parse module instance mutex naming + +From: Ian Kent + +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 +--- + 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); + diff --git a/SOURCES/autofs-5.1.8-serialise-lookup-module-open-and-reinit.patch b/SOURCES/autofs-5.1.8-serialise-lookup-module-open-and-reinit.patch new file mode 100644 index 0000000..0f7425d --- /dev/null +++ b/SOURCES/autofs-5.1.8-serialise-lookup-module-open-and-reinit.patch @@ -0,0 +1,272 @@ +autofs-5.1.8 - serialise lookup module open and reinit + +From: Ian Kent + +Add a map source lock to serialise map setting and use of module +structure fields such as the context. + +Signed-off-by: Ian Kent +--- + 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; diff --git a/SPECS/autofs.spec b/SPECS/autofs.spec index e8cec87..4e237df 100644 --- a/SPECS/autofs.spec +++ b/SPECS/autofs.spec @@ -12,7 +12,7 @@ Summary: A tool for automatically mounting and unmounting filesystems Name: autofs Version: 5.1.7 -Release: 32%{?dist}.1 +Release: 36%{?dist} Epoch: 1 License: GPLv2+ Source: https://www.kernel.org/pub/linux/daemons/autofs/v5/autofs-%{version}-2.tar.gz @@ -129,6 +129,15 @@ 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 +Patch112: autofs-5.1.8-fix-minus-only-option-handling-in-concat_options.patch +Patch113: autofs-5.1.8-fix-incorrect-path-for-is_mounted-in-try_remount.patch %if %{with_systemd} BuildRequires: systemd-units @@ -302,6 +311,15 @@ echo %{version}-%{release} > .version %patch103 -p1 %patch104 -p1 +%patch105 -p1 +%patch106 -p1 +%patch107 -p1 +%patch108 -p1 +%patch109 -p1 +%patch110 -p1 +%patch111 -p1 +%patch112 -p1 +%patch113 -p1 %build LDFLAGS=-Wl,-z,now @@ -410,15 +428,40 @@ fi %dir /etc/auto.master.d %changelog -* Fri Feb 03 2023 Ian Kent - 1:5.1.7-32.el9_1.1 -- bz2166144 - automount -m crashes with Segmentation fault (core dumped) - - fix incorrect changelog date. -- Related: rhbz#2166144 +* Tue Dec 06 2022 Ian Kent - 1:5.1.7-36 +- bz2149013 - autofs: errors in autofs-5.1.4-83.el8.x86_64 when restarting + autofs with busy directories + - fix incorrect path for is_mounted() in try_remount(). +- Resolves: rhbz#2149013 -* Fri Feb 03 2023 Ian Kent - 1:5.1.7-32.el9_1 -- bz2166144 - automount -m crashes with Segmentation fault (core dumped) +* Wed Nov 30 2022 Ian Kent - 1:5.1.7-35 +- bz2145251 - RHEL9: automount does not handle null option string after + "-" anymore + - fix minus only option handling in concat_options(). +- Resolves: rhbz#2145251 + +* Tue Nov 29 2022 Ian Kent - 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 - 1:5.1.7-33 +- bz2131907 - autofs: missing unlock in sasl_do_kinit_ext_cc() + - fix missing unlock in sasl_do_kinit_ext_cc(). +- Resolves: rhbz#2131907 + +* Tue Oct 04 2022 Ian Kent - 1:5.1.7-32 +- bz2122565 - automount -m crashes with Segmentation fault (core dumped) - fix invalid tsv access. -- Resolves: rhbz#2166144 +- bz2126176 - autofs: %changelog entries are out of order + - fix changelog date of out of order entry. +- Resolves: rhbz#2122565 rhbz#2126176 * Mon May 30 2022 Ian Kent - 1:5.1.7-31 - bz2087535 - libnss_sss: threads stuck at sss_nss_lock from initgroups @@ -557,7 +600,7 @@ fi - fix incorrect changelog revision. - Resolves: rhbz#1942371 -* Tue Apr 13 2021 Ian Kent - 1:5.1.7-12 +* Fri Apr 16 2021 Ian Kent - 1:5.1.7-12 - bz1948956 - Using -hosts option does not resolve host from /etc/hosts and mount failes - Coverity fixes (arising from RHEL-8 bug 1912106)