diff options
author | Ian Kent <raven@themaw.net> | 2022-11-08 14:14:07 +0800 |
---|---|---|
committer | Ian Kent <raven@themaw.net> | 2022-11-27 08:14:11 +0800 |
commit | b3b8efbb5d0bef046238d82391821d421920c913 (patch) | |
tree | 6fb01382885014203dbb6a6f0ec1e243f0401123 | |
parent | a83b45e5fe2d7629da5a3c7efd9549747bcb9e67 (diff) | |
download | autofs-b3b8efbb5d0bef046238d82391821d421920c913.tar.gz |
autofs-5.1.8 - fix hosts map deadlock on restart
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>
-rw-r--r-- | CHANGELOG | 1 | ||||
-rw-r--r-- | daemon/lookup.c | 22 | ||||
-rw-r--r-- | modules/parse_amd.c | 18 |
3 files changed, 23 insertions, 18 deletions
@@ -44,6 +44,7 @@ - fix parse module instance mutex naming. - serialise lookup module open and reinit. - coverity fix for invalid access. +- fix hosts map deadlock on restart. 19/10/2021 autofs-5.1.8 - add xdr_exports(). diff --git a/daemon/lookup.c b/daemon/lookup.c index 26026a12..29f43d24 100644 --- a/daemon/lookup.c +++ b/daemon/lookup.c @@ -809,19 +809,21 @@ int do_lookup_mount(struct autofs_point *ap, struct map_source *map, const char 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; diff --git a/modules/parse_amd.c b/modules/parse_amd.c index a2684664..e2dd0b33 100644 --- a/modules/parse_amd.c +++ b/modules/parse_amd.c @@ -1377,17 +1377,19 @@ static int do_host_mount(struct autofs_point *ap, const char *name, } } - 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); |