90 lines
2.5 KiB
Diff
90 lines
2.5 KiB
Diff
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.4.orig/CHANGELOG
|
|
+++ autofs-5.1.4/CHANGELOG
|
|
@@ -154,6 +154,7 @@
|
|
- fix multi-mount check.
|
|
- fix get parent multi-mount check in try_remount().
|
|
- fix deadlock in remount.
|
|
+- fix submount shutdown race.
|
|
|
|
xx/xx/2018 autofs-5.1.5
|
|
- fix flag file permission.
|
|
--- autofs-5.1.4.orig/daemon/master.c
|
|
+++ autofs-5.1.4/daemon/master.c
|
|
@@ -1213,22 +1213,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
|
|
@@ -1240,8 +1242,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.4.orig/lib/mounts.c
|
|
+++ autofs-5.1.4/lib/mounts.c
|
|
@@ -1153,7 +1153,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);
|
|
}
|