- Add fix for RHEL-87525.
This commit is contained in:
parent
b847c35d22
commit
ebf894222f
66
autofs-5.1.9-fix-deadlock-in-master_notify_submount.patch
Normal file
66
autofs-5.1.9-fix-deadlock-in-master_notify_submount.patch
Normal file
@ -0,0 +1,66 @@
|
||||
autofs-5.1.9 - fix deadlock in master_notify_submount()
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
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 <raven@themaw.net>
|
||||
---
|
||||
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);
|
||||
}
|
||||
@ -0,0 +1,77 @@
|
||||
autofs-5.1.9 - fix lock ordering deadlock in expire_cleanup()
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
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 <raven@themaw.net>
|
||||
---
|
||||
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;
|
||||
}
|
||||
|
||||
89
autofs-5.1.9-fix-submount-shutdown-race.patch
Normal file
89
autofs-5.1.9-fix-submount-shutdown-race.patch
Normal file
@ -0,0 +1,89 @@
|
||||
autofs-5.1.9 - fix submount shutdown race
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
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 <raven@themaw.net>
|
||||
---
|
||||
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);
|
||||
}
|
||||
14
autofs.spec
14
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: 12%{?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,11 @@ 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
|
||||
|
||||
%if %{with_systemd}
|
||||
BuildRequires: systemd-units
|
||||
BuildRequires: systemd-devel
|
||||
@ -206,6 +211,13 @@ fi
|
||||
%dir /etc/auto.master.d
|
||||
|
||||
%changelog
|
||||
* Wed Apr 30 2025 Ian Kent <ikent@redhat.com> - 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 <tdawson@redhat.com> - 1:5.1.9-11
|
||||
- Bump release for October 2024 mass rebuild:
|
||||
Resolves: RHEL-64018
|
||||
|
||||
Loading…
Reference in New Issue
Block a user