diff --git a/SOURCES/autofs-5.1.8-allow-null-map-in-indirect-maps.patch b/SOURCES/autofs-5.1.8-allow-null-map-in-indirect-maps.patch new file mode 100644 index 0000000..6e18e99 --- /dev/null +++ b/SOURCES/autofs-5.1.8-allow-null-map-in-indirect-maps.patch @@ -0,0 +1,152 @@ +autofs-5.1.8 - allow -null map in indirect maps + +From: Ian Kent + +We have had reports of GUI programs (such as Nautilus) probing for files +such as .hidden in the parent directory of the directory being accessed. + +If using an indirect mount map with a wildcard map entry autofs is duty +bound to try and mount these which usually results in a mount failure but +can also cause lengthy delays in some cases. + +There are some challenges to modifying application code and even if it +can be done it's always open to being broken later by developers that +aren't aware of the reasoning behind the original changes. + +Now, there is a machanism in autofs that can be used to ignore certain +map entries, the "builtin map -null", see auto.master(5). Currently it +can be used only in the master map but this change extends it to be used +in indirect mount maps as well. In this way it can be used to handle +problematic entries by simply adding a map entry that uses the builtin +-null map. + +For example: +.hidden -null +* someserver:/remote/home/& + +This mechanism is not standard so if one is using systems other than +those with Linux autofs and central map storage, such as LDAP, then +it would be necessary to configure nsswitch to ensure the files map +source is consulted first followed by the remote map source. Then the +-null map entries included in a local file map that uses plus map +inclusion to move on the the central map source if there is no match. + +For example, in /etc/auto.home we can have: +.hidden -null ++auto.home + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/indirect.c | 12 +++++++++++- + daemon/lookup.c | 4 ++++ + include/parse_subs.h | 1 + + lib/parse_subs.c | 13 +++++++++++++ + man/auto.master.5.in | 9 +++++++-- + 6 files changed, 37 insertions(+), 3 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -150,6 +150,7 @@ + - fix some sss error return cases. + - fix incorrect matching of cached wildcard key. + - fix expire retry looping. ++- allow -null map in indirect maps. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/indirect.c ++++ autofs-5.1.4/daemon/indirect.c +@@ -796,13 +796,23 @@ int handle_packet_missing_indirect(struc + return 0; + } + +- /* Check if we recorded a mount fail for this key anywhere */ + me = lookup_source_mapent(ap, pkt->name, LKP_DISTINCT); + if (me) { ++ /* Check if we recorded a mount fail for this key */ + if (me->status >= monotonic_time(NULL)) { + ops->send_fail(ap->logopt, ap->ioctlfd, + pkt->wait_queue_token, -ENOENT); + cache_unlock(me->mc); ++ master_mutex_unlock(); ++ pthread_setcancelstate(state, NULL); ++ return 0; ++ } ++ ++ /* Ignore nulled indirect map entries */ ++ if (starts_with_null_opt(me->mapent)) { ++ ops->send_fail(ap->logopt, ap->ioctlfd, ++ pkt->wait_queue_token, -ENOENT); ++ cache_unlock(me->mc); + master_mutex_unlock(); + pthread_setcancelstate(state, NULL); + return 0; +--- autofs-5.1.4.orig/daemon/lookup.c ++++ autofs-5.1.4/daemon/lookup.c +@@ -780,6 +780,10 @@ int lookup_ghost(struct autofs_point *ap + goto next; + } + ++ /* Ignore nulled indirect map entries */ ++ if (starts_with_null_opt(me->mapent)) ++ goto next; ++ + fullpath = make_browse_path(ap->logopt, + ap->path, me->key, ap->pref); + if (!fullpath) +--- autofs-5.1.4.orig/include/parse_subs.h ++++ autofs-5.1.4/include/parse_subs.h +@@ -122,6 +122,7 @@ int strmcmp(const char *, const char *, + char *dequote(const char *, int, unsigned int); + int span_space(const char *, unsigned int); + char *sanitize_path(const char *, int, unsigned int, unsigned int); ++int starts_with_null_opt(const char *); + char *merge_options(const char *, const char *); + int expandamdent(const char *, char *, const struct substvar *); + int expand_selectors(struct autofs_point *, const char *, char **, struct substvar *); +--- autofs-5.1.4.orig/lib/parse_subs.c ++++ autofs-5.1.4/lib/parse_subs.c +@@ -878,6 +878,19 @@ char *sanitize_path(const char *path, in + return s_path; + } + ++int starts_with_null_opt(const char *str) ++{ ++ if (str && strlen(str) >= 5 && *str == '-') { ++ char sep = *(str + 5); ++ ++ if (sep == 0 || sep == ' ' || sep == ',') { ++ if (!strncmp(str, "-null", 5)) ++ return 1; ++ } ++ } ++ return 0; ++} ++ + static char *hasopt(const char *str, const char *opt) + { + const size_t optlen = strlen(opt); +--- autofs-5.1.4.orig/man/auto.master.5.in ++++ autofs-5.1.4/man/auto.master.5.in +@@ -267,13 +267,18 @@ master map entry. + If "\-null" is given as the map it is used to tell automount(8) to ignore a subsequent + master map entry with the given path. + .P +-It can only be used for paths that appear in the master map (or in direct mount maps). ++It can be used for paths that appear in the master map or in direct mount maps (but ++not in direct mount maps themselves) or as a key in an indirect mount map. ++.P ++An indirect mount map key can be nulled. If so the map key is ignored and does not ++result in a mount attempt (essentially the key lookup is abandoned early on). + .P + An indirect mount map top level mount point path can be nulled. If so no mounts from + the nulled mount are performed (essentially it isn't mounted). + .P + Direct mount map path entries can be nulled. Since they must be present at startup +-they are (notionally) part of the master map. ++they are (notionally) part of the master map so direct mount paths that use the -null ++map may be used in the master map to ignore subsequent direct mount map entries. + .P + A nulled master map entry path will ignore a single subsequent matching entry. Any + matching entry following that will be treated as it normally would be. An example diff --git a/SOURCES/autofs-5.1.8-fix-multi-mount-check.patch b/SOURCES/autofs-5.1.8-fix-multi-mount-check.patch new file mode 100644 index 0000000..af5508f --- /dev/null +++ b/SOURCES/autofs-5.1.8-fix-multi-mount-check.patch @@ -0,0 +1,44 @@ +autofs-5.1.8 - fix multi-mount check + +From: Ian Kent + +When checking if a mount location is a multi-mount after the first location +the next '-' or '/' indicates it's a multi-mount. + +But the '-' can be part of a mount location and can follow a space leading +to incorrectly deciding the location is a multi-mount. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 9 ++++++++- + 2 files changed, 9 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -151,6 +151,7 @@ + - fix incorrect matching of cached wildcard key. + - fix expire retry looping. + - allow -null map in indirect maps. ++- fix multi-mount check. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/modules/parse_sun.c ++++ autofs-5.1.4/modules/parse_sun.c +@@ -786,7 +786,14 @@ static int check_is_multi(const char *ma + if (not_first_chunk) { + if (*p == '"') + p++; +- if (*p == '/' || *p == '-') { ++ /* ++ * Although an options string here would mean ++ * we have a multi-mount we can't rely on it ++ * since it's also valid in a mount location. ++ */ ++ if (*p == '-') ++ p++; ++ if (*p == '/') { + multi = 1; + break; + } diff --git a/SOURCES/autofs-5.1.9-add-flags-argument-to-amd-do_program_mount.patch b/SOURCES/autofs-5.1.9-add-flags-argument-to-amd-do_program_mount.patch new file mode 100644 index 0000000..45ac41e --- /dev/null +++ b/SOURCES/autofs-5.1.9-add-flags-argument-to-amd-do_program_mount.patch @@ -0,0 +1,60 @@ +autofs-5.1.9 - add flags argument to amd do_program_mount() + +From: Ian Kent + +Most of the amd mount functions take a flags argument that allows them +to alter their function based on configuration. + +For example the amd option autofs_use_lofs will use bind mounts instead +of symlinks in some cases which might be preferred. + +The program mount function was not being passed this parameter but the +design of all the amd mount functions is quite similar and adding the +flag works as expected.. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_amd.c | 7 ++++--- + 2 files changed, 5 insertions(+), 3 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -160,6 +160,7 @@ + - don't free ext mount if mounted. + - refactor amd function do_program_mount(). + - refactor umount_amd_ext_mount(). ++- add flags argument to amd do_program_mount(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/modules/parse_amd.c ++++ autofs-5.1.4/modules/parse_amd.c +@@ -1405,7 +1405,8 @@ out: + } + + static int do_program_mount(struct autofs_point *ap, +- struct amd_entry *entry, const char *name) ++ struct amd_entry *entry, const char *name, ++ unsigned int flags) + { + int rv = 1; + +@@ -1479,7 +1480,7 @@ static int do_program_mount(struct autof + goto out; + } + done: +- rv = do_link_mount(ap, name, entry, 0); ++ rv = do_link_mount(ap, name, entry, flags); + if (rv) { + if (!umount_amd_ext_mount(ap, entry->fs, 1)) { + debug(ap->logopt, MODPREFIX +@@ -1708,7 +1709,7 @@ static int amd_mount(struct autofs_point + case AMD_MOUNT_TYPE_PROGRAM: + if (!validate_program_options(ap->logopt, entry)) + return 1; +- ret = do_program_mount(ap, entry, name); ++ ret = do_program_mount(ap, entry, name, flags); + break; + + default: diff --git a/SOURCES/autofs-5.1.9-dont-free-ext-mount-if-mounted.patch b/SOURCES/autofs-5.1.9-dont-free-ext-mount-if-mounted.patch new file mode 100644 index 0000000..f3ded11 --- /dev/null +++ b/SOURCES/autofs-5.1.9-dont-free-ext-mount-if-mounted.patch @@ -0,0 +1,53 @@ +autofs-5.1.9 - don't free ext mount if mounted + +From: Ian Kent + +If an external mount is in use when a umount is attempted don't free +it just let the reference count go to zero. + +This will leave the mount in place and it won't get umounted. But if +another automount uses it it's reference count will become no zero +allowing for it to be umounted as normal if it isn't in use during +automount expire. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 8 ++++---- + 2 files changed, 5 insertions(+), 4 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -157,6 +157,7 @@ + - fix submount shutdown race. + - fix amd external mount error handling. + - fix amd external mount mount handling. ++- don't free ext mount if mounted. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -906,10 +906,10 @@ int ext_mount_remove(const char *path) + if (!em) + goto done; + +- em->ref--; + if (em->ref) +- goto done; +- else { ++ em->ref--; ++ ++ if (!em->ref && !is_mounted(path, MNTS_REAL)) { + hlist_del_init(&em->mount); + free(em->mp); + if (em->umount) +@@ -931,7 +931,7 @@ int ext_mount_inuse(const char *path) + em = ext_mount_lookup(path); + if (!em) + goto done; +- ret = em->ref; ++ ret = 1; + done: + ext_mount_hash_mutex_unlock(); + return ret; diff --git a/SOURCES/autofs-5.1.9-fix-amd-external-mount-error-handling.patch b/SOURCES/autofs-5.1.9-fix-amd-external-mount-error-handling.patch new file mode 100644 index 0000000..d47d7bd --- /dev/null +++ b/SOURCES/autofs-5.1.9-fix-amd-external-mount-error-handling.patch @@ -0,0 +1,55 @@ +autofs-5.1.9 - fix amd external mount error handling + +From: Ian Kent + +An amd program mount might have defined its own umount program to be used +for external mounts. + +In mount failure cases where the mount needs to be umounted be sure to +use the custom umount if there is one. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_amd.c | 6 +++--- + 2 files changed, 4 insertions(+), 3 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -155,6 +155,7 @@ + - fix get parent multi-mount check in try_remount(). + - fix deadlock in remount. + - fix submount shutdown race. ++- fix amd external mount error handling. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/modules/parse_amd.c ++++ autofs-5.1.4/modules/parse_amd.c +@@ -1183,7 +1183,7 @@ static int do_generic_mount(struct autof + } + /* If we have an external mount add it to the list */ + if (umount && !ext_mount_add(entry->fs, entry->umount)) { +- umount_ent(ap, entry->fs); ++ umount_amd_ext_mount(ap, entry->fs); + error(ap->logopt, MODPREFIX + "error: could not add external mount %s", + entry->fs); +@@ -1233,7 +1233,7 @@ static int do_nfs_mount(struct autofs_po + } + /* We might be using an external mount */ + if (umount && !ext_mount_add(entry->fs, entry->umount)) { +- umount_ent(ap, entry->fs); ++ umount_amd_ext_mount(ap, entry->fs); + error(ap->logopt, MODPREFIX + "error: could not add external mount %s", entry->fs); + ret = 1; +@@ -1462,7 +1462,7 @@ static int do_program_mount(struct autof + "%s: mounted %s", entry->type, entry->fs); + goto do_free; + } +- umount_ent(ap, entry->fs); ++ umount_amd_ext_mount(ap, entry->fs); + } + + if (!ext_mount_inuse(entry->fs)) diff --git a/SOURCES/autofs-5.1.9-fix-amd-external-mount-mount-handling.patch b/SOURCES/autofs-5.1.9-fix-amd-external-mount-mount-handling.patch new file mode 100644 index 0000000..f3d09f4 --- /dev/null +++ b/SOURCES/autofs-5.1.9-fix-amd-external-mount-mount-handling.patch @@ -0,0 +1,71 @@ +autofs-5.1.9 - fix amd external mount mount handling + +From: Ian Kent + +Amd external mounts exist outside of the autofs file system and need +extra effort to try and keep track of them so they are mounted and +umounted when they should be. + +Cleanup cases where an external mount is already mounted. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_amd.c | 21 ++++++++++++--------- + 2 files changed, 13 insertions(+), 9 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -156,6 +156,7 @@ + - fix deadlock in remount. + - fix submount shutdown race. + - fix amd external mount error handling. ++- fix amd external mount mount handling. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/modules/parse_amd.c ++++ autofs-5.1.4/modules/parse_amd.c +@@ -1182,8 +1182,9 @@ static int do_generic_mount(struct autof + umount = 1; + } + /* If we have an external mount add it to the list */ +- if (umount && !ext_mount_add(entry->fs, entry->umount)) { +- umount_amd_ext_mount(ap, entry->fs); ++ if (!ext_mount_add(entry->fs, entry->umount)) { ++ if (umount) ++ umount_amd_ext_mount(ap, entry->fs); + error(ap->logopt, MODPREFIX + "error: could not add external mount %s", + entry->fs); +@@ -1232,8 +1233,9 @@ static int do_nfs_mount(struct autofs_po + umount = 1; + } + /* We might be using an external mount */ +- if (umount && !ext_mount_add(entry->fs, entry->umount)) { +- umount_amd_ext_mount(ap, entry->fs); ++ if (!ext_mount_add(entry->fs, entry->umount)) { ++ if (umount) ++ umount_amd_ext_mount(ap, entry->fs); + error(ap->logopt, MODPREFIX + "error: could not add external mount %s", entry->fs); + ret = 1; +@@ -1435,12 +1437,13 @@ static int do_program_mount(struct autof + * before executing the mount command and removing it at + * umount. + */ +- if (ext_mount_inuse(entry->fs)) { ++ if (is_mounted(entry->fs, MNTS_REAL)) { ++ if (!ext_mount_add(entry->fs, entry->umount)) { ++ error(ap->logopt, MODPREFIX ++ "error: could not add external mount %s", entry->fs); ++ goto out; ++ } + rv = 0; +- /* An external mount with path entry->fs exists +- * so ext_mount_add() won't fail. +- */ +- ext_mount_add(entry->fs, entry->umount); + } else { + rv = mkdir_path(entry->fs, mp_mode); + if (rv && errno != EEXIST) { diff --git a/SOURCES/autofs-5.1.9-fix-deadlock-in-remount.patch b/SOURCES/autofs-5.1.9-fix-deadlock-in-remount.patch index fba8571..5a0f8c4 100644 --- a/SOURCES/autofs-5.1.9-fix-deadlock-in-remount.patch +++ b/SOURCES/autofs-5.1.9-fix-deadlock-in-remount.patch @@ -16,9 +16,9 @@ Signed-off-by: Ian Kent --- autofs-5.1.4.orig/CHANGELOG +++ autofs-5.1.4/CHANGELOG -@@ -151,6 +151,7 @@ - - fix incorrect matching of cached wildcard key. - - fix expire retry looping. +@@ -153,6 +153,7 @@ + - allow -null map in indirect maps. + - fix multi-mount check. - fix get parent multi-mount check in try_remount(). +- fix deadlock in remount. @@ -26,7 +26,7 @@ Signed-off-by: Ian Kent - fix flag file permission. --- autofs-5.1.4.orig/modules/parse_sun.c +++ autofs-5.1.4/modules/parse_sun.c -@@ -881,7 +881,18 @@ update_offset_entry(struct autofs_point +@@ -888,7 +888,18 @@ update_offset_entry(struct autofs_point strcpy(m_mapent, loc); } @@ -46,7 +46,7 @@ Signed-off-by: Ian Kent ret = cache_update_offset(mc, name, m_key, m_mapent, age); me = cache_lookup_distinct(mc, m_key); -@@ -1573,7 +1584,18 @@ dont_expand: +@@ -1580,7 +1591,18 @@ dont_expand: free(myoptions); } while (*p == '/' || (*p == '"' && *(p + 1) == '/')); diff --git a/SOURCES/autofs-5.1.9-fix-get-parent-multi-mount-check-in-try_remount.patch b/SOURCES/autofs-5.1.9-fix-get-parent-multi-mount-check-in-try_remount.patch index b4c3926..48a07d8 100644 --- a/SOURCES/autofs-5.1.9-fix-get-parent-multi-mount-check-in-try_remount.patch +++ b/SOURCES/autofs-5.1.9-fix-get-parent-multi-mount-check-in-try_remount.patch @@ -22,10 +22,10 @@ Signed-off-by: Ian Kent --- autofs-5.1.4.orig/CHANGELOG +++ autofs-5.1.4/CHANGELOG -@@ -150,6 +150,7 @@ - - fix some sss error return cases. - - fix incorrect matching of cached wildcard key. +@@ -152,6 +152,7 @@ - fix expire retry looping. + - allow -null map in indirect maps. + - fix multi-mount check. +- fix get parent multi-mount check in try_remount(). xx/xx/2018 autofs-5.1.5 diff --git a/SOURCES/autofs-5.1.9-fix-submount-shutdown-race.patch b/SOURCES/autofs-5.1.9-fix-submount-shutdown-race.patch new file mode 100644 index 0000000..c6086eb --- /dev/null +++ b/SOURCES/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.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); + } diff --git a/SOURCES/autofs-5.1.9-refactor-amd-function-do_program_mount.patch b/SOURCES/autofs-5.1.9-refactor-amd-function-do_program_mount.patch new file mode 100644 index 0000000..4929d7c --- /dev/null +++ b/SOURCES/autofs-5.1.9-refactor-amd-function-do_program_mount.patch @@ -0,0 +1,138 @@ +autofs-5.1.9 - refactor amd function do_program_mount() + +From: Ian Kent + +The amd mounts function do_program_mount() is particularly untidy. + +Refactor it to make it a little simpler and to take advantage of the +coming refactoring of the funtion umount_amd_ext_mount(). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + modules/parse_amd.c | 74 ++++++++++++++++++++++++---------------------------- + 2 files changed, 36 insertions(+), 39 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -158,6 +158,7 @@ + - fix amd external mount error handling. + - fix amd external mount mount handling. + - don't free ext mount if mounted. ++- refactor amd function do_program_mount(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/modules/parse_amd.c ++++ autofs-5.1.4/modules/parse_amd.c +@@ -1407,26 +1407,8 @@ out: + static int do_program_mount(struct autofs_point *ap, + struct amd_entry *entry, const char *name) + { +- char *prog, *str; +- char **argv; +- int argc = -1; + int rv = 1; + +- str = strdup(entry->mount); +- if (!str) +- goto out; +- +- prog = NULL; +- argv = NULL; +- +- argc = construct_argv(str, &prog, &argv); +- if (argc == -1) { +- error(ap->logopt, MODPREFIX +- "%s: error creating mount arguments", entry->type); +- free(str); +- goto out; +- } +- + /* The am-utils documentation doesn't actually say that the + * mount (and umount, if given) command need to use ${fs} as + * the mount point in the command. +@@ -1445,6 +1427,25 @@ static int do_program_mount(struct autof + } + rv = 0; + } else { ++ char *prog, *str; ++ char **argv; ++ int argc = -1; ++ ++ str = strdup(entry->mount); ++ if (!str) ++ goto out; ++ ++ prog = NULL; ++ argv = NULL; ++ ++ argc = construct_argv(str, &prog, &argv); ++ if (argc == -1) { ++ error(ap->logopt, MODPREFIX ++ "%s: error creating mount arguments", entry->type); ++ free(str); ++ goto out; ++ } ++ + rv = mkdir_path(entry->fs, mp_mode); + if (rv && errno != EEXIST) { + char buf[MAX_ERR_BUF]; +@@ -1454,7 +1455,9 @@ static int do_program_mount(struct autof + error(ap->logopt, + MODPREFIX "%s: mkdir_path %s failed: %s", + entry->type, entry->fs, estr); +- goto do_free; ++ free_argv(argc, (const char **) argv); ++ free(str); ++ goto out; + } + + rv = spawnv(ap->logopt, prog, (const char * const *) argv); +@@ -1463,33 +1466,26 @@ static int do_program_mount(struct autof + rv = 0; + debug(ap->logopt, MODPREFIX + "%s: mounted %s", entry->type, entry->fs); +- goto do_free; ++ free_argv(argc, (const char **) argv); ++ free(str); ++ goto done; + } + umount_amd_ext_mount(ap, entry->fs); + } +- +- if (!ext_mount_inuse(entry->fs)) +- rmdir_path(ap, entry->fs, ap->dev); + error(ap->logopt, MODPREFIX + "%s: failed to mount using %s", entry->type, entry->mount); +- } +-do_free: +- free_argv(argc, (const char **) argv); +- free(str); +- +- if (rv) ++ free_argv(argc, (const char **) argv); ++ free(str); + goto out; +- ++ } ++done: + rv = do_link_mount(ap, name, entry, 0); +- if (!rv) +- goto out; +- +- if (umount_amd_ext_mount(ap, entry->fs)) { +- if (!ext_mount_inuse(entry->fs)) +- rmdir_path(ap, entry->fs, ap->dev); +- debug(ap->logopt, MODPREFIX +- "%s: failed to umount external mount at %s", +- entry->type, entry->fs); ++ if (rv) { ++ if (umount_amd_ext_mount(ap, entry->fs)) { ++ debug(ap->logopt, MODPREFIX ++ "%s: failed to cleanup external mount at %s", ++ entry->type, entry->fs); ++ } + } + out: + return rv; diff --git a/SOURCES/autofs-5.1.9-refactor-amd-function-umount_amd_ext_mount.patch b/SOURCES/autofs-5.1.9-refactor-amd-function-umount_amd_ext_mount.patch new file mode 100644 index 0000000..6fc863c --- /dev/null +++ b/SOURCES/autofs-5.1.9-refactor-amd-function-umount_amd_ext_mount.patch @@ -0,0 +1,242 @@ +autofs-5.1.9 - refactor amd function umount_amd_ext_mount() + +From: Ian Kent + +The amd mounts function umount_amd_ext_mount() needs some improvement. + +Make sure the function returns true for success and false for failure +and add a parameter to control if the expternal mount reference should +be decremented on successful umount. + +If the reference count of the external mount is greater than 1 there's +some other mount using (symlink pointing to) it so don't try to umount +it just return success. + +Also check for the case where the mount is already mounted. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/automount.c | 4 +- + include/mounts.h | 2 - + lib/mounts.c | 80 ++++++++++++++++++++++++++++++---------------------- + modules/parse_amd.c | 10 +++--- + 5 files changed, 56 insertions(+), 41 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -159,6 +159,7 @@ + - fix amd external mount mount handling. + - don't free ext mount if mounted. + - refactor amd function do_program_mount(). ++- refactor umount_amd_ext_mount(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -619,7 +619,7 @@ static int umount_subtree_mounts(struct + /* Check for an external mount and umount if possible */ + mnt = mnts_find_amdmount(path); + if (mnt) { +- umount_amd_ext_mount(ap, mnt->ext_mp); ++ umount_amd_ext_mount(ap, mnt->ext_mp, 1); + mnts_remove_amdmount(path); + mnts_put_mount(mnt); + } +@@ -684,7 +684,7 @@ int umount_multi(struct autofs_point *ap + /* Check for an external mount and attempt umount if needed */ + mnt = mnts_find_amdmount(path); + if (mnt) { +- umount_amd_ext_mount(ap, mnt->ext_mp); ++ umount_amd_ext_mount(ap, mnt->ext_mp, 1); + mnts_remove_amdmount(path); + mnts_put_mount(mnt); + } +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -199,7 +199,7 @@ int try_remount(struct autofs_point *, s + void set_indirect_mount_tree_catatonic(struct autofs_point *); + void set_direct_mount_tree_catatonic(struct autofs_point *, struct mapent *); + int umount_ent(struct autofs_point *, const char *); +-int umount_amd_ext_mount(struct autofs_point *, const char *); ++int umount_amd_ext_mount(struct autofs_point *, const char *, int remove); + int clean_stale_multi_triggers(struct autofs_point *, struct mapent *, char *, const char *); + + #endif +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -3097,37 +3097,62 @@ int umount_ent(struct autofs_point *ap, + return mounted; + } + +-int umount_amd_ext_mount(struct autofs_point *ap, const char *path) ++int umount_amd_ext_mount(struct autofs_point *ap, const char *path, int remove) + { + struct ext_mount *em; + char *umount = NULL; +- char *mp; ++ char *mp = NULL; + int rv = 1; ++ int ret; + + pthread_mutex_lock(&ext_mount_hash_mutex); +- + em = ext_mount_lookup(path); + if (!em) { + pthread_mutex_unlock(&ext_mount_hash_mutex); ++ rv = 0; + goto out; + } + mp = strdup(em->mp); + if (!mp) { + pthread_mutex_unlock(&ext_mount_hash_mutex); ++ rv = 0; + goto out; + } + if (em->umount) { + umount = strdup(em->umount); + if (!umount) { + pthread_mutex_unlock(&ext_mount_hash_mutex); +- free(mp); ++ rv = 0; + goto out; + } + } +- ++ /* Don't try and umount if there's more than one ++ * user of the external mount. ++ */ ++ if (em->ref > 1) { ++ pthread_mutex_unlock(&ext_mount_hash_mutex); ++ if (!remove) ++ error(ap->logopt, ++ "reference count mismatch, called with remove false"); ++ else ++ ext_mount_remove(mp); ++ goto out; ++ } ++ /* This shouldn't happen ... */ ++ if (!is_mounted(mp, MNTS_REAL)) { ++ pthread_mutex_unlock(&ext_mount_hash_mutex); ++ error(ap->logopt, "failed to umount program mount at %s", mp); ++ if (remove) ++ ext_mount_remove(mp); ++ goto out; ++ } + pthread_mutex_unlock(&ext_mount_hash_mutex); + +- if (umount) { ++ if (!umount) { ++ ret = umount_ent(ap, mp); ++ if (ret) ++ rv = 0; ++ } else { + char *prog; + char **argv; + int argc = -1; +@@ -3136,41 +3161,30 @@ int umount_amd_ext_mount(struct autofs_p + argv = NULL; + + argc = construct_argv(umount, &prog, &argv); +- if (argc == -1) +- goto done; +- +- if (!ext_mount_remove(mp)) { +- rv =0; +- goto out_free; +- } +- +- rv = spawnv(ap->logopt, prog, (const char * const *) argv); +- if (rv == -1 || (WIFEXITED(rv) && WEXITSTATUS(rv))) ++ if (argc == -1) { + error(ap->logopt, +- "failed to umount program mount at %s", mp); +- else { ++ "failed to allocate args for umount of %s", mp); + rv = 0; +- debug(ap->logopt, "umounted program mount at %s", mp); +- rmdir_path(ap, mp, ap->dev); ++ goto out; + } +-out_free: ++ ret = spawnv(ap->logopt, prog, (const char * const *) argv); ++ rv = WIFEXITED(ret) && !WEXITSTATUS(ret); + free_argv(argc, (const char **) argv); +- +- goto done; + } + +- if (ext_mount_remove(mp)) { +- rv = umount_ent(ap, mp); +- if (rv) +- error(ap->logopt, +- "failed to umount external mount %s", mp); +- else +- debug(ap->logopt, "umounted external mount %s", mp); ++ if (is_mounted(mp, MNTS_REAL)) ++ error(ap->logopt, ++ "failed to umount external mount %s", mp); ++ else { ++ info(ap->logopt, "umounted external mount %s", mp); ++ rmdir_path(ap, mp, ap->dev); + } +-done: ++ if (remove) ++ ext_mount_remove(mp); ++out: + if (umount) + free(umount); +- free(mp); +-out: ++ if (mp) ++ free(mp); + return rv; + } +--- autofs-5.1.4.orig/modules/parse_amd.c ++++ autofs-5.1.4/modules/parse_amd.c +@@ -1133,7 +1133,7 @@ symlink: + + if (entry->sublink) { + /* failed to complete sublink mount */ +- umount_amd_ext_mount(ap, entry->fs); ++ umount_amd_ext_mount(ap, entry->fs, 1); + } + out: + return ret; +@@ -1184,7 +1184,7 @@ static int do_generic_mount(struct autof + /* If we have an external mount add it to the list */ + if (!ext_mount_add(entry->fs, entry->umount)) { + if (umount) +- umount_amd_ext_mount(ap, entry->fs); ++ umount_amd_ext_mount(ap, entry->fs, 0); + error(ap->logopt, MODPREFIX + "error: could not add external mount %s", + entry->fs); +@@ -1235,7 +1235,7 @@ static int do_nfs_mount(struct autofs_po + /* We might be using an external mount */ + if (!ext_mount_add(entry->fs, entry->umount)) { + if (umount) +- umount_amd_ext_mount(ap, entry->fs); ++ umount_amd_ext_mount(ap, entry->fs, 0); + error(ap->logopt, MODPREFIX + "error: could not add external mount %s", entry->fs); + ret = 1; +@@ -1470,7 +1470,7 @@ static int do_program_mount(struct autof + free(str); + goto done; + } +- umount_amd_ext_mount(ap, entry->fs); ++ umount_amd_ext_mount(ap, entry->fs, 0); + } + error(ap->logopt, MODPREFIX + "%s: failed to mount using %s", entry->type, entry->mount); +@@ -1481,7 +1481,7 @@ static int do_program_mount(struct autof + done: + rv = do_link_mount(ap, name, entry, 0); + if (rv) { +- if (umount_amd_ext_mount(ap, entry->fs)) { ++ if (!umount_amd_ext_mount(ap, entry->fs, 1)) { + debug(ap->logopt, MODPREFIX + "%s: failed to cleanup external mount at %s", + entry->type, entry->fs); diff --git a/SPECS/autofs.spec b/SPECS/autofs.spec index 258f923..849413a 100644 --- a/SPECS/autofs.spec +++ b/SPECS/autofs.spec @@ -8,7 +8,7 @@ Summary: A tool for automatically mounting and unmounting filesystems Name: autofs Version: 5.1.4 -Release: 109%{?dist}.1 +Release: 114%{?dist}.1 Epoch: 1 License: GPLv2+ Group: System Environment/Daemons @@ -326,8 +326,20 @@ Patch324: autofs-5.1.8-fix-some-sss-error-return-cases.patch Patch325: autofs-5.1.8-fix-incorrect-matching-of-cached-wildcard-key.patch Patch326: autofs-5.1.8-fix-expire-retry-looping.patch -Patch327: autofs-5.1.9-fix-get-parent-multi-mount-check-in-try_remount.patch -Patch328: autofs-5.1.9-fix-deadlock-in-remount.patch +Patch327: autofs-5.1.8-allow-null-map-in-indirect-maps.patch +Patch328: autofs-5.1.8-fix-multi-mount-check.patch + +Patch329: autofs-5.1.9-fix-get-parent-multi-mount-check-in-try_remount.patch +Patch330: autofs-5.1.9-fix-deadlock-in-remount.patch + +Patch331: autofs-5.1.9-fix-submount-shutdown-race.patch + +Patch332: autofs-5.1.9-fix-amd-external-mount-error-handling.patch +Patch333: autofs-5.1.9-fix-amd-external-mount-mount-handling.patch +Patch334: autofs-5.1.9-dont-free-ext-mount-if-mounted.patch +Patch335: autofs-5.1.9-refactor-amd-function-do_program_mount.patch +Patch336: autofs-5.1.9-refactor-amd-function-umount_amd_ext_mount.patch +Patch337: autofs-5.1.9-add-flags-argument-to-amd-do_program_mount.patch %if %{with_systemd} BuildRequires: systemd-units @@ -698,6 +710,18 @@ echo %{version}-%{release} > .version %patch327 -p1 %patch328 -p1 +%patch329 -p1 +%patch330 -p1 + +%patch331 -p1 + +%patch332 -p1 +%patch333 -p1 +%patch334 -p1 +%patch335 -p1 +%patch336 -p1 +%patch337 -p1 + %build LDFLAGS=-Wl,-z,now %configure --disable-mount-locking --enable-ignore-busy --with-libtirpc --without-hesiod %{?systemd_configure_arg:} @@ -792,12 +816,41 @@ fi %dir /etc/auto.master.d %changelog -* Thu Jan 11 2024 Ian Kent - 5.1.4-109.el8_9.1 -- RHEL-21288 - SIGSEGV using hierarchical map entries on reload with +* Fri Nov 08 2024 Ian Kent - 5.1.4-114 +- RHEL-61670 - sporadic autofs daemon segfaults + - fix submount shutdown race. +- RHEL-52402 - Sporadic mount failures with amd program maps on RHEL8 + - fix amd external mount error handling. + - fix amd external mount mount handling. + - don't free ext mount if mounted. + - refactor amd function do_program_mount(). + - refactor umount_amd_ext_mount(). + - add flags argument to amd do_program_mount(). +- Resolves: RHEL-61670 RHEL-52402 + + +* Mon Dec 18 2023 Ian Kent - 5.1.4-113 +- RHEL-18035 - SIGSEGV using hierarchical map entries on reload with autofs-5.1.4-109 - fix get parent multi-mount check in try_remount(). - fix deadlock in remount. -- Resolves: RHEL-21288 +- Resolves: RHEL-18035 + +* Mon Sep 18 2023 Ian Kent - 5.1.4-112 +- RHEL-7997 - multi mount detection fails for share with blank+dash + causing SEGV crash + -fix multi-mount check. +-Resolves: RHEL-7997 + +* Mon Sep 18 2023 Ian Kent - 5.1.4-111 +- RHEL-12369 - autofs attempts to mount nonexistant ".hidden" filesystems + - update patch "allow -null map in indirect maps". +- Resolves: RHEL-12369 + +* Mon Sep 18 2023 Ian Kent - 5.1.4-110 +- bz2232402 - autofs attempts to mount nonexistant ".hidden" filesystems + - allow -null map in indirect maps. +- Resolves: rhbz#2232402 * Tue Jul 25 2023 MSVSphere Packaging Team - 5.1.4-109 - Rebuilt for MSVSphere 8.8