diff --git a/package/autofs/patches/autofs-5.1.7-add-ext_mount_hash_mutex-lock-helpers.patch b/package/autofs/patches/autofs-5.1.7-add-ext_mount_hash_mutex-lock-helpers.patch new file mode 100644 index 00000000..ae2b3834 --- /dev/null +++ b/package/autofs/patches/autofs-5.1.7-add-ext_mount_hash_mutex-lock-helpers.patch @@ -0,0 +1,104 @@ +autofs-5.1.7 - add ext_mount_hash_mutex lock helpers + +From: Ian Kent + +Coverity: check_return: Calling "pthread_mutex_lock" without checking + return value. + +Well, I use helpers to do this in many places so can't really disagree. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 26 ++++++++++++++++++++------ + 2 files changed, 21 insertions(+), 6 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index b1b28888..ff44ac25 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -65,6 +65,7 @@ + - fix double free in parse_mapent(). + - refactor lookup_prune_one_cache() a bit. + - cater for empty mounts list in mnts_get_expire_list(). ++- add ext_mount_hash_mutex lock helpers. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/mounts.c b/lib/mounts.c +index 3996eb5e..c24d1a88 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -788,6 +788,20 @@ char *make_mnt_name_string(char *path) + return mnt_name; + } + ++static void ext_mount_hash_mutex_lock(void) ++{ ++ int status = pthread_mutex_lock(&ext_mount_hash_mutex); ++ if (status) ++ fatal(status); ++} ++ ++static void ext_mount_hash_mutex_unlock(void) ++{ ++ int status = pthread_mutex_unlock(&ext_mount_hash_mutex); ++ if (status) ++ fatal(status); ++} ++ + static struct ext_mount *ext_mount_lookup(const char *mp) + { + uint32_t hval = hash(mp, HASH_SIZE(ext_mounts_hash)); +@@ -806,7 +820,7 @@ int ext_mount_add(const char *path, const char *umount) + struct ext_mount *em; + int ret = 0; + +- pthread_mutex_lock(&ext_mount_hash_mutex); ++ ext_mount_hash_mutex_lock(); + + em = ext_mount_lookup(path); + if (em) { +@@ -840,7 +854,7 @@ int ext_mount_add(const char *path, const char *umount) + + ret = 1; + done: +- pthread_mutex_unlock(&ext_mount_hash_mutex); ++ ext_mount_hash_mutex_unlock(); + return ret; + } + +@@ -849,7 +863,7 @@ int ext_mount_remove(const char *path) + struct ext_mount *em; + int ret = 0; + +- pthread_mutex_lock(&ext_mount_hash_mutex); ++ ext_mount_hash_mutex_lock(); + + em = ext_mount_lookup(path); + if (!em) +@@ -867,7 +881,7 @@ int ext_mount_remove(const char *path) + ret = 1; + } + done: +- pthread_mutex_unlock(&ext_mount_hash_mutex); ++ ext_mount_hash_mutex_unlock(); + return ret; + } + +@@ -876,13 +890,13 @@ int ext_mount_inuse(const char *path) + struct ext_mount *em; + int ret = 0; + +- pthread_mutex_lock(&ext_mount_hash_mutex); ++ ext_mount_hash_mutex_lock(); + em = ext_mount_lookup(path); + if (!em) + goto done; + ret = em->ref; + done: +- pthread_mutex_unlock(&ext_mount_hash_mutex); ++ ext_mount_hash_mutex_unlock(); + return ret; + } + diff --git a/package/autofs/patches/autofs-5.1.7-add-length-check-in-umount_subtree_mounts.patch b/package/autofs/patches/autofs-5.1.7-add-length-check-in-umount_subtree_mounts.patch new file mode 100644 index 00000000..264f83a3 --- /dev/null +++ b/package/autofs/patches/autofs-5.1.7-add-length-check-in-umount_subtree_mounts.patch @@ -0,0 +1,42 @@ +autofs-5.1.7 - add length check in umount_subtree_mounts() + +From: Ian Kent + +Coverity: fixed_size_dest: You might overrun the 4097-character + fixed-size string "key" by copying "me->key" without + checking the length. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 5 +++++ + 2 files changed, 6 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 224f58d6..9e385ba9 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -55,6 +55,7 @@ + - fix possible memory leak in master_parse(). + - fix possible memory leak in mnts_add_amdmount(). + - fix double unlock in parse_mount(). ++- add length check in umount_subtree_mounts(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/automount.c b/daemon/automount.c +index 48472d5f..70506d83 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -562,6 +562,11 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi + left++; + } + ++ if (me->len > PATH_MAX) { ++ crit(ap->logopt, "me->key too long for buffer"); ++ return 1; ++ } ++ + strcpy(key, me->key); + + cache_unlock(mc); diff --git a/package/autofs/patches/autofs-5.1.7-add-missing-description-of-null-map-option.patch b/package/autofs/patches/autofs-5.1.7-add-missing-description-of-null-map-option.patch new file mode 100644 index 00000000..93c7cdb5 --- /dev/null +++ b/package/autofs/patches/autofs-5.1.7-add-missing-description-of-null-map-option.patch @@ -0,0 +1,55 @@ +autofs-5.1.7 - add missing desciption of null map option + +From: Ian Kent + +The description of how the -null master map option behaves is +mising from auto.master(5). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + man/auto.master.5.in | 19 +++++++++++++++++++ + 2 files changed, 20 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index b29d2ed8..f5f0da76 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -76,6 +76,7 @@ + - eliminate redundant cache lookup in tree_mapent_add_node(). + - fix hosts map offset order. + - fix direct mount deadlock. ++- add missing description of null map option. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/man/auto.master.5.in b/man/auto.master.5.in +index 72fbfd23..16717015 100644 +--- a/man/auto.master.5.in ++++ b/man/auto.master.5.in +@@ -265,6 +265,25 @@ accessing /net/myserver will mount exports from myserver on directories below + NOTE: mounts done from a hosts map will be mounted with the "nosuid,nodev" options + unless overridden by explicitly specifying the "suid", "dev" options in the + master map entry. ++.SH BUILTIN MAP \-null ++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). ++.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. ++.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 ++use of this is allowing local master map entries to override remote ones. ++.P ++NOTE: If a duplicate master map entry path is seen (excluding paths of null entries) ++it will be ignored and noted in the log, that is the first encountered master map ++entry is used unless there is a corresponding null entry. + .SH LDAP MAPS + If the map type \fBldap\fP is specified the mapname is of the form + \fB[//servername/]dn\fP, where the optional \fBservername\fP is diff --git a/package/autofs/patches/autofs-5.1.7-add-missing-free-in-handle_mounts.patch b/package/autofs/patches/autofs-5.1.7-add-missing-free-in-handle_mounts.patch new file mode 100644 index 00000000..288e200a --- /dev/null +++ b/package/autofs/patches/autofs-5.1.7-add-missing-free-in-handle_mounts.patch @@ -0,0 +1,42 @@ +autofs-5.1.7 - add missing free in handle_mounts() + +From: Ian Kent + +Coverity: error[doubleFree]: Memory pointed to by 'root' is freed twice + +No it's not, but root isn't freed before the fatal call which crashes +automount so add a free() before the fatal() call. + +It appears Coverity doesn't recognise pthread_exit() as an exit condition. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 2 ++ + 2 files changed, 3 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 9c3ede45..62a918a9 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -50,6 +50,7 @@ + - check for offset with no mount location. + - remove mounts_mutex. + - remove unused variable from get_exports(). ++- add missing free in handle_mounts(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/automount.c b/daemon/automount.c +index 28c4d1ee..48472d5f 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -1922,6 +1922,8 @@ void *handle_mounts(void *arg) + status = pthread_mutex_lock(&suc->mutex); + if (status) { + logerr("failed to lock startup condition mutex!"); ++ if (root) ++ free(root); + fatal(status); + } + diff --git a/package/autofs/patches/autofs-5.1.7-cater-for-empty-mounts-list-in-mnts_get_expire_list.patch b/package/autofs/patches/autofs-5.1.7-cater-for-empty-mounts-list-in-mnts_get_expire_list.patch new file mode 100644 index 00000000..062ecdce --- /dev/null +++ b/package/autofs/patches/autofs-5.1.7-cater-for-empty-mounts-list-in-mnts_get_expire_list.patch @@ -0,0 +1,44 @@ +autofs-5.1.7 - cater for empty mounts list in mnts_get_expire_list() + +From: Ian Kent + +Coverity: var_deref_model: Passing null pointer "tree" to + "tree_traverse_inorder", which dereferences it. + +This obviously can't happen but deal with it anyway to quiet Coverity. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 6 ++++-- + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index b79aebc8..b1b28888 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -64,6 +64,7 @@ + - fix missing lock release in mount_subtree(). + - fix double free in parse_mapent(). + - refactor lookup_prune_one_cache() a bit. ++- cater for empty mounts list in mnts_get_expire_list(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/mounts.c b/lib/mounts.c +index 883e3743..3996eb5e 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1445,8 +1445,10 @@ void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap) + } + } + +- tree_traverse_inorder(tree, tree_mnt_expire_list_work, mnts); +- tree_free(tree); ++ if (tree) { ++ tree_traverse_inorder(tree, tree_mnt_expire_list_work, mnts); ++ tree_free(tree); ++ } + done: + mnts_hash_mutex_unlock(); + } diff --git a/package/autofs/patches/autofs-5.1.7-dont-try-umount-after-stat-ENOENT-fail.patch b/package/autofs/patches/autofs-5.1.7-dont-try-umount-after-stat-ENOENT-fail.patch new file mode 100644 index 00000000..d71cd3e0 --- /dev/null +++ b/package/autofs/patches/autofs-5.1.7-dont-try-umount-after-stat-ENOENT-fail.patch @@ -0,0 +1,45 @@ +autofs-5.1.7 - dont try umount after stat() ENOENT fail + +From: Ian Kent + +Coverity: Calling function "umount" that uses "me->key" after a check + function. This can cause a time-of-check, time-of-use race + condition. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 6 +++++- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 7add6c55..c7bc0c39 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -57,6 +57,7 @@ + - fix double unlock in parse_mount(). + - add length check in umount_subtree_mounts(). + - fix flags check in umount_multi(). ++- dont try umount after stat() ENOENT fail. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/direct.c b/daemon/direct.c +index a33f9f91..3bd714e6 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -739,9 +739,13 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me) + + ret = stat(me->key, &st); + if (ret == -1) { ++ int save_errno = errno; ++ + error(ap->logopt, + "failed to stat direct mount trigger %s", me->key); +- goto out_umount; ++ if (save_errno != ENOENT) ++ goto out_umount; ++ goto out_err; + } + + ops->open(ap->logopt, &ioctlfd, st.st_dev, me->key); diff --git a/package/autofs/patches/autofs-5.1.7-dont-use-AUTOFS_DEV_IOCTL_CLOSEMOUNT.patch b/package/autofs/patches/autofs-5.1.7-dont-use-AUTOFS_DEV_IOCTL_CLOSEMOUNT.patch new file mode 100644 index 00000000..aafaed5a --- /dev/null +++ b/package/autofs/patches/autofs-5.1.7-dont-use-AUTOFS_DEV_IOCTL_CLOSEMOUNT.patch @@ -0,0 +1,47 @@ +autofs-5.1.7 - dont use AUTOFS_DEV_IOCTL_CLOSEMOUNT + +From: Ian Kent + +Using an ioctl (AUTOFS_DEV_IOCTL_CLOSEMOUNT) to close an autofs mount +file handle can race with copy_to_user() so the file handle needs to +be closed using close(2) instead. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/dev-ioctl-lib.c | 10 +--------- + 2 files changed, 2 insertions(+), 9 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 06bf24b8..51e7767e 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -68,6 +68,7 @@ + - add ext_mount_hash_mutex lock helpers. + - fix amd section mounts map reload. + - fix dandling symlink creation if nis support is not available. ++- dont use AUTOFS_DEV_IOCTL_CLOSEMOUNT. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/dev-ioctl-lib.c b/lib/dev-ioctl-lib.c +index e7a1b42a..6b549d73 100644 +--- a/lib/dev-ioctl-lib.c ++++ b/lib/dev-ioctl-lib.c +@@ -404,15 +404,7 @@ err: + /* Close */ + static int dev_ioctl_close(unsigned int logopt, int ioctlfd) + { +- struct autofs_dev_ioctl param; +- +- init_autofs_dev_ioctl(¶m); +- param.ioctlfd = ioctlfd; +- +- if (ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_CLOSEMOUNT, ¶m) == -1) +- return -1; +- +- return 0; ++ return close(ioctlfd); + } + + static int ioctl_close(unsigned int logopt, int ioctlfd) diff --git a/package/autofs/patches/autofs-5.1.7-eliminate-redundant-cache-lookup-in-tree_mapent_add_node.patch b/package/autofs/patches/autofs-5.1.7-eliminate-redundant-cache-lookup-in-tree_mapent_add_node.patch new file mode 100644 index 00000000..2d55fd0b --- /dev/null +++ b/package/autofs/patches/autofs-5.1.7-eliminate-redundant-cache-lookup-in-tree_mapent_add_node.patch @@ -0,0 +1,90 @@ +autofs-5.1.7 - eliminate redundant cache lookup in tree_mapent_add_node() + +From: Ian Kent + +Since we need to create the offset tree after adding the offset entries +to the mapent cache (from a list.h list) there's no need to lookup the +mapent in tree_mapent_add_node() and validate it. Just use it directly +when calling tree_mapent_add_node() and avoid a cache lookup on every +node addition. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/mounts.h | 2 +- + lib/mounts.c | 13 ++----------- + modules/parse_sun.c | 2 +- + 4 files changed, 5 insertions(+), 13 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 5a767360..81b6ce6a 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -73,6 +73,7 @@ + - fix amd hosts mount expire. + - fix offset entries order. + - use mapent tree root for tree_mapent_add_node(). ++- eliminate redundant cache lookup in tree_mapent_add_node(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/include/mounts.h b/include/mounts.h +index f7768ce5..5a7a0b89 100644 +--- a/include/mounts.h ++++ b/include/mounts.h +@@ -170,7 +170,7 @@ void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap); + void mnts_put_expire_list(struct list_head *mnts); + void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags); + struct tree_node *tree_mapent_root(struct mapent *me); +-int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, const char *key); ++int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, struct mapent *me); + int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key); + void tree_mapent_cleanup_offsets(struct mapent *oe); + int tree_mapent_mount_offsets(struct mapent *oe, int nonstrict); +diff --git a/lib/mounts.c b/lib/mounts.c +index 9ec547ea..6b24a6c2 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1519,19 +1519,10 @@ static void tree_mapent_free(struct tree_node *n) + } + + int tree_mapent_add_node(struct mapent_cache *mc, +- struct tree_node *root, const char *key) ++ struct tree_node *root, struct mapent *me) + { +- unsigned int logopt = mc->ap->logopt; + struct tree_node *n; + struct mapent *parent; +- struct mapent *me; +- +- me = cache_lookup_distinct(mc, key); +- if (!me) { +- error(logopt, +- "failed to find key %s of multi-mount", key); +- return 0; +- } + + n = tree_add_node(root, me); + if (!n) +@@ -1540,7 +1531,7 @@ int tree_mapent_add_node(struct mapent_cache *mc, + MAPENT_SET_ROOT(me, root) + + /* Set the subtree parent */ +- parent = cache_get_offset_parent(mc, key); ++ parent = cache_get_offset_parent(mc, me->key); + if (!parent) + MAPENT_SET_PARENT(me, root) + else +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index c75bcc8e..12844a30 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -1546,7 +1546,7 @@ dont_expand: + return 1; + } + list_for_each_entry_safe(oe, tmp, &offsets, work) { +- if (!tree_mapent_add_node(mc, MAPENT_ROOT(me), oe->key)) ++ if (!tree_mapent_add_node(mc, MAPENT_ROOT(me), oe)) + error(ap->logopt, "failed to add offset %s to tree", oe->key); + list_del_init(&oe->work); + } diff --git a/package/autofs/patches/autofs-5.1.7-fix-amd-hosts-mount-expire.patch b/package/autofs/patches/autofs-5.1.7-fix-amd-hosts-mount-expire.patch new file mode 100644 index 00000000..c82c2980 --- /dev/null +++ b/package/autofs/patches/autofs-5.1.7-fix-amd-hosts-mount-expire.patch @@ -0,0 +1,52 @@ +autofs-5.1.7 - fix amd hosts mount expire + +From: Ian Kent + +When swicthing to use the mnt_list to track mounts for expire, if the +amd hosts map entry name is for the host short name, the amd mount +entry for the short name gets removed. This causes a subsequent mounts +for host exports to fail. + +What should happen is the short name amd entry not be removed and a +mounted mount entry for the symlinked FQDN mount added so it expires. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_amd.c | 9 +++++---- + 2 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 698cc27a..94eb6a2c 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -70,6 +70,7 @@ + - fix dandling symlink creation if nis support is not available. + - dont use AUTOFS_DEV_IOCTL_CLOSEMOUNT. + - fix lookup_prune_one_cache() refactoring change. ++- fix amd hosts mount expire. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index 64c1ce63..163174cd 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -2341,12 +2341,13 @@ int parse_mount(struct autofs_point *ap, const char *name, + if (!rv) { + /* + * If entry->path doesn't match the mnt->mp then +- * the mount point path has changed and a new +- * mnt_list entry added for it, so remove the +- * original. ++ * it's a "host" map and the mount point path is ++ * different to the lookup name. Add a new mnt_list ++ * entry so that both the symlinked name and the ++ * mount expire. + */ + if (strcmp(this->path, mnt->mp)) +- mnts_remove_amdmount(this->path); ++ mnts_add_mount(ap, this->rhost, MNTS_INDIRECT|MNTS_MOUNTED); + break; + } + /* Not mounted, remove the mnt_list entry from amdmount list */ diff --git a/package/autofs/patches/autofs-5.1.7-fix-amd-section-mounts-map-reload.patch b/package/autofs/patches/autofs-5.1.7-fix-amd-section-mounts-map-reload.patch new file mode 100644 index 00000000..cbe84aed --- /dev/null +++ b/package/autofs/patches/autofs-5.1.7-fix-amd-section-mounts-map-reload.patch @@ -0,0 +1,124 @@ +autofs-5.1.7 - fix amd section mounts map reload + +From: Ian Kent + +Master map section mounts (amd format mounts) get umounted on reload. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/master.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 81 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index ff44ac25..ddc07912 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -66,6 +66,7 @@ + - refactor lookup_prune_one_cache() a bit. + - cater for empty mounts list in mnts_get_expire_list(). + - add ext_mount_hash_mutex lock helpers. ++- fix amd section mounts map reload. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/master.c b/daemon/master.c +index 84743f80..f99359c5 100644 +--- a/daemon/master.c ++++ b/daemon/master.c +@@ -882,6 +882,83 @@ struct master *master_new(const char *name, unsigned int timeout, unsigned int f + return master; + } + ++static void master_update_amd_mount_section_mount(struct master *master, ++ const char *path, time_t age) ++{ ++ unsigned int m_logopt = master->logopt; ++ struct master_mapent *entry; ++ struct map_source *source; ++ unsigned int loglevel; ++ unsigned int logopt; ++ unsigned int flags; ++ time_t timeout; ++ char *map; ++ char *opts; ++ ++ entry = master_find_mapent(master, path); ++ if (!entry) ++ return; ++ ++ map = conf_amd_get_map_name(path); ++ if (!map) ++ return; ++ ++ /* amd top level mounts have only one map */ ++ source = entry->maps; ++ if (strcmp(source->name, map) != 0) { ++ struct map_source *new; ++ char *type; ++ char *argv[2]; ++ ++ type = conf_amd_get_map_type(path); ++ argv[0] = map; ++ argv[1] = NULL; ++ ++ new = master_add_map_source(entry, type, "amd", ++ age, 1, (const char **) argv); ++ if (!new) { ++ error(m_logopt, ++ "failed to add source for amd section mount %s", ++ path); ++ if (type) ++ free(type); ++ goto out; ++ } ++ master_free_map_source(source, 0); ++ entry->maps = new; ++ source = new; ++ if (type) ++ free(type); ++ } ++ ++ loglevel = conf_amd_get_log_options(); ++ logopt = m_logopt; ++ if (loglevel <= LOG_DEBUG && loglevel > LOG_INFO) ++ logopt = LOGOPT_DEBUG; ++ else if (loglevel <= LOG_INFO && loglevel > LOG_ERR) ++ logopt = LOGOPT_VERBOSE; ++ ++ flags = conf_amd_get_flags(path); ++ if (flags & CONF_BROWSABLE_DIRS) ++ entry->ap->flags |= MOUNT_FLAG_GHOST; ++ ++ opts = conf_amd_get_map_options(path); ++ if (opts) { ++ if (strstr(opts, "cache:=all")) ++ entry->ap->flags |= MOUNT_FLAG_AMD_CACHE_ALL; ++ free(opts); ++ } ++ ++ entry->ap->logopt = logopt; ++ ++ timeout = conf_amd_get_dismount_interval(path); ++ set_exp_timeout(entry->ap, source, timeout); ++ source->master_line = 0; ++ entry->age = age; ++out: ++ free(map); ++} ++ + static void master_add_amd_mount_section_mounts(struct master *master, time_t age) + { + unsigned int m_logopt = master->logopt; +@@ -916,8 +993,10 @@ static void master_add_amd_mount_section_mounts(struct master *master, time_t ag + * master map it's not a duplicate, don't issue + * an error message. + */ +- if (ret == 1) ++ if (ret == 1) { ++ master_update_amd_mount_section_mount(master, path, age); + goto next; ++ } + info(m_logopt, + "amd section mount path conflict, %s ignored", + path); diff --git a/package/autofs/patches/autofs-5.1.7-fix-arg-not-used-in-print.patch b/package/autofs/patches/autofs-5.1.7-fix-arg-not-used-in-print.patch new file mode 100644 index 00000000..52b8a6e1 --- /dev/null +++ b/package/autofs/patches/autofs-5.1.7-fix-arg-not-used-in-print.patch @@ -0,0 +1,40 @@ +autofs-5.1.7 - fix arg not used in error print + +From: Ian Kent + +Coverity: extra_argument: This argument was not used by the format + string: "key". + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 4 +--- + 2 files changed, 2 insertions(+), 3 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index f11aa1c7..1d56c96f 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -60,6 +60,7 @@ + - dont try umount after stat() ENOENT fail. + - remove redundant assignment in master_add_amd_mount_section_mounts(). + - fix dead code in mnts_add_mount(). ++- fix arg not used in error print. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/mounts.c b/lib/mounts.c +index 018b9c80..883e3743 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1519,9 +1519,7 @@ int tree_mapent_add_node(struct mapent_cache *mc, + } + + if (MAPENT_ROOT(base) != MAPENT_NODE(base)) { +- error(logopt, +- "failed to find multi-mount root of offset tree", +- key); ++ error(logopt, "key %s is not multi-mount root", root); + return 0; + } + tree = MAPENT_ROOT(base); diff --git a/package/autofs/patches/autofs-5.1.7-fix-dandling-symlink-creation-if-nis-support-is-not-available.patch b/package/autofs/patches/autofs-5.1.7-fix-dandling-symlink-creation-if-nis-support-is-not-available.patch new file mode 100644 index 00000000..6d1149b8 --- /dev/null +++ b/package/autofs/patches/autofs-5.1.7-fix-dandling-symlink-creation-if-nis-support-is-not-available.patch @@ -0,0 +1,39 @@ +autofs-5.1.7 - fix dandling symlink creation if nis support is not available + +From: Ian Kent + +If NIS support is not available a dangling symlink is created pointing +from lookup_nis.so to (a non-existent) lookup_yp.so. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/Makefile | 2 ++ + 2 files changed, 3 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index ddc07912..06bf24b8 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -67,6 +67,7 @@ + - cater for empty mounts list in mnts_get_expire_list(). + - add ext_mount_hash_mutex lock helpers. + - fix amd section mounts map reload. ++- fix dandling symlink creation if nis support is not available. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/modules/Makefile b/modules/Makefile +index 91dc20ab..6908da06 100644 +--- a/modules/Makefile ++++ b/modules/Makefile +@@ -77,7 +77,9 @@ install: all + install -c $(MODS) -m 755 $(INSTALLROOT)$(autofslibdir) + -rm -f $(INSTALLROOT)$(autofslibdir)/mount_smbfs.so + ln -fs lookup_file.so $(INSTALLROOT)$(autofslibdir)/lookup_files.so ++ifeq ($(YPCLNT), 1) + ln -fs lookup_yp.so $(INSTALLROOT)$(autofslibdir)/lookup_nis.so ++endif + ifeq ($(LDAP), 1) + ln -fs lookup_ldap.so $(INSTALLROOT)$(autofslibdir)/lookup_ldaps.so + endif diff --git a/package/autofs/patches/autofs-5.1.7-fix-dead-code-in-mnts_add_mount.patch b/package/autofs/patches/autofs-5.1.7-fix-dead-code-in-mnts_add_mount.patch new file mode 100644 index 00000000..a32bf7ba --- /dev/null +++ b/package/autofs/patches/autofs-5.1.7-fix-dead-code-in-mnts_add_mount.patch @@ -0,0 +1,55 @@ +autofs-5.1.7 - fix dead code in mnts_add_mount() + +From: Ian Kent + +Coverity: dead_error_line: Execution cannot reach this statement: "free(mp);". + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 8 ++------ + 2 files changed, 3 insertions(+), 6 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index f95b1aa6..f11aa1c7 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -59,6 +59,7 @@ + - fix flags check in umount_multi(). + - dont try umount after stat() ENOENT fail. + - remove redundant assignment in master_add_amd_mount_section_mounts(). ++- fix dead code in mnts_add_mount(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/mounts.c b/lib/mounts.c +index ef69cec1..018b9c80 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1205,13 +1205,13 @@ struct mnt_list *mnts_add_mount(struct autofs_point *ap, + if (*name == '/') { + mp = strdup(name); + if (!mp) +- goto fail; ++ return NULL; + } else { + int len = ap->len + strlen(name) + 2; + + mp = malloc(len); + if (!mp) +- goto fail; ++ return NULL; + strcpy(mp, ap->path); + strcat(mp, "/"); + strcat(mp, name); +@@ -1228,10 +1228,6 @@ struct mnt_list *mnts_add_mount(struct autofs_point *ap, + free(mp); + + return this; +-fail: +- if (mp) +- free(mp); +- return NULL; + } + + void mnts_remove_mount(const char *mp, unsigned int flags) diff --git a/package/autofs/patches/autofs-5.1.7-fix-direct-mount-deadlock.patch b/package/autofs/patches/autofs-5.1.7-fix-direct-mount-deadlock.patch new file mode 100644 index 00000000..edfb5a13 --- /dev/null +++ b/package/autofs/patches/autofs-5.1.7-fix-direct-mount-deadlock.patch @@ -0,0 +1,135 @@ +autofs-5.1.7 - fix direct mount deadlock + +From: Ian Kent + +When umounting direct mounts at exit or when umounting mounts no +longer in the map on re-load a deadlock can occur. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 22 +++++++++++++++++++++- + daemon/state.c | 14 +++++++++----- + 3 files changed, 31 insertions(+), 6 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 9e341e06..b29d2ed8 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -75,6 +75,7 @@ + - use mapent tree root for tree_mapent_add_node(). + - eliminate redundant cache lookup in tree_mapent_add_node(). + - fix hosts map offset order. ++- fix direct mount deadlock. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/direct.c b/daemon/direct.c +index 3bd714e6..d37dd676 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -84,11 +84,27 @@ static void mnts_cleanup(void *arg) + int do_umount_autofs_direct(struct autofs_point *ap, struct mapent *me) + { + struct ioctl_ops *ops = get_ioctl_ops(); ++ struct mapent_cache *mc = me->mc; + char buf[MAX_ERR_BUF]; + int ioctlfd = -1, rv, left, retries; ++ char key[PATH_MAX + 1]; ++ struct mapent *tmp; + int opened = 0; + +- left = umount_multi(ap, me->key, 0); ++ if (me->len > PATH_MAX) { ++ error(ap->logopt, "path too long"); ++ return 1; ++ } ++ strcpy(key, me->key); ++ ++ cache_unlock(mc); ++ left = umount_multi(ap, key, 0); ++ cache_readlock(mc); ++ tmp = cache_lookup_distinct(mc, key); ++ if (tmp != me) { ++ error(ap->logopt, "key %s no longer in mapent cache", key); ++ return -1; ++ } + if (left) { + warn(ap->logopt, "could not unmount %d dirs under %s", + left, me->key); +@@ -213,6 +229,7 @@ int umount_autofs_direct(struct autofs_point *ap) + mc = map->mc; + pthread_cleanup_push(cache_lock_cleanup, mc); + cache_readlock(mc); ++restart: + me = cache_enumerate(mc, NULL); + while (me) { + int error; +@@ -230,6 +247,9 @@ int umount_autofs_direct(struct autofs_point *ap) + * failed umount. + */ + error = do_umount_autofs_direct(ap, me); ++ /* cache became invalid, restart */ ++ if (error == -1) ++ goto restart; + if (!error) + goto done; + +diff --git a/daemon/state.c b/daemon/state.c +index 091210a5..5156bb21 100644 +--- a/daemon/state.c ++++ b/daemon/state.c +@@ -324,11 +324,12 @@ static void do_readmap_cleanup(void *arg) + return; + } + +-static void do_readmap_mount(struct autofs_point *ap, ++static int do_readmap_mount(struct autofs_point *ap, + struct map_source *map, struct mapent *me, time_t now) + { + struct mapent_cache *nc; + struct mapent *ne, *nested, *valid; ++ int ret = 0; + + nc = ap->entry->master->nc; + +@@ -387,7 +388,7 @@ static void do_readmap_mount(struct autofs_point *ap, + cache_unlock(vmc); + error(ap->logopt, + "failed to find expected existing valid map entry"); +- return; ++ return ret; + } + /* Take over the mount if there is one */ + valid->ioctlfd = me->ioctlfd; +@@ -406,14 +407,14 @@ static void do_readmap_mount(struct autofs_point *ap, + ap->exp_runfreq = runfreq; + } + } else if (!is_mounted(me->key, MNTS_REAL)) +- do_umount_autofs_direct(ap, me); ++ ret = do_umount_autofs_direct(ap, me); + else + debug(ap->logopt, + "%s is mounted", me->key); + } else + do_mount_autofs_direct(ap, me, get_exp_timeout(ap, map)); + +- return; ++ return ret; + } + + static void *do_readmap(void *arg) +@@ -480,9 +481,12 @@ static void *do_readmap(void *arg) + mc = map->mc; + pthread_cleanup_push(cache_lock_cleanup, mc); + cache_readlock(mc); ++restart: + me = cache_enumerate(mc, NULL); + while (me) { +- do_readmap_mount(ap, map, me, now); ++ int ret = do_readmap_mount(ap, map, me, now); ++ if (ret == -1) ++ goto restart; + me = cache_enumerate(mc, me); + } + lookup_prune_one_cache(ap, map->mc, now); diff --git a/package/autofs/patches/autofs-5.1.7-fix-double-free-in-parse_mapent.patch b/package/autofs/patches/autofs-5.1.7-fix-double-free-in-parse_mapent.patch new file mode 100644 index 00000000..64ec0c89 --- /dev/null +++ b/package/autofs/patches/autofs-5.1.7-fix-double-free-in-parse_mapent.patch @@ -0,0 +1,39 @@ +autofs-5.1.7 - fix double free in parse_mapent() + +From: Ian Kent + +Coverity: +in parse_mapent(): double_free: Calling "free" frees pointer "newopt" + which has already been freed. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 2 -- + 2 files changed, 1 insertion(+), 2 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index ff3d88eb..81461978 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -62,6 +62,7 @@ + - fix dead code in mnts_add_mount(). + - fix arg not used in error print. + - fix missing lock release in mount_subtree(). ++- fix double free in parse_mapent(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index 5d15f892..03a63290 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -974,8 +974,6 @@ static int parse_mapent(const char *ent, char *g_options, char **options, char * + estr = strerror_r(errno, buf, MAX_ERR_BUF); + error(logopt, MODPREFIX + "concat_options: %s", estr); +- if (newopt) +- free(newopt); + free(myoptions); + return 0; + } diff --git a/package/autofs/patches/autofs-5.1.7-fix-double-unlock-in-parse_mount.patch b/package/autofs/patches/autofs-5.1.7-fix-double-unlock-in-parse_mount.patch new file mode 100644 index 00000000..d08b9426 --- /dev/null +++ b/package/autofs/patches/autofs-5.1.7-fix-double-unlock-in-parse_mount.patch @@ -0,0 +1,37 @@ +autofs-5.1.7 - fix double unlock in parse_mount() + +From: Ian Kent + +Coverity: double_unlock: "cache_unlock" unlocks "mc->rwlock" while it + is unlocked. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 1 - + 2 files changed, 1 insertion(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 2e3b9fd7..224f58d6 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -54,6 +54,7 @@ + - remove redundant if check. + - fix possible memory leak in master_parse(). + - fix possible memory leak in mnts_add_amdmount(). ++- fix double unlock in parse_mount(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index a81d4028..05f53fc2 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -1526,7 +1526,6 @@ dont_expand: + if (!loc) { + free(options); + free(pmapent); +- cache_unlock(mc); + warn(ap->logopt, MODPREFIX "out of memory"); + return 1; + } diff --git a/package/autofs/patches/autofs-5.1.7-fix-flag-check-in-umount_multi.patch b/package/autofs/patches/autofs-5.1.7-fix-flag-check-in-umount_multi.patch new file mode 100644 index 00000000..eaa784c9 --- /dev/null +++ b/package/autofs/patches/autofs-5.1.7-fix-flag-check-in-umount_multi.patch @@ -0,0 +1,38 @@ +autofs-5.1.7 - fix flags check in umount_multi() + +From: Ian Kent + +Coverity: operator_confusion: "ap->flags | 1" is always 1/true + regardless of the values of its operand. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 9e385ba9..7add6c55 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -56,6 +56,7 @@ + - fix possible memory leak in mnts_add_amdmount(). + - fix double unlock in parse_mount(). + - add length check in umount_subtree_mounts(). ++- fix flags check in umount_multi(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/automount.c b/daemon/automount.c +index 70506d83..23235a7d 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -662,7 +662,7 @@ int umount_multi(struct autofs_point *ap, const char *path, int incl) + /* Check if the autofs mount has browse mode enabled. + * If so re-create the directory entry. + */ +- if (ap->flags | MOUNT_FLAG_GHOST) { ++ if (ap->flags & MOUNT_FLAG_GHOST) { + int ret; + + /* If the browse directory create fails log an diff --git a/package/autofs/patches/autofs-5.1.7-fix-hosts-map-offset-order.patch b/package/autofs/patches/autofs-5.1.7-fix-hosts-map-offset-order.patch new file mode 100644 index 00000000..4d41c306 --- /dev/null +++ b/package/autofs/patches/autofs-5.1.7-fix-hosts-map-offset-order.patch @@ -0,0 +1,300 @@ +autofs-5.1.7 - fix hosts map offset order + +From: Ian Kent + +Map entry offset paths need to be in shortest to longest order but +exports from a server could come in any order. If there are a large +number of exports this can result in a lot of overhead when adding +the offset to the ordered list used to mount the offset during parsing +since the path length of exports can vary a lot. + +So leverage the tree implemention to sort the export offsets into +shortest to longest order as we go when constructing the mapent from +the exports list. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/automount.h | 2 + + include/mounts.h | 8 ++++++ + include/rpc_subs.h | 3 ++ + lib/mounts.c | 57 ++++++++++++++++++++++++++++++++++++++-- + modules/lookup_hosts.c | 69 ++++++++++++++++++++++++++++++++++++++---------- + 6 files changed, 123 insertions(+), 17 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 81b6ce6a..9e341e06 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -74,6 +74,7 @@ + - fix offset entries order. + - use mapent tree root for tree_mapent_add_node(). + - eliminate redundant cache lookup in tree_mapent_add_node(). ++- fix hosts map offset order. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/include/automount.h b/include/automount.h +index d279744d..947ed16d 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -31,9 +31,9 @@ + #include "master.h" + #include "macros.h" + #include "log.h" ++#include "mounts.h" + #include "rpc_subs.h" + #include "parse_subs.h" +-#include "mounts.h" + #include "dev-ioctl-lib.h" + #include "parse_amd.h" + +diff --git a/include/mounts.h b/include/mounts.h +index 5a7a0b89..ddb7e4c5 100644 +--- a/include/mounts.h ++++ b/include/mounts.h +@@ -52,6 +52,7 @@ extern const unsigned int t_direct; + extern const unsigned int t_offset; + + struct mnt_list; ++struct exportinfo; + struct mapent; + + struct tree_ops; +@@ -66,6 +67,9 @@ struct tree_node { + #define MNT_LIST(n) (container_of(n, struct mnt_list, node)) + #define MNT_LIST_NODE(ptr) ((struct tree_node *) &((struct mnt_list *) ptr)->node) + ++#define EXPORTINFO(n) (container_of(n, struct exportinfo, node)) ++#define EXPORT_NODE(ptr) ((struct tree_node *) &((struct exportinfo *) ptr)->node) ++ + #define MAPENT(n) (container_of(n, struct mapent, node)) + #define MAPENT_NODE(p) ((struct tree_node *) &((struct mapent *) p)->node) + #define MAPENT_ROOT(p) ((struct tree_node *) ((struct mapent *) p)->mm_root) +@@ -166,9 +170,13 @@ struct mnt_list *mnts_add_mount(struct autofs_point *ap, const char *name, unsig + void mnts_remove_mount(const char *mp, unsigned int flags); + struct mnt_list *get_mnt_list(const char *path, int include); + unsigned int mnts_has_mounted_mounts(struct autofs_point *ap); ++int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, void *ptr); ++void tree_free(struct tree_node *root); + void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap); + void mnts_put_expire_list(struct list_head *mnts); + void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags); ++struct tree_node *tree_host_root(struct exportinfo *exp); ++struct tree_node *tree_host_add_node(struct tree_node *root, struct exportinfo *exp); + struct tree_node *tree_mapent_root(struct mapent *me); + int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, struct mapent *me); + int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key); +diff --git a/include/rpc_subs.h b/include/rpc_subs.h +index 080f19d9..debf2df0 100644 +--- a/include/rpc_subs.h ++++ b/include/rpc_subs.h +@@ -23,6 +23,8 @@ + #include + #include + ++#include "automount.h" ++ + #define NFS4_VERSION 4 + + /* rpc helper subs */ +@@ -57,6 +59,7 @@ struct exportinfo { + char *dir; + struct hostinfo *hosts; + struct exportinfo *next; ++ struct tree_node node; + }; + + struct conn_info { +diff --git a/lib/mounts.c b/lib/mounts.c +index 6b24a6c2..5a4602e3 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -79,6 +79,17 @@ static struct tree_ops mnt_ops = { + }; + static struct tree_ops *tree_mnt_ops = &mnt_ops; + ++static struct tree_node *tree_host_new(void *ptr); ++static int tree_host_cmp(struct tree_node *n, void *ptr); ++static void tree_host_free(struct tree_node *n); ++ ++static struct tree_ops host_ops = { ++ .new = tree_host_new, ++ .cmp = tree_host_cmp, ++ .free = tree_host_free, ++}; ++static struct tree_ops *tree_host_ops = &host_ops; ++ + static struct tree_node *tree_mapent_new(void *ptr); + static int tree_mapent_cmp(struct tree_node *n, void *ptr); + static void tree_mapent_free(struct tree_node *n); +@@ -1341,7 +1352,7 @@ static struct tree_node *tree_add_node(struct tree_node *root, void *ptr) + return NULL; + } + +-static void tree_free(struct tree_node *root) ++void tree_free(struct tree_node *root) + { + struct tree_ops *ops = root->ops; + +@@ -1352,7 +1363,7 @@ static void tree_free(struct tree_node *root) + ops->free(root); + } + +-static int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, void *ptr) ++int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, void *ptr) + { + int ret; + +@@ -1479,6 +1490,48 @@ void mnts_put_expire_list(struct list_head *mnts) + mnts_hash_mutex_unlock(); + } + ++struct tree_node *tree_host_root(struct exportinfo *exp) ++{ ++ return tree_root(tree_host_ops, exp); ++} ++ ++static struct tree_node *tree_host_new(void *ptr) ++{ ++ struct tree_node *n = EXPORT_NODE(ptr); ++ ++ n->ops = tree_host_ops; ++ n->left = NULL; ++ n->right = NULL; ++ ++ return n; ++} ++ ++static int tree_host_cmp(struct tree_node *n, void *ptr) ++{ ++ struct exportinfo *n_exp = EXPORTINFO(n); ++ size_t n_exp_len = strlen(n_exp->dir); ++ struct exportinfo *exp = ptr; ++ size_t exp_len = strlen(exp->dir); ++ int eq; ++ ++ eq = strcmp(exp->dir, n_exp->dir); ++ if (!eq) ++ return 0; ++ return (exp_len < n_exp_len) ? -1 : 1; ++} ++ ++static void tree_host_free(struct tree_node *n) ++{ ++ n->ops = NULL; ++ n->left = NULL; ++ n->right = NULL; ++} ++ ++struct tree_node *tree_host_add_node(struct tree_node *root, struct exportinfo *exp) ++{ ++ return tree_add_node(root, exp); ++} ++ + struct tree_node *tree_mapent_root(struct mapent *me) + { + return tree_root(tree_mapent_ops, me); +diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c +index 24edf00c..26c224f6 100644 +--- a/modules/lookup_hosts.c ++++ b/modules/lookup_hosts.c +@@ -84,14 +84,38 @@ int lookup_read_master(struct master *master, time_t age, void *context) + return NSS_STATUS_UNKNOWN; + } + ++struct work_info { ++ char *mapent; ++ const char *host; ++ int pos; ++}; ++ ++static int tree_host_work(struct tree_node *n, void *ptr) ++{ ++ struct exportinfo *exp = EXPORTINFO(n); ++ struct work_info *wi = ptr; ++ int len; ++ ++ if (!wi->pos) ++ len = sprintf(wi->mapent, "\"%s\" \"%s:%s\"", ++ exp->dir, wi->host, exp->dir); ++ else ++ len = sprintf(wi->mapent + wi->pos, " \"%s\" \"%s:%s\"", ++ exp->dir, wi->host, exp->dir); ++ wi->pos += len; ++ ++ return 1; ++} ++ + static char *get_exports(struct autofs_point *ap, const char *host) + { + char buf[MAX_ERR_BUF]; + char *mapent; + struct exportinfo *exp, *this; ++ struct tree_node *tree = NULL; ++ struct work_info wi; + size_t hostlen = strlen(host); + size_t mapent_len; +- int len, pos; + + debug(ap->logopt, MODPREFIX "fetchng export list for %s", host); + +@@ -100,7 +124,28 @@ static char *get_exports(struct autofs_point *ap, const char *host) + this = exp; + mapent_len = 0; + while (this) { ++ struct tree_node *n; ++ + mapent_len += hostlen + 2*(strlen(this->dir) + 2) + 3; ++ ++ if (!tree) { ++ tree = tree_host_root(this); ++ if (!tree) { ++ error(ap->logopt, "failed to create exports tree root"); ++ rpc_exports_free(exp); ++ return NULL; ++ } ++ goto next; ++ } ++ ++ n = tree_host_add_node(tree, this); ++ if (!n) { ++ error(ap->logopt, "failed to add exports tree node"); ++ tree_free(tree); ++ rpc_exports_free(exp); ++ return NULL; ++ } ++next: + this = this->next; + } + +@@ -115,20 +160,16 @@ static char *get_exports(struct autofs_point *ap, const char *host) + } + *mapent = 0; + +- pos = 0; +- this = exp; +- if (this) { +- len = sprintf(mapent, "\"%s\" \"%s:%s\"", +- this->dir, host, this->dir); +- pos += len; +- this = this->next; +- } ++ wi.mapent = mapent; ++ wi.host = host; ++ wi.pos = 0; + +- while (this) { +- len = sprintf(mapent + pos, " \"%s\" \"%s:%s\"", +- this->dir, host, this->dir); +- pos += len; +- this = this->next; ++ if (!tree) { ++ free(mapent); ++ mapent = NULL; ++ } else { ++ tree_traverse_inorder(tree, tree_host_work, &wi); ++ tree_free(tree); + } + rpc_exports_free(exp); + diff --git a/package/autofs/patches/autofs-5.1.7-fix-lookup_prune_one_cache-refactoring-change.patch b/package/autofs/patches/autofs-5.1.7-fix-lookup_prune_one_cache-refactoring-change.patch new file mode 100644 index 00000000..f157755a --- /dev/null +++ b/package/autofs/patches/autofs-5.1.7-fix-lookup_prune_one_cache-refactoring-change.patch @@ -0,0 +1,60 @@ +autofs-5.1.7 - fix lookup_prune_one_cache() refactoring change + +From: Ian Kent + +Commit 256963d6b (autofs-5.1.7 - refactor lookup_prune_one_cache() a bit) +changed the position of the getting the next enumeration map entry but +failed to update a couple of other locations that assume the next map +entry has been set. Under certain fairly common conditions this leads +to an infinite loop. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/lookup.c | 5 ++++- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 51e7767e..698cc27a 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -69,6 +69,7 @@ + - fix amd section mounts map reload. + - fix dandling symlink creation if nis support is not available. + - dont use AUTOFS_DEV_IOCTL_CLOSEMOUNT. ++- fix lookup_prune_one_cache() refactoring change. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/lookup.c b/daemon/lookup.c +index 3e9722e4..0b281f83 100644 +--- a/daemon/lookup.c ++++ b/daemon/lookup.c +@@ -1379,6 +1379,7 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti + if (!key || strchr(key, '*')) { + if (key) + free(key); ++ me = cache_enumerate(mc, me); + continue; + } + +@@ -1386,6 +1387,7 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti + if (!path) { + warn(ap->logopt, "can't malloc storage for path"); + free(key); ++ me = cache_enumerate(mc, me); + continue; + } + +@@ -1413,9 +1415,10 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti + } + if (!valid && + is_mounted(path, MNTS_REAL)) { +- debug(ap->logopt, "prune posponed, %s mounted", path); ++ debug(ap->logopt, "prune postponed, %s mounted", path); + free(key); + free(path); ++ me = cache_enumerate(mc, me); + continue; + } + if (valid) diff --git a/package/autofs/patches/autofs-5.1.7-fix-missing-lock-release-in-mount_subtree.patch b/package/autofs/patches/autofs-5.1.7-fix-missing-lock-release-in-mount_subtree.patch new file mode 100644 index 00000000..8b1d2110 --- /dev/null +++ b/package/autofs/patches/autofs-5.1.7-fix-missing-lock-release-in-mount_subtree.patch @@ -0,0 +1,36 @@ +autofs-5.1.7 - fix missing lock release in mount_subtree() + +From: Ian Kent + +Covarity: missing_unlock: Returning without unlocking "mc->rwlock". + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 1d56c96f..ff3d88eb 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -61,6 +61,7 @@ + - remove redundant assignment in master_add_amd_mount_section_mounts(). + - fix dead code in mnts_add_mount(). + - fix arg not used in error print. ++- fix missing lock release in mount_subtree(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index 05f53fc2..5d15f892 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -1105,6 +1105,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc, + len = mount_fullpath(key, PATH_MAX, ap->path, ap->len, me->key); + if (!len) { + warn(ap->logopt, "path loo long"); ++ cache_unlock(mc); + return 1; + } + key[len] = '/'; diff --git a/package/autofs/patches/autofs-5.1.7-fix-nonstrict-offset-mount-fail-handling.patch b/package/autofs/patches/autofs-5.1.7-fix-nonstrict-offset-mount-fail-handling.patch new file mode 100644 index 00000000..ebc63afd --- /dev/null +++ b/package/autofs/patches/autofs-5.1.7-fix-nonstrict-offset-mount-fail-handling.patch @@ -0,0 +1,60 @@ +autofs-5.1.7 - fix nonstrict offset mount fail handling + +From: Ian Kent + +If a triggered offset mount fails automount is not handling nonstrict +mount failure correctly. + +The nonstrict mount failure handling needs to convert an offset mount +failure to a success if the offset subtree below the failed mount is not +empty otherwise it must return the failure. The previous implementation +used -1 to indicate the subtree was empty and that was used to detect +when the mount should fail instead of converting the fail to a success. + +Make the new implementation do the same. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 2 +- + modules/parse_sun.c | 2 +- + 3 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index f5f0da76..ecffa933 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -77,6 +77,7 @@ + - fix hosts map offset order. + - fix direct mount deadlock. + - add missing description of null map option. ++- fix nonstrict offset mount fail handling. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/mounts.c b/lib/mounts.c +index 5a4602e3..4c866885 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1616,7 +1616,7 @@ static int tree_mapent_traverse_subtree(struct tree_node *n, tree_work_fn_t work + { + struct traverse_subtree_context *ctxt = ptr; + struct mapent *oe = MAPENT(n); +- int ret = 1; ++ int ret = -1; + + if (n->left) { + ret = tree_mapent_traverse_subtree(n->left, work, ctxt); +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index 12844a30..cdf515c6 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -1181,7 +1181,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc, + * offsets to be mounted. + */ + rv = sun_mount(ap, name, name, namelen, loc, loclen, options, ctxt); +- if (rv == 0) { ++ if (rv <= 0) { + ret = tree_mapent_mount_offsets(me, 1); + if (!ret) { + tree_mapent_cleanup_offsets(me); diff --git a/package/autofs/patches/autofs-5.1.7-fix-offset-entries-order.patch b/package/autofs/patches/autofs-5.1.7-fix-offset-entries-order.patch new file mode 100644 index 00000000..ff216b45 --- /dev/null +++ b/package/autofs/patches/autofs-5.1.7-fix-offset-entries-order.patch @@ -0,0 +1,207 @@ +autofs-5.1.7 - fix offset entries order + +From: Ian Kent + +While it's rare it's possible that a mapent entry might not have +it's offsets in shortest to longest path order. + +If this happens adding an entry to the mapent tree can result in +an incorrect tree topology that doesn't work. That's because adding +tree entries ensures that nodes in a sub-tree are placed below the +containing node so the containing node must be present for that to +work. This topology is critical to the performance of map entries +that have a very large number of offsets such as an NFS server with +many exports. + +There's no other choice but make a traversal after the offset entries +have all been added to create the mapent tree. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/automount.h | 1 + + lib/cache.c | 1 + + modules/parse_sun.c | 74 +++++++++++++++++++++++++++++++++++++++++---------- + 4 files changed, 62 insertions(+), 15 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 94eb6a2c..7b360f52 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -71,6 +71,7 @@ + - dont use AUTOFS_DEV_IOCTL_CLOSEMOUNT. + - fix lookup_prune_one_cache() refactoring change. + - fix amd hosts mount expire. ++- fix offset entries order. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/include/automount.h b/include/automount.h +index 51a0bf0e..d279744d 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -169,6 +169,7 @@ struct mapent { + /* Parent nesting point within multi-mount */ + struct tree_node *mm_parent; + struct tree_node node; ++ struct list_head work; + char *key; + size_t len; + char *mapent; +diff --git a/lib/cache.c b/lib/cache.c +index ef761739..66dda5d9 100644 +--- a/lib/cache.c ++++ b/lib/cache.c +@@ -559,6 +559,7 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c + me->mm_parent = NULL; + INIT_TREE_NODE(&me->node); + INIT_LIST_HEAD(&me->ino_index); ++ INIT_LIST_HEAD(&me->work); + me->ioctlfd = -1; + me->dev = (dev_t) -1; + me->ino = (ino_t) -1; +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index 03a63290..b206a326 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -789,14 +789,15 @@ static int check_is_multi(const char *mapent) + + static int + update_offset_entry(struct autofs_point *ap, +- struct mapent_cache *mc, const char *name, +- const char *m_root, int m_root_len, ++ struct mapent_cache *mc, struct list_head *offsets, ++ const char *name, const char *m_root, int m_root_len, + const char *m_offset, const char *myoptions, + const char *loc, time_t age) + { + char m_key[PATH_MAX + 1]; + char m_mapent[MAPENT_MAX_LEN + 1]; + int o_len, m_key_len, m_options_len, m_mapent_len; ++ struct mapent *me; + int ret; + + memset(m_mapent, 0, MAPENT_MAX_LEN + 1); +@@ -862,8 +863,29 @@ update_offset_entry(struct autofs_point *ap, + cache_writelock(mc); + ret = cache_update_offset(mc, name, m_key, m_mapent, age); + +- if (!tree_mapent_add_node(mc, name, m_key)) +- error(ap->logopt, "failed to add offset %s to tree", m_key); ++ me = cache_lookup_distinct(mc, m_key); ++ if (me && list_empty(&me->work)) { ++ struct list_head *last; ++ ++ /* Offset entries really need to be in shortest to ++ * longest path order. If not and the list of offsets ++ * is large there will be a performace hit. ++ */ ++ list_for_each_prev(last, offsets) { ++ struct mapent *this; ++ ++ this = list_entry(last, struct mapent, work); ++ if (me->len >= this->len) { ++ if (last->next == offsets) ++ list_add_tail(&me->work, offsets); ++ else ++ list_add_tail(&me->work, last); ++ break; ++ } ++ } ++ if (list_empty(&me->work)) ++ list_add(&me->work, offsets); ++ } + cache_unlock(mc); + + if (ret == CHE_DUPLICATE) { +@@ -1209,6 +1231,25 @@ static char *do_expandsunent(const char *src, const char *key, + return mapent; + } + ++static void cleanup_offset_entries(struct autofs_point *ap, ++ struct mapent_cache *mc, ++ struct list_head *offsets) ++{ ++ struct mapent *me, *tmp; ++ int ret; ++ ++ if (list_empty(offsets)) ++ return; ++ cache_writelock(mc); ++ list_for_each_entry_safe(me, tmp, offsets, work) { ++ list_del(&me->work); ++ ret = cache_delete(mc, me->key); ++ if (ret != CHE_OK) ++ crit(ap->logopt, "failed to delete offset %s", me->key); ++ } ++ cache_unlock(mc); ++} ++ + /* + * syntax is: + * [-options] location [location] ... +@@ -1228,7 +1269,8 @@ int parse_mount(struct autofs_point *ap, const char *name, + char buf[MAX_ERR_BUF]; + struct map_source *source; + struct mapent_cache *mc; +- struct mapent *me; ++ struct mapent *me, *oe, *tmp; ++ LIST_HEAD(offsets); + char *pmapent, *options; + const char *p; + int mapent_len, rv = 0; +@@ -1444,9 +1486,7 @@ dont_expand: + + if (!m_offset) { + warn(ap->logopt, MODPREFIX "null path or out of memory"); +- cache_writelock(mc); +- tree_mapent_delete_offsets(mc, name); +- cache_unlock(mc); ++ cleanup_offset_entries(ap, mc, &offsets); + free(options); + free(pmapent); + pthread_setcancelstate(cur_state, NULL); +@@ -1461,9 +1501,7 @@ dont_expand: + + l = parse_mapent(p, options, &myoptions, &loc, ap->logopt); + if (!l) { +- cache_writelock(mc); +- tree_mapent_delete_offsets(mc, name); +- cache_unlock(mc); ++ cleanup_offset_entries(ap, mc, &offsets); + free(m_offset); + free(options); + free(pmapent); +@@ -1474,15 +1512,13 @@ dont_expand: + p += l; + p = skipspace(p); + +- status = update_offset_entry(ap, mc, ++ status = update_offset_entry(ap, mc, &offsets, + name, m_root, m_root_len, + m_offset, myoptions, loc, age); + + if (status != CHE_OK) { + warn(ap->logopt, MODPREFIX "error adding multi-mount"); +- cache_writelock(mc); +- tree_mapent_delete_offsets(mc, name); +- cache_unlock(mc); ++ cleanup_offset_entries(ap, mc, &offsets); + free(m_offset); + free(options); + free(pmapent); +@@ -1499,6 +1535,14 @@ dont_expand: + free(myoptions); + } while (*p == '/' || (*p == '"' && *(p + 1) == '/')); + ++ cache_writelock(mc); ++ list_for_each_entry_safe(oe, tmp, &offsets, work) { ++ if (!tree_mapent_add_node(mc, name, oe->key)) ++ error(ap->logopt, "failed to add offset %s to tree", oe->key); ++ list_del_init(&oe->work); ++ } ++ cache_unlock(mc); ++ + rv = mount_subtree(ap, mc, name, NULL, options, ctxt); + + free(options); diff --git a/package/autofs/patches/autofs-5.1.7-fix-possible-memory-leak-in-master_parse.patch b/package/autofs/patches/autofs-5.1.7-fix-possible-memory-leak-in-master_parse.patch new file mode 100644 index 00000000..c2ea9df9 --- /dev/null +++ b/package/autofs/patches/autofs-5.1.7-fix-possible-memory-leak-in-master_parse.patch @@ -0,0 +1,38 @@ +autofs-5.1.7 - fix possible memory leak in master_parse() + +From: Ian Kent + +Coverity: Overwriting "path" in "path = master_strdup(yyvsp[-1].strtype)" + leaks the storage that "path" points to. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/master_parse.y | 2 ++ + 2 files changed, 3 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 2186cbe3..b797f6dc 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -52,6 +52,7 @@ + - remove unused variable from get_exports(). + - add missing free in handle_mounts(). + - remove redundant if check. ++- fix possible memory leak in master_parse(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/master_parse.y b/daemon/master_parse.y +index 08e44b57..7480c36a 100644 +--- a/daemon/master_parse.y ++++ b/daemon/master_parse.y +@@ -155,6 +155,8 @@ file: { + line: + | PATH mapspec + { ++ if (path) ++ free(path); + path = master_strdup($1); + if (!path) { + local_free_vars(); diff --git a/package/autofs/patches/autofs-5.1.7-fix-possible-memory-leak-in-mnts_add_amdmount.patch b/package/autofs/patches/autofs-5.1.7-fix-possible-memory-leak-in-mnts_add_amdmount.patch new file mode 100644 index 00000000..5b7c9cc6 --- /dev/null +++ b/package/autofs/patches/autofs-5.1.7-fix-possible-memory-leak-in-mnts_add_amdmount.patch @@ -0,0 +1,58 @@ +autofs-5.1.7 - fix possible memory leak in mnts_add_amdmount() + +From: Ian Kent + +Coverity: leaked_storage: Variable "ext_mp" going out of scope leaks + the storage it points to. + +Same applies to the other duped fields destined for the mnt_list struct. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 20 ++++++++++---------- + 2 files changed, 11 insertions(+), 10 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index b797f6dc..2e3b9fd7 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -53,6 +53,7 @@ + - add missing free in handle_mounts(). + - remove redundant if check. + - fix possible memory leak in master_parse(). ++- fix possible memory leak in mnts_add_amdmount(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/mounts.c b/lib/mounts.c +index c8a7bf00..ef69cec1 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1119,16 +1119,16 @@ struct mnt_list *mnts_add_amdmount(struct autofs_point *ap, struct amd_entry *en + + mnts_hash_mutex_lock(); + this = mnts_get_mount(entry->path); +- if (this) { +- this->ext_mp = ext_mp; +- this->amd_pref = pref; +- this->amd_type = type; +- this->amd_opts = opts; +- this->amd_cache_opts = entry->cache_opts; +- this->flags |= MNTS_AMD_MOUNT; +- if (list_empty(&this->amdmount)) +- list_add_tail(&this->amdmount, &ap->amdmounts); +- } ++ if (!this) ++ goto fail; ++ this->ext_mp = ext_mp; ++ this->amd_pref = pref; ++ this->amd_type = type; ++ this->amd_opts = opts; ++ this->amd_cache_opts = entry->cache_opts; ++ this->flags |= MNTS_AMD_MOUNT; ++ if (list_empty(&this->amdmount)) ++ list_add_tail(&this->amdmount, &ap->amdmounts); + mnts_hash_mutex_unlock(); + + return this; diff --git a/package/autofs/patches/autofs-5.1.7-refactor-lookup_prune_one_cache-a-bit.patch b/package/autofs/patches/autofs-5.1.7-refactor-lookup_prune_one_cache-a-bit.patch new file mode 100644 index 00000000..e013a520 --- /dev/null +++ b/package/autofs/patches/autofs-5.1.7-refactor-lookup_prune_one_cache-a-bit.patch @@ -0,0 +1,75 @@ +autofs-5.1.7 - refactor lookup_prune_one_cache() a bit + +From: Ian Kent + +Coverity: use: Using an unreliable value of "me" inside the second locked + section. + +Change lookup_prune_one_cache() a little, move the location the next +key is set (before releasing the lock) and add a comment explaining +why we don't care about the side effects of the read lock release/ +write lock aquire/write lock release/read lock reaquire. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/lookup.c | 20 +++++++++++++++++++- + 2 files changed, 20 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 81461978..b79aebc8 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -63,6 +63,7 @@ + - fix arg not used in error print. + - fix missing lock release in mount_subtree(). + - fix double free in parse_mapent(). ++- refactor lookup_prune_one_cache() a bit. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/lookup.c b/daemon/lookup.c +index 32dbc24d..3e9722e4 100644 +--- a/daemon/lookup.c ++++ b/daemon/lookup.c +@@ -1375,7 +1375,6 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti + } + + key = strdup(me->key); +- me = cache_enumerate(mc, me); + /* Don't consider any entries with a wildcard */ + if (!key || strchr(key, '*')) { + if (key) +@@ -1422,6 +1421,7 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti + if (valid) + cache_unlock(valid->mc); + ++ me = cache_enumerate(mc, me); + if (me) + next_key = strdup(me->key); + +@@ -1456,6 +1456,24 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti + next: + cache_readlock(mc); + if (next_key) { ++ /* The lock release and reaquire above can mean ++ * a number of things could happen. ++ * ++ * First, mapents could be added between the ++ * current mapent and the mapent of next_key. ++ * Don't care about that because there's no ++ * need to prune newly added entries. ++ * ++ * Second, the next mapent data could have ++ * changed. Don't care about that either since ++ * we are looking to prune stale map entries ++ * and don't care when they become stale. ++ * ++ * Finally, the mapent of next_key could have ++ * gone away. Again don't care about this either, ++ * the loop will exit prematurely so just wait ++ * until the next prune and try again. ++ */ + me = cache_lookup_distinct(mc, next_key); + free(next_key); + } diff --git a/package/autofs/patches/autofs-5.1.7-remove-redundant-assignment-in-master_add_amd_mount_section_mounts.patch b/package/autofs/patches/autofs-5.1.7-remove-redundant-assignment-in-master_add_amd_mount_section_mounts.patch new file mode 100644 index 00000000..44cdc669 --- /dev/null +++ b/package/autofs/patches/autofs-5.1.7-remove-redundant-assignment-in-master_add_amd_mount_section_mounts.patch @@ -0,0 +1,40 @@ +autofs-5.1.7 - remove redundant assignment in master_add_amd_mount_section_mounts() + +From: Ian Kent + +Coverity: missing_lock: Accessing "entry->current" without holding lock + "master_mapent.current_mutex". + +This is initialization not clearing current source. But the field has +already been initialized in the master_new_mapent() call. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/master.c | 1 - + 2 files changed, 1 insertion(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index c7bc0c39..f95b1aa6 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -58,6 +58,7 @@ + - add length check in umount_subtree_mounts(). + - fix flags check in umount_multi(). + - dont try umount after stat() ENOENT fail. ++- remove redundant assignment in master_add_amd_mount_section_mounts(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/master.c b/daemon/master.c +index 30d7cf98..84743f80 100644 +--- a/daemon/master.c ++++ b/daemon/master.c +@@ -996,7 +996,6 @@ static void master_add_amd_mount_section_mounts(struct master *master, time_t ag + source->master_line = 0; + + entry->age = age; +- entry->current = NULL; + + master_add_mapent(master, entry); + next: diff --git a/package/autofs/patches/autofs-5.1.7-remove-redundant-if-check.patch b/package/autofs/patches/autofs-5.1.7-remove-redundant-if-check.patch new file mode 100644 index 00000000..86948ea8 --- /dev/null +++ b/package/autofs/patches/autofs-5.1.7-remove-redundant-if-check.patch @@ -0,0 +1,40 @@ +autofs-5.1.7 - remove redundant if check + +From: Ian Kent + +Coverity: identical code in if condition branches. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 5 +---- + 2 files changed, 2 insertions(+), 4 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 62a918a9..2186cbe3 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -51,6 +51,7 @@ + - remove mounts_mutex. + - remove unused variable from get_exports(). + - add missing free in handle_mounts(). ++- remove redundant if check. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/direct.c b/daemon/direct.c +index 3f4f5704..a33f9f91 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -752,10 +752,7 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me) + + ops->timeout(ap->logopt, ioctlfd, timeout); + cache_set_ino_index(me->mc, me->key, st.st_dev, st.st_ino); +- if (ap->logopt & LOGOPT_DEBUG) +- notify_mount_result(ap, me->key, timeout, str_offset); +- else +- notify_mount_result(ap, me->key, timeout, str_offset); ++ notify_mount_result(ap, me->key, timeout, str_offset); + ops->close(ap->logopt, ioctlfd); + + debug(ap->logopt, "mounted trigger %s", me->key); diff --git a/package/autofs/patches/autofs-5.1.7-use-mapent-tree-root-for-tree_mapent_add_node.patch b/package/autofs/patches/autofs-5.1.7-use-mapent-tree-root-for-tree_mapent_add_node.patch new file mode 100644 index 00000000..0b83d8e0 --- /dev/null +++ b/package/autofs/patches/autofs-5.1.7-use-mapent-tree-root-for-tree_mapent_add_node.patch @@ -0,0 +1,119 @@ +autofs-5.1.7 - use mapent tree root for tree_mapent_add_node() + +From: Ian Kent + +Since we need to create the offset tree after adding the offset entries +to the mapent cache lookup the root mapent once and use it when calling +tree_mapent_add_node() instread of doing a cache lookup on every node +addition. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/mounts.h | 2 +- + lib/mounts.c | 24 +++++------------------- + modules/parse_sun.c | 11 ++++++++++- + 4 files changed, 17 insertions(+), 21 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 7b360f52..5a767360 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -72,6 +72,7 @@ + - fix lookup_prune_one_cache() refactoring change. + - fix amd hosts mount expire. + - fix offset entries order. ++- use mapent tree root for tree_mapent_add_node(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/include/mounts.h b/include/mounts.h +index 1b376b3d..f7768ce5 100644 +--- a/include/mounts.h ++++ b/include/mounts.h +@@ -170,7 +170,7 @@ void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap); + void mnts_put_expire_list(struct list_head *mnts); + void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags); + struct tree_node *tree_mapent_root(struct mapent *me); +-int tree_mapent_add_node(struct mapent_cache *mc, const char *base, const char *key); ++int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, const char *key); + int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key); + void tree_mapent_cleanup_offsets(struct mapent *oe); + int tree_mapent_mount_offsets(struct mapent *oe, int nonstrict); +diff --git a/lib/mounts.c b/lib/mounts.c +index c24d1a88..9ec547ea 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1519,27 +1519,13 @@ static void tree_mapent_free(struct tree_node *n) + } + + int tree_mapent_add_node(struct mapent_cache *mc, +- const char *root, const char *key) ++ struct tree_node *root, const char *key) + { + unsigned int logopt = mc->ap->logopt; +- struct tree_node *tree, *n; +- struct mapent *base; ++ struct tree_node *n; + struct mapent *parent; + struct mapent *me; + +- base = cache_lookup_distinct(mc, root); +- if (!base) { +- error(logopt, +- "failed to find multi-mount root for key %s", key); +- return 0; +- } +- +- if (MAPENT_ROOT(base) != MAPENT_NODE(base)) { +- error(logopt, "key %s is not multi-mount root", root); +- return 0; +- } +- tree = MAPENT_ROOT(base); +- + me = cache_lookup_distinct(mc, key); + if (!me) { + error(logopt, +@@ -1547,16 +1533,16 @@ int tree_mapent_add_node(struct mapent_cache *mc, + return 0; + } + +- n = tree_add_node(tree, me); ++ n = tree_add_node(root, me); + if (!n) + return 0; + +- MAPENT_SET_ROOT(me, tree) ++ MAPENT_SET_ROOT(me, root) + + /* Set the subtree parent */ + parent = cache_get_offset_parent(mc, key); + if (!parent) +- MAPENT_SET_PARENT(me, tree) ++ MAPENT_SET_PARENT(me, root) + else + MAPENT_SET_PARENT(me, MAPENT_NODE(parent)) + +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index b206a326..c75bcc8e 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -1536,8 +1536,17 @@ dont_expand: + } while (*p == '/' || (*p == '"' && *(p + 1) == '/')); + + cache_writelock(mc); ++ me = cache_lookup_distinct(mc, name); ++ if (!me) { ++ cache_unlock(mc); ++ free(options); ++ free(pmapent); ++ cleanup_offset_entries(ap, mc, &offsets); ++ pthread_setcancelstate(cur_state, NULL); ++ return 1; ++ } + list_for_each_entry_safe(oe, tmp, &offsets, work) { +- if (!tree_mapent_add_node(mc, name, oe->key)) ++ if (!tree_mapent_add_node(mc, MAPENT_ROOT(me), oe->key)) + error(ap->logopt, "failed to add offset %s to tree", oe->key); + list_del_init(&oe->work); + } diff --git a/package/autofs/patches/patch_order_5.1.7 b/package/autofs/patches/patch_order_5.1.7 index d039e8bd..9f107c30 100644 --- a/package/autofs/patches/patch_order_5.1.7 +++ b/package/autofs/patches/patch_order_5.1.7 @@ -49,3 +49,31 @@ autofs-5.1.7-move-amd-mounts-removal-into-lib_mounts_c.patch autofs-5.1.7-check-for-offset-with-no-mount-location.patch autofs-5.1.7-remove-mounts_mutex.patch autofs-5.1.7-remove-unused-variable-from-get_exports.patch +autofs-5.1.7-add-missing-free-in-handle_mounts.patch +autofs-5.1.7-remove-redundant-if-check.patch +autofs-5.1.7-fix-possible-memory-leak-in-master_parse.patch +autofs-5.1.7-fix-possible-memory-leak-in-mnts_add_amdmount.patch +autofs-5.1.7-fix-double-unlock-in-parse_mount.patch +autofs-5.1.7-add-length-check-in-umount_subtree_mounts.patch +autofs-5.1.7-fix-flag-check-in-umount_multi.patch +autofs-5.1.7-dont-try-umount-after-stat-ENOENT-fail.patch +autofs-5.1.7-remove-redundant-assignment-in-master_add_amd_mount_section_mounts.patch +autofs-5.1.7-fix-dead-code-in-mnts_add_mount.patch +autofs-5.1.7-fix-arg-not-used-in-print.patch +autofs-5.1.7-fix-missing-lock-release-in-mount_subtree.patch +autofs-5.1.7-fix-double-free-in-parse_mapent.patch +autofs-5.1.7-refactor-lookup_prune_one_cache-a-bit.patch +autofs-5.1.7-cater-for-empty-mounts-list-in-mnts_get_expire_list.patch +autofs-5.1.7-add-ext_mount_hash_mutex-lock-helpers.patch +autofs-5.1.7-fix-amd-section-mounts-map-reload.patch +autofs-5.1.7-fix-dandling-symlink-creation-if-nis-support-is-not-available.patch +autofs-5.1.7-dont-use-AUTOFS_DEV_IOCTL_CLOSEMOUNT.patch +autofs-5.1.7-fix-lookup_prune_one_cache-refactoring-change.patch +autofs-5.1.7-fix-amd-hosts-mount-expire.patch +autofs-5.1.7-fix-offset-entries-order.patch +autofs-5.1.7-use-mapent-tree-root-for-tree_mapent_add_node.patch +autofs-5.1.7-eliminate-redundant-cache-lookup-in-tree_mapent_add_node.patch +autofs-5.1.7-fix-hosts-map-offset-order.patch +autofs-5.1.7-fix-direct-mount-deadlock.patch +autofs-5.1.7-add-missing-description-of-null-map-option.patch +autofs-5.1.7-fix-nonstrict-offset-mount-fail-handling.patch