diff --git a/autofs-5.1.9-fix-deadlock-in-master_notify_submount.patch b/autofs-5.1.9-fix-deadlock-in-master_notify_submount.patch new file mode 100644 index 0000000..2e9630d --- /dev/null +++ b/autofs-5.1.9-fix-deadlock-in-master_notify_submount.patch @@ -0,0 +1,66 @@ +autofs-5.1.9 - fix deadlock in master_notify_submount() + +From: Ian Kent + +A deadlock between mnts_remove_submount() and master_notify_submount() +can occur because master_notify_submount() holds the state mutex over +a call to mnts_find_submount() which then needs to take mnts_hash_mutex. +But mnts_remove_submount() takes mnts_hash_mutex and then needs to take +the state mutex to clear the ->ap field so deadlock cann occur. + +But it isn't necessary for master_notify_submount() to take the state +mutex before calling mnts_find_submount() because if the submount is' +found a reference is taken on the entry so it won't go away while it's +being used. All that's needed is to ensure that the ->ap field doesn't +get set to NULL by mnts_remove_submount() while it's being used to check +if the submount has shutdown. + +Fixes: 81ac572466e3 ("autofs-5.1.9 - fix submount shutdown race") +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/master.c | 7 +++---- + 2 files changed, 4 insertions(+), 4 deletions(-) + +--- autofs-5.1.9.orig/CHANGELOG ++++ autofs-5.1.9/CHANGELOG +@@ -18,6 +18,7 @@ + - refactor amd mount options handling. + - add some unimplemented amd map options. + - fix submount shutdown race. ++- fix deadlock in master_notify_submount(). + + 02/11/2023 autofs-5.1.9 + - fix kernel mount status notification. +--- autofs-5.1.9.orig/daemon/master.c ++++ autofs-5.1.9/daemon/master.c +@@ -1246,26 +1246,25 @@ int master_notify_submount(struct autofs + * ST_SHUTDOWN_FORCE we need to wait until it goes away + * or changes to state ST_SHUTDOWN or ST_READY. + */ +- st_mutex_lock(); + while ((sbmnt = mnts_find_submount(path))) { + struct timespec t = { 0, 300000000 }; + struct timespec r; + ++ st_mutex_lock(); + if (!sbmnt->ap || + (sbmnt->ap->state != ST_SHUTDOWN_PENDING && + sbmnt->ap->state != ST_SHUTDOWN_FORCE)) { + ret = 0; ++ st_mutex_unlock(); + mnts_put_mount(sbmnt); + break; + } ++ st_mutex_unlock(); + mnts_put_mount(sbmnt); + +- st_mutex_unlock(); + while (nanosleep(&t, &r) == -1 && errno == EINTR) + memcpy(&t, &r, sizeof(struct timespec)); +- st_mutex_lock(); + } +- st_mutex_unlock(); + done: + mnts_put_mount(this); + } diff --git a/autofs-5.1.9-fix-handling-of-ignored-offsets.patch b/autofs-5.1.9-fix-handling-of-ignored-offsets.patch new file mode 100644 index 0000000..3ac77c0 --- /dev/null +++ b/autofs-5.1.9-fix-handling-of-ignored-offsets.patch @@ -0,0 +1,89 @@ +autofs-5.1.9 - fix handling of ignored offsets + +From: Ian Kent + +If a map entry offset path already has a real mount mounted on it then +it's ignored as it has very likely been auto-mounted by the NFS client. + +But we have seen a case were autofs incorrectly makes a function call +that attempts to mount the offset tree mounts again after successfully +mounting the real mount on the offset. This causes automount(8) to see +this as an NFS auto-mounted mount to be ignored and then incorrectly +invalidates these offsets. + +Guard against this by flagging offset trigger mounts as mounted when +they are initially successfully mounted and clearing it upon umounting +them. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 3 +++ + include/automount.h | 3 +++ + lib/mounts.c | 7 ++++++- + 4 files changed, 13 insertions(+), 1 deletion(-) + +--- autofs-5.1.9.orig/CHANGELOG ++++ autofs-5.1.9/CHANGELOG +@@ -20,6 +20,7 @@ + - fix submount shutdown race. + - fix deadlock in master_notify_submount(). + - fix lock ordering deadlock in expire_cleanup(). ++- fix handling of ignored offsets. + + 02/11/2023 autofs-5.1.9 + - fix kernel mount status notification. +--- autofs-5.1.9.orig/daemon/direct.c ++++ autofs-5.1.9/daemon/direct.c +@@ -541,6 +541,7 @@ int umount_autofs_offset(struct autofs_p + debug(ap->logopt, + "offset %s not mounted", + me->key); ++ me->flags &= ~MOUNT_FLAG_OFFSET_MOUNTED; + return 0; + } + ioctlfd = open_ioctlfd(ap, me->key, me->dev); +@@ -629,6 +630,7 @@ force_umount: + rv = umount2(me->key, MNT_DETACH); + } else + info(ap->logopt, "umounted offset mount %s", me->key); ++ me->flags &= ~MOUNT_FLAG_OFFSET_MOUNTED; + + return rv; + } +@@ -783,6 +785,7 @@ int mount_autofs_offset(struct autofs_po + cache_set_ino_index(me->mc, me); + notify_mount_result(ap, me->key, timeout, str_offset); + ops->close(ap->logopt, ioctlfd); ++ me->flags |= MOUNT_FLAG_OFFSET_MOUNTED; + + debug(ap->logopt, "mounted trigger %s", me->key); + +--- autofs-5.1.9.orig/include/automount.h ++++ autofs-5.1.9/include/automount.h +@@ -548,6 +548,9 @@ struct kernel_mod_version { + /* Indicator for applications to ignore the mount entry */ + #define MOUNT_FLAG_IGNORE 0x1000 + ++/* Flag to show we have mounted the offset mount trigger */ ++#define MOUNT_FLAG_OFFSET_MOUNTED 0x2000 ++ + struct autofs_point { + pthread_t thid; + char *path; /* Mount point name */ +--- autofs-5.1.9.orig/lib/mounts.c ++++ autofs-5.1.9/lib/mounts.c +@@ -1865,7 +1865,12 @@ static int tree_mapent_mount_offset(stru + if (ret != MOUNT_OFFSET_IGNORE) { + warn(ap->logopt, "failed to mount offset"); + return 0; +- } else { ++ } ++ ++ /* Only invalidate the offset trigger if a real mount ++ * is not covering it. ++ */ ++ if (!(oe->flags & MOUNT_FLAG_OFFSET_MOUNTED)) { + debug(ap->logopt, + "ignoring \"nohide\" trigger %s", oe->key); + /* diff --git a/autofs-5.1.9-fix-invalidated-map-entry-handling-in-hosts-module.patch b/autofs-5.1.9-fix-invalidated-map-entry-handling-in-hosts-module.patch new file mode 100644 index 0000000..b0544be --- /dev/null +++ b/autofs-5.1.9-fix-invalidated-map-entry-handling-in-hosts-module.patch @@ -0,0 +1,40 @@ +autofs-5.1.9 - fix invalidated map entry handling in hosts module + +From: Ian Kent + +The multi-mount handling must be able to deal with NFS auto-mounting +mounts itself within a mount tree. If this happens the mapent will have +its ->mapent set to NULL but will not be marked with a negative timeout +and mount attempts should silently succeed. All lookup modules handle +this ok already except the hosts lookup module so fix it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_hosts.c | 5 +++++ + 2 files changed, 6 insertions(+) + +--- autofs-5.1.9.orig/CHANGELOG ++++ autofs-5.1.9/CHANGELOG +@@ -21,6 +21,7 @@ + - fix deadlock in master_notify_submount(). + - fix lock ordering deadlock in expire_cleanup(). + - fix handling of ignored offsets. ++- fix invalidated map entry handling in hosts module. + + 02/11/2023 autofs-5.1.9 + - fix kernel mount status notification. +--- autofs-5.1.9.orig/modules/lookup_hosts.c ++++ autofs-5.1.9/modules/lookup_hosts.c +@@ -428,6 +428,11 @@ int lookup_mount(struct autofs_point *ap + * it must be a mount request for one of the exports. + */ + if (*name == '/') { ++ /* Multi-mounts must be able to ignore offsets that have ++ * been auto-mounted by NFS itself. ++ */ ++ if (!me->mapent) ++ return NSS_STATUS_SUCCESS; + pthread_cleanup_push(cache_lock_cleanup, mc); + mapent_len = strlen(me->mapent); + mapent = malloc(mapent_len + 1); diff --git a/autofs-5.1.9-fix-lock-ordering-deadlock-in-expire_cleanup.patch b/autofs-5.1.9-fix-lock-ordering-deadlock-in-expire_cleanup.patch new file mode 100644 index 0000000..5202139 --- /dev/null +++ b/autofs-5.1.9-fix-lock-ordering-deadlock-in-expire_cleanup.patch @@ -0,0 +1,77 @@ +autofs-5.1.9 - fix lock ordering deadlock in expire_cleanup() + +From: Ian Kent + +Commit 81ac572466e3 ("autofs-5.1.9 - fix submount shutdown race") +introduced a lock ordering deadlock between the state mutex and the +mounts hash list mutex when fixing a submount shutdown race. It's enough +to just move the conditional alarm set function call outside of the +state mutex critical section to fix it. + +Fixes: 81ac572466e3 ("autofs-5.1.9 - fix submount shutdown race") +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/state.c | 12 ++++++++---- + 2 files changed, 9 insertions(+), 4 deletions(-) + +--- autofs-5.1.9.orig/CHANGELOG ++++ autofs-5.1.9/CHANGELOG +@@ -19,6 +19,7 @@ + - add some unimplemented amd map options. + - fix submount shutdown race. + - fix deadlock in master_notify_submount(). ++- fix lock ordering deadlock in expire_cleanup(). + + 02/11/2023 autofs-5.1.9 + - fix kernel mount status notification. +--- autofs-5.1.9.orig/daemon/state.c ++++ autofs-5.1.9/daemon/state.c +@@ -62,8 +62,9 @@ void expire_cleanup(void *arg) + pthread_t thid = pthread_self(); + struct expire_args *ec; + struct autofs_point *ap; +- int success; + enum states next = ST_INVAL; ++ unsigned int need_alarm = 0; ++ int success; + + ec = (struct expire_args *) arg; + ap = ec->ap; +@@ -99,7 +100,7 @@ void expire_cleanup(void *arg) + } + + if (ap->state == ST_EXPIRE) +- conditional_alarm_add(ap, ap->exp_runfreq); ++ need_alarm = 1; + + /* FALLTHROUGH */ + +@@ -116,7 +117,7 @@ void expire_cleanup(void *arg) + rv = ops->askumount(ap->logopt, ap->ioctlfd, &idle); + if (!rv && !idle && !ap->shutdown) { + next = ST_READY; +- conditional_alarm_add(ap, ap->exp_runfreq); ++ need_alarm = 1; + break; + } + +@@ -129,7 +130,7 @@ void expire_cleanup(void *arg) + + /* Failed shutdown returns to ready */ + warn(ap->logopt, "filesystem %s still busy", ap->path); +- conditional_alarm_add(ap, ap->exp_runfreq); ++ need_alarm = 1; + next = ST_READY; + break; + #endif +@@ -156,6 +157,9 @@ void expire_cleanup(void *arg) + + st_mutex_unlock(); + ++ if (need_alarm) ++ conditional_alarm_add(ap, ap->exp_runfreq); ++ + return; + } + diff --git a/autofs-5.1.9-fix-submount-shutdown-race.patch b/autofs-5.1.9-fix-submount-shutdown-race.patch new file mode 100644 index 0000000..51b3118 --- /dev/null +++ b/autofs-5.1.9-fix-submount-shutdown-race.patch @@ -0,0 +1,89 @@ +autofs-5.1.9 - fix submount shutdown race + +From: Ian Kent + +In function master_notify_submount() an expire notification is sent to +existing submounts. automount waits for the task to complete then, if +the submount is exiting, waits for the submount to reach a completion +state. + +But the submount can go away during these checks resulting in the +autofs mount point structure field of the mount list structure to be +set to NULL which can then lead to a crash. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/master.c | 23 +++++++++++++---------- + lib/mounts.c | 2 ++ + 3 files changed, 16 insertions(+), 10 deletions(-) + +--- autofs-5.1.9.orig/CHANGELOG ++++ autofs-5.1.9/CHANGELOG +@@ -17,6 +17,7 @@ + - make iocl ops ->timeout() handle per-dentry expire. + - refactor amd mount options handling. + - add some unimplemented amd map options. ++- fix submount shutdown race. + + 02/11/2023 autofs-5.1.9 + - fix kernel mount status notification. +--- autofs-5.1.9.orig/daemon/master.c ++++ autofs-5.1.9/daemon/master.c +@@ -1222,22 +1222,24 @@ int master_notify_submount(struct autofs + + this = mnts_find_submount(path); + if (this) { ++ struct autofs_point *found; ++ + /* We have found a submount to expire */ + st_mutex_lock(); +- +- if (this->ap->state == ST_SHUTDOWN) { ++ found = this->ap; ++ if (!found || found->state == ST_SHUTDOWN) { + this = NULL; + st_mutex_unlock(); + goto done; + } +- +- this->ap->shutdown = ap->shutdown; +- +- __st_add_task(this->ap, state); +- ++ found->shutdown = ap->shutdown; ++ __st_add_task(found, state); + st_mutex_unlock(); + +- st_wait_task(this->ap, state, 0); ++ /* This is ok because found isn't dereferenced during ++ * the wait checks. ++ */ ++ st_wait_task(found, state, 0); + + /* + * If our submount gets to state ST_SHUTDOWN_PENDING or +@@ -1249,8 +1251,9 @@ int master_notify_submount(struct autofs + struct timespec t = { 0, 300000000 }; + struct timespec r; + +- if (sbmnt->ap->state != ST_SHUTDOWN_PENDING && +- sbmnt->ap->state != ST_SHUTDOWN_FORCE) { ++ if (!sbmnt->ap || ++ (sbmnt->ap->state != ST_SHUTDOWN_PENDING && ++ sbmnt->ap->state != ST_SHUTDOWN_FORCE)) { + ret = 0; + mnts_put_mount(sbmnt); + break; +--- autofs-5.1.9.orig/lib/mounts.c ++++ autofs-5.1.9/lib/mounts.c +@@ -1136,7 +1136,9 @@ void mnts_remove_submount(const char *mp + this = mnts_lookup(mp); + if (this && this->flags & MNTS_AUTOFS) { + this->flags &= ~MNTS_AUTOFS; ++ st_mutex_lock(); + this->ap = NULL; ++ st_mutex_unlock(); + list_del_init(&this->submount); + __mnts_put_mount(this); + } diff --git a/autofs.spec b/autofs.spec index c488f50..a24264a 100644 --- a/autofs.spec +++ b/autofs.spec @@ -12,7 +12,7 @@ Summary: A tool for automatically mounting and unmounting filesystems Name: autofs Version: 5.1.9 -Release: 11%{?dist} +Release: 13%{?dist} Epoch: 1 License: GPL-2.0-or-later Source: https://www.kernel.org/pub/linux/daemons/autofs/v5/autofs-%{version}.tar.gz @@ -35,6 +35,15 @@ Patch15: autofs-5.1.9-make-ioctl-ops-timeout-handle-per-dentry-expire.patch Patch16: autofs-5.1.9-refactor-amd-mount-options-handling.patch Patch17: autofs-5.1.9-add-some-unimplemented-amd-map-options.patch +# RHEL-87525 +Patch20: autofs-5.1.9-fix-submount-shutdown-race.patch +Patch21: autofs-5.1.9-fix-deadlock-in-master_notify_submount.patch +Patch22: autofs-5.1.9-fix-lock-ordering-deadlock-in-expire_cleanup.patch + +# RHEL-90571 +Patch30: autofs-5.1.9-fix-handling-of-ignored-offsets.patch +Patch31: autofs-5.1.9-fix-invalidated-map-entry-handling-in-hosts-module.patch + %if %{with_systemd} BuildRequires: systemd-units BuildRequires: systemd-devel @@ -206,6 +215,19 @@ fi %dir /etc/auto.master.d %changelog +* Mon May 12 2025 Ian Kent - 1:5.1.9-13 +- RHEL-90571 - autofs: segfault while dereferencing null mapent [rhel-10] + - fix handling of ignored offsets. + - fix invalidated map entry handling in hosts module. +- Resolves: RHEL-90571 + +* Wed Apr 30 2025 Ian Kent - 1:5.1.9-12 +- RHEL-87525 - autofs hang - autofs-5.1.4-114.el8_10.2 [rhel-10] + - fix submount shutdown race. + - fix deadlock in master_notify_submount(). + - fix lock ordering deadlock in expire_cleanup(). +- Resolves: RHEL-87525 + * Tue Oct 29 2024 Troy Dawson - 1:5.1.9-11 - Bump release for October 2024 mass rebuild: Resolves: RHEL-64018