diff --git a/autofs-5.1.8-avoid-calling-pthread_getspecific-with-NULL-key_thread_attempt_id.patch b/autofs-5.1.8-avoid-calling-pthread_getspecific-with-NULL-key_thread_attempt_id.patch new file mode 100644 index 0000000..c70e49d --- /dev/null +++ b/autofs-5.1.8-avoid-calling-pthread_getspecific-with-NULL-key_thread_attempt_id.patch @@ -0,0 +1,39 @@ +autofs-5.1.8 - avoid calling pthread_getspecific() with NULL key_thread_attempt_id + +From: Ian Kent + +Don't call pthread_getspecific() if key_thread_attempt_id is NULL in +case the pthread_getspecific() implementation doesn't check for this. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/log.c | 3 +++ + 2 files changed, 4 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 9d57a21b..dacc2fa0 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -12,6 +12,7 @@ + - simplify cache_add() a little. + - fix use after free in tree_mapent_delete_offset_tree(). + - fix memory leak in xdr_exports(). ++- avoid calling pthread_getspecific() with NULL key_thread_attempt_id. + + 19/10/2021 autofs-5.1.8 + - add xdr_exports(). +diff --git a/lib/log.c b/lib/log.c +index 0cb47d7e..d1edef28 100644 +--- a/lib/log.c ++++ b/lib/log.c +@@ -38,6 +38,9 @@ static char *prepare_attempt_prefix(const char *msg) + char buffer[ATTEMPT_ID_SIZE + 1]; + char *prefixed_msg = NULL; + ++ if (!key_thread_attempt_id) ++ return NULL; ++ + attempt_id = pthread_getspecific(key_thread_attempt_id); + if (attempt_id) { + int len = sizeof(buffer) + 1 + strlen(msg) + 1; diff --git a/autofs-5.1.8-bailout-on-rpc-systemerror.patch b/autofs-5.1.8-bailout-on-rpc-systemerror.patch new file mode 100644 index 0000000..5762456 --- /dev/null +++ b/autofs-5.1.8-bailout-on-rpc-systemerror.patch @@ -0,0 +1,38 @@ +autofs-5.1.8 - bailout on rpc systemerror + +From: Ian Kent + +If there's a system error (eg. oversize packet received) just give up +since redoing the call would likely end up with the same error. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/rpc_subs.c | 2 ++ + 2 files changed, 3 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index b4b064ff..575f186d 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -7,6 +7,7 @@ + - fix nonstrict fail handling of last offset mount. + - dont fail on duplicate offset entry tree add. + - fix loop under run in cache_get_offset_parent(). ++- bailout on rpc systemerror. + + 19/10/2021 autofs-5.1.8 + - add xdr_exports(). +diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c +index 7b8162b4..ee7f94b9 100644 +--- a/lib/rpc_subs.c ++++ b/lib/rpc_subs.c +@@ -1195,6 +1195,8 @@ static int rpc_get_exports_proto(struct conn_info *info, struct exportinfo **exp + info->timeout); + if (status == RPC_SUCCESS) + break; ++ if (status == RPC_SYSTEMERROR) ++ break; + if (++vers_entry > 2) + break; + CLNT_CONTROL(client, CLSET_VERS, diff --git a/autofs-5.1.8-dont-fail-on-duplicate-host-export-entry.patch b/autofs-5.1.8-dont-fail-on-duplicate-host-export-entry.patch new file mode 100644 index 0000000..885f813 --- /dev/null +++ b/autofs-5.1.8-dont-fail-on-duplicate-host-export-entry.patch @@ -0,0 +1,50 @@ +autofs-5.1.8 - dont fail on duplicate host export entry + +From: Ian Kent + +If we encounter a duplicate host export entry don't fail, just ignore +it and return the duplicate. + +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 bd1f672c..aaf20cd6 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -5,6 +5,7 @@ + - fix root offset error handling. + - fix fix root offset error handling. + - fix nonstrict fail handling of last offset mount. ++- dont fail on duplicate offset entry tree add. + + 19/10/2021 autofs-5.1.8 + - add xdr_exports(). +diff --git a/lib/mounts.c b/lib/mounts.c +index b4229908..451849a6 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1341,7 +1341,7 @@ static struct tree_node *tree_add_node(struct tree_node *root, void *ptr) + } + + if (!eq) +- error(LOGOPT_ANY, "cannot add duplicate entry to tree"); ++ return p; + else { + if (eq < 0) + return tree_add_left(p, ptr); +@@ -1515,8 +1515,10 @@ static int tree_host_cmp(struct tree_node *n, void *ptr) + int eq; + + eq = strcmp(exp->dir, n_exp->dir); +- if (!eq) ++ if (!eq) { ++ error(LOGOPT_ANY, "duplicate entry %s ignored", exp->dir); + return 0; ++ } + return (exp_len < n_exp_len) ? -1 : 1; + } + diff --git a/autofs-5.1.8-dont-use-initgroups-at-spawn.patch b/autofs-5.1.8-dont-use-initgroups-at-spawn.patch new file mode 100644 index 0000000..d854f95 --- /dev/null +++ b/autofs-5.1.8-dont-use-initgroups-at-spawn.patch @@ -0,0 +1,135 @@ +autofs-5.1.8 - dont use initgroups() at spawn + +From: Ian Kent + +The initgroups(3) function isn't safe to use between fork() and +exec() in a threaded program. + +Using it this way often leads to a hang for even moderate work +loads. + +But the getgrouplist()/setgroups() combination can be used safely +in this case and this patch changes autofs to use these (the safety +of using of setgroups() is yet to to be documented). + +A large portion of the work on this patch has been contributed +by Roberto Bergantinos . + +Reported-by: Roberto Bergantinos +Fixes: 6343a3292020 ("autofs-5.1.3 - fix ordering of seteuid/setegid in do_spawn()") +Signed-off-by: Roberto Bergantinos +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/spawn.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++---- + 2 files changed, 48 insertions(+), 4 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 72a5aa59..e1214323 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -16,6 +16,7 @@ + - fix sysconf(3) return handling. + - remove nonstrict parameter from tree_mapent_umount_offsets(). + - fix handling of incorrect return from umount_ent(). ++- dont use initgroups() at spawn. + + 19/10/2021 autofs-5.1.8 + - add xdr_exports(). +diff --git a/daemon/spawn.c b/daemon/spawn.c +index 914e5288..6f8856a9 100644 +--- a/daemon/spawn.c ++++ b/daemon/spawn.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + #include "automount.h" + +@@ -335,6 +336,10 @@ static int do_spawn(unsigned logopt, unsigned int wait, + struct thread_stdenv_vars *tsv; + pid_t euid = 0; + gid_t egid = 0; ++ gid_t *groups = NULL; ++ gid_t *saved_groups = NULL; ++ int ngroups = 0; ++ int nsaved_groups = 0; + + if (open_pipe(pipefd)) + return -1; +@@ -357,6 +362,31 @@ static int do_spawn(unsigned logopt, unsigned int wait, + } + + open_mutex_lock(); ++ ++ if (euid) { ++ struct passwd *pwd; ++ ++ pwd = getpwuid(getuid()); ++ if (!pwd) ++ fprintf(stderr, ++ "warning: getpwuid: can't get current username\n"); ++ else { ++ /* get number of groups for current gid */ ++ getgrouplist(pwd->pw_name, getgid(), NULL, &nsaved_groups); ++ saved_groups = malloc(nsaved_groups * sizeof(gid_t)); ++ ++ /* get current gid groups list */ ++ getgrouplist(pwd->pw_name, getgid(), saved_groups, &nsaved_groups); ++ } ++ ++ /* get number of groups of mount triggering process */ ++ getgrouplist(tsv->user, egid, NULL, &ngroups); ++ groups = malloc(ngroups * sizeof(gid_t)); ++ ++ /* get groups list of mount triggering process */ ++ getgrouplist(tsv->user, egid, groups, &ngroups); ++ } ++ + f = fork(); + if (f == 0) { + char **pargv = (char **) argv; +@@ -398,10 +428,13 @@ static int do_spawn(unsigned logopt, unsigned int wait, + if (!tsv->user) + fprintf(stderr, + "warning: can't init groups\n"); +- else if (initgroups(tsv->user, egid) == -1) +- fprintf(stderr, +- "warning: initgroups: %s\n", +- strerror(errno)); ++ else if (groups) { ++ if (setgroups(ngroups, groups) == -1) ++ fprintf(stderr, ++ "warning: setgroups: %s\n", ++ strerror(errno)); ++ free(groups); ++ } + + if (setegid(egid) == -1) + fprintf(stderr, +@@ -436,6 +469,11 @@ static int do_spawn(unsigned logopt, unsigned int wait, + strerror(errno)); + if (pgrp >= 0) + setpgid(0, pgrp); ++ /* Reset groups for trigger of trailing mount */ ++ if (euid && saved_groups) { ++ setgroups(nsaved_groups, saved_groups); ++ free(saved_groups); ++ } + + /* + * The kernel leaves mount type autofs alone because +@@ -474,6 +512,11 @@ done: + pthread_sigmask(SIG_SETMASK, &tmpsig, NULL); + open_mutex_unlock(); + ++ if (groups) ++ free(groups); ++ if (saved_groups) ++ free(saved_groups); ++ + close(pipefd[1]); + + if (f < 0) { diff --git a/autofs-5.1.8-fix-fedfs-build-flags.patch b/autofs-5.1.8-fix-fedfs-build-flags.patch new file mode 100644 index 0000000..b81e657 --- /dev/null +++ b/autofs-5.1.8-fix-fedfs-build-flags.patch @@ -0,0 +1,37 @@ +autofs-5.1.8 - fix fedfs build flags + +From: Ian Kent + +Dynamic executables should be compiled with -fPIE and linked with -pie. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + fedfs/Makefile | 4 ++-- + 2 files changed, 3 insertions(+), 2 deletions(-) + +--- autofs-5.1.8.orig/CHANGELOG ++++ autofs-5.1.8/CHANGELOG +@@ -1,4 +1,5 @@ + - fix kernel mount status notificantion. ++- fix fedfs build flags. + + 19/10/2021 autofs-5.1.8 + - add xdr_exports(). +--- autofs-5.1.8.orig/fedfs/Makefile ++++ autofs-5.1.8/fedfs/Makefile +@@ -23,12 +23,12 @@ LDFLAGS += -rdynamic + all: mount.fedfs fedfs-map-nfs4 + + mount.fedfs: $(mount_fedfs_OBJ) $(fedfs-getsrvinfo_OBJ) $(HDRS) +- $(CC) -o mount.fedfs \ ++ $(CC) $(DAEMON_LDFLAGS) -o mount.fedfs \ + $(mount_fedfs_OBJ) $(fedfs-getsrvinfo_OBJ) \ + $(LDFLAGS) $(LIBRESOLV) $(LIBS) + + fedfs-map-nfs4: $(fedfs-map-nfs4_OBJ) $(fedfs-getsrvinfo_OBJ) $(HDRS) +- $(CC) -o fedfs-map-nfs4 \ ++ $(CC) $(DAEMON_LDFLAGS) -o fedfs-map-nfs4 \ + $(fedfs-map-nfs4_OBJ) $(fedfs-getsrvinfo_OBJ) \ + $(LDFLAGS) $(LIBRESOLV) $(LIBS) + diff --git a/autofs-5.1.8-fix-fix-root-offset-error-handling.patch b/autofs-5.1.8-fix-fix-root-offset-error-handling.patch new file mode 100644 index 0000000..d58777a --- /dev/null +++ b/autofs-5.1.8-fix-fix-root-offset-error-handling.patch @@ -0,0 +1,38 @@ +autofs-5.1.8 - fix fix root offset error handling + +From: Ian Kent + +The change to fix root offset error handlling is missing a cache read +lock prior to the key lookup, the following unmatched unlock then +causes a hang. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 6f18a0bb..f81b0259 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -3,6 +3,7 @@ + - fix set open file limit. + - improve descriptor open error reporting. + - fix root offset error handling. ++- fix fix root offset error handling. + + 19/10/2021 autofs-5.1.8 + - add xdr_exports(). +diff --git a/daemon/direct.c b/daemon/direct.c +index 8810900c..cf3f24d7 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -1275,6 +1275,7 @@ static void *do_mount_direct(void *arg) + /* If this is a multi-mount subtree mount failure + * ensure the tree continues to expire. + */ ++ cache_readlock(mt.mc); + me = cache_lookup_distinct(mt.mc, mt.name); + if (me && IS_MM(me) && !IS_MM_ROOT(me)) + conditional_alarm_add(ap, ap->exp_runfreq); diff --git a/autofs-5.1.8-fix-handling-of-incorrect-return-from-umount_ent.patch b/autofs-5.1.8-fix-handling-of-incorrect-return-from-umount_ent.patch new file mode 100644 index 0000000..af63d29 --- /dev/null +++ b/autofs-5.1.8-fix-handling-of-incorrect-return-from-umount_ent.patch @@ -0,0 +1,116 @@ +autofs-5.1.8 - fix handling of incorrect return from umount_ent() + +From: Ian Kent + +Commit 0210535df4b ("autofs-5.1.0 - gaurd against incorrect umount +return") guards against umount_ent() returning a fail when the mount +has actually been umounted. + +But we also see umount_ent() return success when in fact the mount has +not been umounted leading to incorrect handling of automounts. + +So checking the return of umount_ent() isn't always giving the correct +result in more than just one case, consequently we should ignore the +result from the spawned umount(8) and check if the mount has in fact +been umounted. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 3 +-- + lib/mounts.c | 19 ++++++++++--------- + 3 files changed, 12 insertions(+), 11 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 5402b88d..72a5aa59 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -15,6 +15,7 @@ + - avoid calling pthread_getspecific() with NULL key_thread_attempt_id. + - fix sysconf(3) return handling. + - remove nonstrict parameter from tree_mapent_umount_offsets(). ++- fix handling of incorrect return from umount_ent(). + + 19/10/2021 autofs-5.1.8 + - add xdr_exports(). +diff --git a/daemon/automount.c b/daemon/automount.c +index 353e4f54..85847edf 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -609,8 +609,7 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi + struct mnt_list *mnt; + + debug(ap->logopt, "unmounting dir = %s", path); +- if (umount_ent(ap, path) && +- is_mounted(path, MNTS_REAL)) { ++ if (umount_ent(ap, path)) { + warn(ap->logopt, "could not umount dir %s", path); + left++; + goto done; +diff --git a/lib/mounts.c b/lib/mounts.c +index 617c1d54..a3f9dfd7 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1869,8 +1869,7 @@ static int tree_mapent_umount_offset(struct mapent *oe, void *ptr) + */ + if (oe->ioctlfd != -1 || + is_mounted(oe->key, MNTS_REAL)) { +- if (umount_ent(ap, oe->key) && +- is_mounted(oe->key, MNTS_REAL)) { ++ if (umount_ent(ap, oe->key)) { + debug(ap->logopt, + "offset %s has active mount, invalidate", + oe->key); +@@ -2010,8 +2009,7 @@ int tree_mapent_umount_offsets(struct mapent *oe) + */ + if (is_mounted(mp, MNTS_REAL)) { + info(ap->logopt, "unmounting dir = %s", mp); +- if (umount_ent(ap, mp) && +- is_mounted(mp, MNTS_REAL)) { ++ if (umount_ent(ap, mp)) { + if (!tree_mapent_mount_offsets(oe, 1)) + warn(ap->logopt, + "failed to remount offset triggers"); +@@ -2982,6 +2980,7 @@ void set_direct_mount_tree_catatonic(struct autofs_point *ap, struct mapent *me) + + int umount_ent(struct autofs_point *ap, const char *path) + { ++ unsigned int mounted; + int rv; + + if (ap->state != ST_SHUTDOWN_FORCE) +@@ -2993,6 +2992,8 @@ int umount_ent(struct autofs_point *ap, const char *path) + rv = spawn_umount(ap->logopt, "-l", path, NULL); + } + ++ mounted = is_mounted(path, MNTS_REAL); ++ + if (rv && (ap->state == ST_SHUTDOWN_FORCE || ap->state == ST_SHUTDOWN)) { + /* + * Verify that we actually unmounted the thing. This is a +@@ -3004,20 +3005,20 @@ int umount_ent(struct autofs_point *ap, const char *path) + * so that we do not try to call rmdir_path on the + * directory. + */ +- if (is_mounted(path, MNTS_REAL)) { ++ if (mounted) { + crit(ap->logopt, + "the umount binary reported that %s was " + "unmounted, but there is still something " + "mounted on this path.", path); +- rv = -1; ++ mounted = -1; + } + } + +- /* On success, check for mounted mount and remove it if found */ +- if (!rv) ++ /* If mount is gone remove it from mounted mounts list. */ ++ if (!mounted) + mnts_remove_mount(path, MNTS_MOUNTED); + +- return rv; ++ return mounted; + } + + int umount_amd_ext_mount(struct autofs_point *ap, const char *path) diff --git a/autofs-5.1.8-fix-kernel-mount-status-notification.patch b/autofs-5.1.8-fix-kernel-mount-status-notification.patch new file mode 100644 index 0000000..f2ed2e8 --- /dev/null +++ b/autofs-5.1.8-fix-kernel-mount-status-notification.patch @@ -0,0 +1,139 @@ +autofs-5.1.8 - fix kernel mount status notification + +From: Ian Kent + +The status return for attempted mount notification is not done +correctly in some cases leading to a status being sent to the +kernel multiple times or the send causing an error. + +We must send a status to the kernel but it needs to be the correct +one. It definitely shouldn't be sent twice for the same mount attempt +and shouldn't be failing. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 2 ++ + daemon/direct.c | 19 +++++++++++-------- + daemon/indirect.c | 19 +++++++++++-------- + 3 files changed, 24 insertions(+), 16 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 3be6119a..9d92229a 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -1,3 +1,5 @@ ++- fix kernel mount status notificantion. ++ + 19/10/2021 autofs-5.1.8 + - add xdr_exports(). + - remove mount.x and rpcgen dependencies. +diff --git a/daemon/direct.c b/daemon/direct.c +index 4a56486b..c2331155 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -1147,12 +1147,18 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di + return 0; + } + +-static void mount_send_fail(void *arg) ++static void mount_send_status(void *arg) + { + struct ioctl_ops *ops = get_ioctl_ops(); + struct pending_args *mt = arg; + struct autofs_point *ap = mt->ap; +- ops->send_fail(ap->logopt, mt->ioctlfd, mt->wait_queue_token, -ENOENT); ++ ++ if (mt->status) ++ ops->send_fail(ap->logopt, mt->ioctlfd, ++ mt->wait_queue_token, mt->status); ++ else ++ ops->send_ready(ap->logopt, ++ mt->ioctlfd, mt->wait_queue_token); + ops->close(ap->logopt, mt->ioctlfd); + } + +@@ -1181,7 +1187,8 @@ static void *do_mount_direct(void *arg) + + pending_mutex_unlock(args); + +- pthread_cleanup_push(mount_send_fail, &mt); ++ mt.status = 0; ++ pthread_cleanup_push(mount_send_status, &mt); + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); + +@@ -1195,9 +1202,7 @@ static void *do_mount_direct(void *arg) + if (status == -1) { + error(ap->logopt, + "can't stat direct mount trigger %s", mt.name); +- ops->send_fail(ap->logopt, +- mt.ioctlfd, mt.wait_queue_token, -ENOENT); +- ops->close(ap->logopt, mt.ioctlfd); ++ mt.status = -ENOENT; + pthread_setcancelstate(state, NULL); + pthread_exit(NULL); + } +@@ -1207,8 +1212,6 @@ static void *do_mount_direct(void *arg) + error(ap->logopt, + "direct trigger not valid or already mounted %s", + mt.name); +- ops->send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token); +- ops->close(ap->logopt, mt.ioctlfd); + pthread_setcancelstate(state, NULL); + pthread_exit(NULL); + } +diff --git a/daemon/indirect.c b/daemon/indirect.c +index b73c2781..23ef9f41 100644 +--- a/daemon/indirect.c ++++ b/daemon/indirect.c +@@ -683,13 +683,18 @@ int handle_packet_expire_indirect(struct autofs_point *ap, autofs_packet_expire_ + return 0; + } + +-static void mount_send_fail(void *arg) ++static void mount_send_status(void *arg) + { + struct ioctl_ops *ops = get_ioctl_ops(); + struct pending_args *mt = arg; + struct autofs_point *ap = mt->ap; +- ops->send_fail(ap->logopt, +- ap->ioctlfd, mt->wait_queue_token, -ENOENT); ++ ++ if (mt->status) ++ ops->send_fail(ap->logopt, ap->ioctlfd, ++ mt->wait_queue_token, mt->status); ++ else ++ ops->send_ready(ap->logopt, ++ ap->ioctlfd, mt->wait_queue_token); + } + + static void *do_mount_indirect(void *arg) +@@ -718,7 +723,8 @@ static void *do_mount_indirect(void *arg) + + pending_mutex_unlock(args); + +- pthread_cleanup_push(mount_send_fail, &mt); ++ mt.status = 0; ++ pthread_cleanup_push(mount_send_status, &mt); + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); + +@@ -731,9 +737,7 @@ static void *do_mount_indirect(void *arg) + len = ncat_path(buf, sizeof(buf), ap->path, mt.name, mt.len); + if (!len) { + crit(ap->logopt, "path to be mounted is to long"); +- ops->send_fail(ap->logopt, +- ap->ioctlfd, mt.wait_queue_token, +- -ENAMETOOLONG); ++ mt.status = -ENAMETOOLONG; + pthread_setcancelstate(state, NULL); + pthread_exit(NULL); + } +@@ -742,7 +746,6 @@ static void *do_mount_indirect(void *arg) + if (status != -1 && !(S_ISDIR(st.st_mode) && st.st_dev == mt.dev)) { + error(ap->logopt, + "indirect trigger not valid or already mounted %s", buf); +- ops->send_ready(ap->logopt, ap->ioctlfd, mt.wait_queue_token); + pthread_setcancelstate(state, NULL); + pthread_exit(NULL); + } diff --git a/autofs-5.1.8-fix-loop-under-run-in-cache_get_offset_parent.patch b/autofs-5.1.8-fix-loop-under-run-in-cache_get_offset_parent.patch new file mode 100644 index 0000000..addac3a --- /dev/null +++ b/autofs-5.1.8-fix-loop-under-run-in-cache_get_offset_parent.patch @@ -0,0 +1,40 @@ +autofs-5.1.8 - fix loop under run in cache_get_offset_parent() + +From: Frank Sorenson + +To avoid reading memory outside of the the string +allocated for parent, tail needs to stop when it +reaches or passes parent, even if it doesn't +actually equal parent. + +Signed-off-by: Frank Sorenson +--- + CHANGELOG | 1 + + lib/cache.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index aaf20cd6..b4b064ff 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -6,6 +6,7 @@ + - fix fix root offset error handling. + - fix nonstrict fail handling of last offset mount. + - dont fail on duplicate offset entry tree add. ++- fix loop under run in cache_get_offset_parent(). + + 19/10/2021 autofs-5.1.8 + - add xdr_exports(). +diff --git a/lib/cache.c b/lib/cache.c +index 66dda5d9..8aed28ea 100644 +--- a/lib/cache.c ++++ b/lib/cache.c +@@ -710,7 +710,7 @@ struct mapent *cache_get_offset_parent(struct mapent_cache *mc, const char *key) + *tail = 0; + + tail--; +- if (tail == parent) ++ if (tail <= parent) + break; + + me = cache_lookup_distinct(mc, parent); diff --git a/autofs-5.1.8-fix-memory-leak-in-xdr_exports.patch b/autofs-5.1.8-fix-memory-leak-in-xdr_exports.patch new file mode 100644 index 0000000..0bf6f28 --- /dev/null +++ b/autofs-5.1.8-fix-memory-leak-in-xdr_exports.patch @@ -0,0 +1,44 @@ +autofs-5.1.8 - fix memory leak in xdr_exports() + +From: Ian Kent + +Converting xdr_exports() to not be recursive introduced a memory leak +if an error is encountered, fix it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/rpc_subs.c | 7 ++++++- + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index f05c9c6b..9d57a21b 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -11,6 +11,7 @@ + - fix nfsv4 only mounts should not use rpcbind. + - simplify cache_add() a little. + - fix use after free in tree_mapent_delete_offset_tree(). ++- fix memory leak in xdr_exports(). + + 19/10/2021 autofs-5.1.8 + - add xdr_exports(). +diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c +index ee7f94b9..0c833af0 100644 +--- a/lib/rpc_subs.c ++++ b/lib/rpc_subs.c +@@ -1151,8 +1151,13 @@ bool_t xdr_exports(XDR *xdrs, struct exportinfo **exports) + + export = (char **) exports; + while (1) { +- if (!xdr_pointer(xdrs, export, size, (xdrproc_t) xdr_export)) ++ if (!xdr_pointer(xdrs, export, size, (xdrproc_t) xdr_export)) { ++ if (*exports) { ++ rpc_exports_free(*exports); ++ *exports = NULL; ++ } + return FALSE; ++ } + if (!*export) + break; + export = (char **) &((struct exportinfo *) *export)->next; diff --git a/autofs-5.1.8-fix-nfsv4-only-mounts-should-not-use-rpcbind.patch b/autofs-5.1.8-fix-nfsv4-only-mounts-should-not-use-rpcbind.patch new file mode 100644 index 0000000..184c001 --- /dev/null +++ b/autofs-5.1.8-fix-nfsv4-only-mounts-should-not-use-rpcbind.patch @@ -0,0 +1,102 @@ +autofs-5.1.8 - fix nfsv4 only mounts should not use rpcbind + +From: Ian Kent + +Commit 606795ecfaa1 ("autofs-5.1.7 - also require TCP_REQUESTED when +setting NFS port" together with commit 26fb6b5408be) caused NFSv4 only +mounts to also use rpcbind to probe availability which breaks the +requirememt that this type of mount not use rpcbind at all. + +Fix this by treating fstype=nfs4 mounts as a special case which doesn't +use rpcbind. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/replicated.h | 2 ++ + modules/mount_nfs.c | 13 +++++++------ + modules/replicated.c | 4 ++-- + 4 files changed, 12 insertions(+), 8 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 575f186d..4e5e82d0 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -8,6 +8,7 @@ + - dont fail on duplicate offset entry tree add. + - fix loop under run in cache_get_offset_parent(). + - bailout on rpc systemerror. ++- fix nfsv4 only mounts should not use rpcbind. + + 19/10/2021 autofs-5.1.8 + - add xdr_exports(). +diff --git a/include/replicated.h b/include/replicated.h +index 95ff1f0d..f889a56a 100644 +--- a/include/replicated.h ++++ b/include/replicated.h +@@ -35,6 +35,8 @@ + #define NFS3_REQUESTED NFS3_SUPPORTED + #define NFS4_REQUESTED NFS4_SUPPORTED + ++#define NFS4_ONLY_REQUESTED 0x0800 ++ + #define TCP_SUPPORTED 0x0001 + #define UDP_SUPPORTED 0x0002 + #define TCP_REQUESTED TCP_SUPPORTED +diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c +index 0ab87dcf..feb5afcd 100644 +--- a/modules/mount_nfs.c ++++ b/modules/mount_nfs.c +@@ -92,7 +92,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + mount_default_proto = defaults_get_mount_nfs_default_proto(); + vers = NFS_VERS_DEFAULT | NFS_PROTO_DEFAULT; + if (strcmp(fstype, "nfs4") == 0) +- vers = NFS4_VERS_DEFAULT | TCP_SUPPORTED; ++ vers = NFS4_VERS_DEFAULT | TCP_SUPPORTED | NFS4_ONLY_REQUESTED; + else if (mount_default_proto == 4) + vers = vers | NFS4_VERS_DEFAULT; + +@@ -157,15 +157,16 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + } else { + /* Is any version of NFSv4 in the options */ + if (_strncmp("vers=4", cp, 6) == 0 || +- _strncmp("nfsvers=4", cp, 9) == 0) +- vers = NFS4_VERS_MASK | TCP_SUPPORTED; +- else if (_strncmp("vers=3", cp, o_len) == 0 || ++ _strncmp("nfsvers=4", cp, 9) == 0) { ++ vers &= ~(NFS_VERS_MASK); ++ vers |= NFS4_VERS_MASK | TCP_SUPPORTED | NFS4_ONLY_REQUESTED; ++ } else if (_strncmp("vers=3", cp, o_len) == 0 || + _strncmp("nfsvers=3", cp, o_len) == 0) { +- vers &= ~(NFS4_VERS_MASK | NFS_VERS_MASK); ++ vers &= ~(NFS4_VERS_MASK | NFS_VERS_MASK | NFS4_ONLY_REQUESTED); + vers |= NFS3_REQUESTED; + } else if (_strncmp("vers=2", cp, o_len) == 0 || + _strncmp("nfsvers=2", cp, o_len) == 0) { +- vers &= ~(NFS4_VERS_MASK | NFS_VERS_MASK); ++ vers &= ~(NFS4_VERS_MASK | NFS_VERS_MASK | NFS4_ONLY_REQUESTED); + vers |= NFS2_REQUESTED; + } else if (strstr(cp, "port=") == cp && + o_len - 5 < 25) { +diff --git a/modules/replicated.c b/modules/replicated.c +index 09075dd0..cdb7c617 100644 +--- a/modules/replicated.c ++++ b/modules/replicated.c +@@ -291,7 +291,7 @@ static unsigned int get_nfs_info(unsigned logopt, struct host *host, + + rpc_info->proto = proto; + if (port < 0) { +- if ((version & NFS4_REQUESTED) && (version & TCP_REQUESTED)) ++ if (version & NFS4_REQUESTED && (version & NFS4_ONLY_REQUESTED)) + rpc_info->port = NFS_PORT; + else + port = 0; +@@ -525,7 +525,7 @@ static int get_vers_and_cost(unsigned logopt, struct host *host, + { + struct conn_info pm_info, rpc_info; + time_t timeout = RPC_TIMEOUT; +- unsigned int supported, vers = (NFS_VERS_MASK | NFS4_VERS_MASK); ++ unsigned int supported, vers = (NFS_VERS_MASK | NFS4_VERS_MASK | NFS4_ONLY_REQUESTED); + int ret = 0; + + if (!check_address_proto(logopt, host, version)) diff --git a/autofs-5.1.8-fix-nonstrict-fail-handling-of-last-offset-mount.patch b/autofs-5.1.8-fix-nonstrict-fail-handling-of-last-offset-mount.patch new file mode 100644 index 0000000..667369e --- /dev/null +++ b/autofs-5.1.8-fix-nonstrict-fail-handling-of-last-offset-mount.patch @@ -0,0 +1,42 @@ +autofs-5.1.8 - fix nonstrict fail handling of last offset mount + +From: Ian Kent + +When mounting a list of multi-mount offsets the offset mount should +succeed even if there's a mount failure for the non-strict case (the +default). + +But currently if the last offset mount fails the multi-mount fails +regardless of whether the mount is non-strict or not. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index f81b0259..bd1f672c 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -4,6 +4,7 @@ + - improve descriptor open error reporting. + - fix root offset error handling. + - fix fix root offset error handling. ++- fix nonstrict fail handling of last offset mount. + + 19/10/2021 autofs-5.1.8 + - add xdr_exports(). +diff --git a/lib/mounts.c b/lib/mounts.c +index 39b7fe81..b4229908 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1940,7 +1940,7 @@ static int tree_mapent_mount_offsets_work(struct tree_node *n, void *ptr) + tree_mapent_mount_offsets(oe, !ctxt->strict); + } + +- return ret; ++ return (ctxt->strict ? ret : 1); + } + + int tree_mapent_mount_offsets(struct mapent *oe, int nonstrict) diff --git a/autofs-5.1.8-fix-root-offset-error-handling.patch b/autofs-5.1.8-fix-root-offset-error-handling.patch new file mode 100644 index 0000000..f4f2116 --- /dev/null +++ b/autofs-5.1.8-fix-root-offset-error-handling.patch @@ -0,0 +1,91 @@ +autofs-5.1.8 - fix root offset error handling + +From: Ian Kent + +If mounting the root or offsets of a multi-mount root fails any mounts +done so far need to be umounted and the multi-mount offset tree deleted +so it can be created cleanly and possibly mounted the next time it's +triggered. + +Also, if a subtree that is not the multi-mount root fails the expire +alarm needs to be re-instated so other subtrees (at least the root) +will continue to expire. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 10 +++++++++- + modules/parse_sun.c | 6 ++++++ + 3 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 870fd8f3..6f18a0bb 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -2,6 +2,7 @@ + - fix fedfs build flags. + - fix set open file limit. + - improve descriptor open error reporting. ++- fix root offset error handling. + + 19/10/2021 autofs-5.1.8 + - add xdr_exports(). +diff --git a/daemon/direct.c b/daemon/direct.c +index c2331155..8810900c 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -1167,6 +1167,7 @@ static void *do_mount_direct(void *arg) + struct ioctl_ops *ops = get_ioctl_ops(); + struct pending_args *args, mt; + struct autofs_point *ap; ++ struct mapent *me; + struct stat st; + int status, state; + +@@ -1230,7 +1231,6 @@ static void *do_mount_direct(void *arg) + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); + if (status) { + struct mnt_list *sbmnt; +- struct mapent *me; + struct statfs fs; + unsigned int close_fd = 0; + unsigned int flags = MNTS_DIRECT|MNTS_MOUNTED; +@@ -1271,6 +1271,14 @@ static void *do_mount_direct(void *arg) + mt.ioctlfd, mt.wait_queue_token, -ENOENT); + ops->close(ap->logopt, mt.ioctlfd); + info(ap->logopt, "failed to mount %s", mt.name); ++ ++ /* If this is a multi-mount subtree mount failure ++ * ensure the tree continues to expire. ++ */ ++ me = cache_lookup_distinct(mt.mc, mt.name); ++ if (me && IS_MM(me) && !IS_MM_ROOT(me)) ++ conditional_alarm_add(ap, ap->exp_runfreq); ++ cache_unlock(mt.mc); + } + pthread_setcancelstate(state, NULL); + +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index d9ac0c94..56fe4161 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -1142,6 +1142,9 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc, + if (!len) { + warn(ap->logopt, "path loo long"); + cache_unlock(mc); ++ cache_writelock(mc); ++ tree_mapent_delete_offsets(mc, name); ++ cache_unlock(mc); + return 1; + } + key[len] = '/'; +@@ -1186,6 +1189,9 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc, + cache_unlock(mc); + error(ap->logopt, MODPREFIX + "failed to mount offset triggers"); ++ cache_writelock(mc); ++ tree_mapent_delete_offsets(mc, name); ++ cache_unlock(mc); + return 1; + } + } diff --git a/autofs-5.1.8-fix-set-open-file-limit.patch b/autofs-5.1.8-fix-set-open-file-limit.patch new file mode 100644 index 0000000..c43ace1 --- /dev/null +++ b/autofs-5.1.8-fix-set-open-file-limit.patch @@ -0,0 +1,56 @@ +autofs-5.1.8 - fix set open file limit + +From: Ian Kent + +The check of whether the open file limit needs to be changed is not +right, it checks the hard open file limit against what autofs wants +to set it to which is always less than this value. Consequently the +open file limit isn't changed. + +autofs should be changing only the soft open file limit but it is +setting both the hard and soft limits. The system hard limit is much +higer than the autofs maximum open files so the hard limit should be +left alone. + +While we are here increase the requested maximum soft open file limit +to 20k. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 7 ++++--- + 2 files changed, 5 insertions(+), 3 deletions(-) + +--- autofs-5.1.8.orig/CHANGELOG ++++ autofs-5.1.8/CHANGELOG +@@ -1,5 +1,6 @@ + - fix kernel mount status notificantion. + - fix fedfs build flags. ++- fix set open file limit. + + 19/10/2021 autofs-5.1.8 + - add xdr_exports(). +--- autofs-5.1.8.orig/daemon/automount.c ++++ autofs-5.1.8/daemon/automount.c +@@ -94,7 +94,7 @@ struct startup_cond suc = { + pthread_key_t key_thread_stdenv_vars; + pthread_key_t key_thread_attempt_id = (pthread_key_t) 0L; + +-#define MAX_OPEN_FILES 10240 ++#define MAX_OPEN_FILES 20480 + + int aquire_flag_file(void); + void release_flag_file(void); +@@ -2486,9 +2486,10 @@ int main(int argc, char *argv[]) + } + + res = getrlimit(RLIMIT_NOFILE, &rlim); +- if (res == -1 || rlim.rlim_max <= MAX_OPEN_FILES) { ++ if (res == -1 || rlim.rlim_cur <= MAX_OPEN_FILES) { + rlim.rlim_cur = MAX_OPEN_FILES; +- rlim.rlim_max = MAX_OPEN_FILES; ++ if (rlim.rlim_max < MAX_OPEN_FILES) ++ rlim.rlim_max = MAX_OPEN_FILES; + } + res = setrlimit(RLIMIT_NOFILE, &rlim); + if (res) diff --git a/autofs-5.1.8-fix-sysconf-return-handling.patch b/autofs-5.1.8-fix-sysconf-return-handling.patch new file mode 100644 index 0000000..903715c --- /dev/null +++ b/autofs-5.1.8-fix-sysconf-return-handling.patch @@ -0,0 +1,68 @@ +autofs-5.1.8 - fix sysconf(3) return handling + +From: Fabian Groffen + +The sysconf(3) return handling doesn't handle a -1 return with errno +not changed which indicated a maximum or minimum limit that's not +known. + +Add handling of this case. + +Signed-off-by: Fabian Groffen +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 13 +++++++++++-- + 2 files changed, 12 insertions(+), 2 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index dacc2fa0..a063a126 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -13,6 +13,7 @@ + - fix use after free in tree_mapent_delete_offset_tree(). + - fix memory leak in xdr_exports(). + - avoid calling pthread_getspecific() with NULL key_thread_attempt_id. ++- fix sysconf(3) return handling. + + 19/10/2021 autofs-5.1.8 + - add xdr_exports(). +diff --git a/lib/mounts.c b/lib/mounts.c +index c731f464..ad8f3de4 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -2385,11 +2385,17 @@ void set_tsd_user_vars(unsigned int logopt, uid_t uid, gid_t gid) + + /* Try to get passwd info */ + ++ /* sysconf may return -1 with unchanged errno to indicate unlimited ++ * size, same for the call for _SC_GETGR_R_SIZE_MAX below ++ */ ++ errno = 0; + tmplen = sysconf(_SC_GETPW_R_SIZE_MAX); +- if (tmplen < 0) { ++ if (tmplen < 0 && errno != 0) { + error(logopt, "failed to get buffer size for getpwuid_r"); + goto free_tsv; + } ++ if (tmplen < 0) ++ tmplen = 1024; /* assume something reasonable */ + + pw_tmp = malloc(tmplen + 1); + if (!pw_tmp) { +@@ -2422,11 +2428,14 @@ void set_tsd_user_vars(unsigned int logopt, uid_t uid, gid_t gid) + + /* Try to get group info */ + ++ errno = 0; + grplen = sysconf(_SC_GETGR_R_SIZE_MAX); +- if (grplen < 0) { ++ if (grplen < 0 && errno != 0) { + error(logopt, "failed to get buffer size for getgrgid_r"); + goto free_tsv_home; + } ++ if (grplen < 0) ++ grplen = 1024; + + gr_tmp = NULL; + status = ERANGE; diff --git a/autofs-5.1.8-fix-use-after-free-in-tree_mapent_delete_offset_tree.patch b/autofs-5.1.8-fix-use-after-free-in-tree_mapent_delete_offset_tree.patch new file mode 100644 index 0000000..f90543e --- /dev/null +++ b/autofs-5.1.8-fix-use-after-free-in-tree_mapent_delete_offset_tree.patch @@ -0,0 +1,59 @@ +autofs-5.1.8 - fix use after free in tree_mapent_delete_offset_tree() + +From: Ian Kent + +The key field of the map entry of the root of the map entry tree to be +deleted can't be used for the key parameter, fix it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 16 +++++++++++++--- + 2 files changed, 14 insertions(+), 3 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 5b37460f..f05c9c6b 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -10,6 +10,7 @@ + - bailout on rpc systemerror. + - fix nfsv4 only mounts should not use rpcbind. + - simplify cache_add() a little. ++- fix use after free in tree_mapent_delete_offset_tree(). + + 19/10/2021 autofs-5.1.8 + - add xdr_exports(). +diff --git a/lib/mounts.c b/lib/mounts.c +index 451849a6..c731f464 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1666,16 +1666,26 @@ static int tree_mapent_delete_offset_tree(struct tree_node *root) + */ + if (MAPENT_ROOT(me) != MAPENT_NODE(me)) { + struct tree_node *root = MAPENT_ROOT(me); ++ char *key; + +- debug(logopt, "deleting offset key %s", me->key); ++ key = strdup(me->key); ++ if (!key) { ++ char buf[MAX_ERR_BUF]; ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(logopt, "strdup: %s", estr); ++ return 0; ++ } ++ ++ debug(logopt, "deleting offset key %s", key); + + /* cache_delete won't delete an active offset */ + MAPENT_SET_ROOT(me, NULL); +- ret = cache_delete(me->mc, me->key); ++ ret = cache_delete(me->mc, key); + if (ret != CHE_OK) { + MAPENT_SET_ROOT(me, root); +- warn(logopt, "failed to delete offset %s", me->key); ++ warn(logopt, "failed to delete offset %s", key); + } ++ free(key); + } else { + MAPENT_SET_ROOT(me, NULL); + MAPENT_SET_PARENT(me, NULL); diff --git a/autofs-5.1.8-improve-descriptor-open-error-reporting.patch b/autofs-5.1.8-improve-descriptor-open-error-reporting.patch new file mode 100644 index 0000000..4b6d82a --- /dev/null +++ b/autofs-5.1.8-improve-descriptor-open-error-reporting.patch @@ -0,0 +1,165 @@ +autofs-5.1.8 - improve descriptor open error reporting + +From: Ian Kent + +Add error message reporting to the descriptor open functions. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 3 --- + daemon/spawn.c | 29 +++++++++++++++++++++++++++++ + lib/mounts.c | 10 ++-------- + modules/lookup_program.c | 5 +---- + 5 files changed, 33 insertions(+), 15 deletions(-) + +--- autofs-5.1.8.orig/CHANGELOG ++++ autofs-5.1.8/CHANGELOG +@@ -1,6 +1,7 @@ + - fix kernel mount status notificantion. + - fix fedfs build flags. + - fix set open file limit. ++- improve descriptor open error reporting. + + 19/10/2021 autofs-5.1.8 + - add xdr_exports(). +--- autofs-5.1.8.orig/daemon/automount.c ++++ autofs-5.1.8/daemon/automount.c +@@ -868,9 +868,6 @@ static int create_logpri_fifo(struct aut + + fd = open_fd(fifo_name, O_RDWR|O_NONBLOCK); + if (fd < 0) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- crit(ap->logopt, +- "Failed to open %s: %s", fifo_name, estr); + unlink(fifo_name); + ret = -1; + goto out_free; +--- autofs-5.1.8.orig/daemon/spawn.c ++++ autofs-5.1.8/daemon/spawn.c +@@ -94,7 +94,12 @@ int open_fd(const char *path, int flags) + #endif + fd = open(path, flags); + if (fd == -1) { ++ char buf[MAX_ERR_BUF]; ++ char *estr; ++ + open_mutex_unlock(); ++ estr = strerror_r(errno, buf, sizeof(buf)); ++ logerr("failed to open file: %s", estr); + return -1; + } + check_cloexec(fd); +@@ -113,7 +118,12 @@ int open_fd_mode(const char *path, int f + #endif + fd = open(path, flags, mode); + if (fd == -1) { ++ char buf[MAX_ERR_BUF]; ++ char *estr; ++ + open_mutex_unlock(); ++ estr = strerror_r(errno, buf, sizeof(buf)); ++ logerr("failed to open file: %s", estr); + return -1; + } + check_cloexec(fd); +@@ -123,6 +133,8 @@ int open_fd_mode(const char *path, int f + + int open_pipe(int pipefd[2]) + { ++ char buf[MAX_ERR_BUF]; ++ char *estr; + int ret; + + open_mutex_lock(); +@@ -145,6 +157,8 @@ done: + return 0; + err: + open_mutex_unlock(); ++ estr = strerror_r(errno, buf, sizeof(buf)); ++ logerr("failed to open pipe: %s", estr); + return -1; + } + +@@ -159,7 +173,12 @@ int open_sock(int domain, int type, int + #endif + fd = socket(domain, type, protocol); + if (fd == -1) { ++ char buf[MAX_ERR_BUF]; ++ char *estr; ++ + open_mutex_unlock(); ++ estr = strerror_r(errno, buf, sizeof(buf)); ++ logerr("failed to open socket: %s", estr); + return -1; + } + check_cloexec(fd); +@@ -184,7 +203,12 @@ FILE *open_fopen_r(const char *path) + #endif + f = fopen(path, "r"); + if (f == NULL) { ++ char buf[MAX_ERR_BUF]; ++ char *estr; ++ + open_mutex_unlock(); ++ estr = strerror_r(errno, buf, sizeof(buf)); ++ logerr("failed to open file: %s", estr); + return NULL; + } + check_cloexec(fileno(f)); +@@ -209,7 +233,12 @@ FILE *open_setmntent_r(const char *table + #endif + tab = fopen(table, "r"); + if (tab == NULL) { ++ char buf[MAX_ERR_BUF]; ++ char *estr; ++ + open_mutex_unlock(); ++ estr = strerror_r(errno, buf, sizeof(buf)); ++ logerr("failed to open mount table: %s", estr); + return NULL; + } + check_cloexec(fileno(tab)); +--- autofs-5.1.8.orig/lib/mounts.c ++++ autofs-5.1.8/lib/mounts.c +@@ -2169,11 +2169,8 @@ struct mnt_list *get_mnt_list(const char + return NULL; + + tab = open_fopen_r(_PROC_MOUNTS); +- if (!tab) { +- char *estr = strerror_r(errno, buf, PATH_MAX - 1); +- logerr("fopen: %s", estr); ++ if (!tab) + return NULL; +- } + + while ((mnt = local_getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) { + len = strlen(mnt->mnt_dir); +@@ -2280,11 +2277,8 @@ static int table_is_mounted(const char * + return 0; + + tab = open_fopen_r(_PROC_MOUNTS); +- if (!tab) { +- char *estr = strerror_r(errno, buf, PATH_MAX - 1); +- logerr("fopen: %s", estr); ++ if (!tab) + return 0; +- } + + while ((mnt = local_getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) { + size_t len = strlen(mnt->mnt_dir); +--- autofs-5.1.8.orig/modules/lookup_program.c ++++ autofs-5.1.8/modules/lookup_program.c +@@ -214,11 +214,8 @@ static char *lookup_one(struct autofs_po + * want to send stderr to the syslog, and we don't use spawnl() + * because we need the pipe hooks + */ +- if (open_pipe(pipefd)) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr(MODPREFIX "pipe: %s", estr); ++ if (open_pipe(pipefd)) + goto out_error; +- } + if (open_pipe(epipefd)) { + close(pipefd[0]); + close(pipefd[1]); diff --git a/autofs-5.1.8-remove-nonstrict-parameter-from-tree_mapent_umount_offsets.patch b/autofs-5.1.8-remove-nonstrict-parameter-from-tree_mapent_umount_offsets.patch new file mode 100644 index 0000000..897d831 --- /dev/null +++ b/autofs-5.1.8-remove-nonstrict-parameter-from-tree_mapent_umount_offsets.patch @@ -0,0 +1,85 @@ +autofs-5.1.8 - remove nonstrict parameter from tree_mapent_umount_offsets() + +From: Ian Kent + +The nonstrict parameter of tree_mapent_umount_offsets() ins't useful +because if a real mount at the base of a sub-tree fails to umount all +we can do is re-instate the offset mounts under it which must succeed +for the mount tree to remain useful. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 2 +- + include/mounts.h | 2 +- + lib/mounts.c | 6 +++--- + 4 files changed, 6 insertions(+), 5 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index a063a126..5402b88d 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -14,6 +14,7 @@ + - fix memory leak in xdr_exports(). + - avoid calling pthread_getspecific() with NULL key_thread_attempt_id. + - fix sysconf(3) return handling. ++- remove nonstrict parameter from tree_mapent_umount_offsets(). + + 19/10/2021 autofs-5.1.8 + - add xdr_exports(). +diff --git a/daemon/automount.c b/daemon/automount.c +index b47c485b..353e4f54 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -558,7 +558,7 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi + struct mapent *tmp; + int ret; + +- ret = tree_mapent_umount_offsets(me, 1); ++ ret = tree_mapent_umount_offsets(me); + if (!ret) { + warn(ap->logopt, + "some offset mounts still present under %s", path); +diff --git a/include/mounts.h b/include/mounts.h +index ddb7e4c5..23c7ba1c 100644 +--- a/include/mounts.h ++++ b/include/mounts.h +@@ -182,7 +182,7 @@ int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, struct + 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); +-int tree_mapent_umount_offsets(struct mapent *oe, int nonstrict); ++int tree_mapent_umount_offsets(struct mapent *oe); + int unlink_mount_tree(struct autofs_point *ap, const char *mp); + void free_mnt_list(struct mnt_list *list); + int is_mounted(const char *mp, unsigned int type); +diff --git a/lib/mounts.c b/lib/mounts.c +index ad8f3de4..617c1d54 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1843,7 +1843,7 @@ static int tree_mapent_umount_offset(struct mapent *oe, void *ptr) + * Check for and umount subtree offsets resulting from + * nonstrict mount fail. + */ +- ret = tree_mapent_umount_offsets(oe, ctxt->strict); ++ ret = tree_mapent_umount_offsets(oe); + if (!ret) + return 0; + +@@ -1975,14 +1975,14 @@ static int tree_mapent_umount_offsets_work(struct tree_node *n, void *ptr) + return tree_mapent_umount_offset(oe, ptr); + } + +-int tree_mapent_umount_offsets(struct mapent *oe, int nonstrict) ++int tree_mapent_umount_offsets(struct mapent *oe) + { + struct tree_node *base = MAPENT_NODE(oe); + struct autofs_point *ap = oe->mc->ap; + struct traverse_subtree_context ctxt = { + .ap = ap, + .base = base, +- .strict = !nonstrict, ++ .strict = 1, + }; + int ret; + diff --git a/autofs-5.1.8-simplify-cache_add-a-little.patch b/autofs-5.1.8-simplify-cache_add-a-little.patch new file mode 100644 index 0000000..ac8fd22 --- /dev/null +++ b/autofs-5.1.8-simplify-cache_add-a-little.patch @@ -0,0 +1,48 @@ +autofs-5.1.8 - simplify cache_add() a little + +From: Ian Kent + +If a map entry is being added to an existing hash chain there's an +unneccessarily complicted setting of ->next of the last entry. + +Just initialize the map entry ->next field instead and remove the +confusing assignment. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/cache.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 4e5e82d0..5b37460f 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -9,6 +9,7 @@ + - fix loop under run in cache_get_offset_parent(). + - bailout on rpc systemerror. + - fix nfsv4 only mounts should not use rpcbind. ++- simplify cache_add() a little. + + 19/10/2021 autofs-5.1.8 + - add xdr_exports(). +diff --git a/lib/cache.c b/lib/cache.c +index 8aed28ea..4f908daf 100644 +--- a/lib/cache.c ++++ b/lib/cache.c +@@ -564,6 +564,7 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c + me->dev = (dev_t) -1; + me->ino = (ino_t) -1; + me->flags = 0; ++ me->next = NULL; + + /* + * We need to add to the end if values exist in order to +@@ -583,7 +584,6 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c + + existing = next; + } +- me->next = existing->next; + existing->next = me; + } + return CHE_OK; diff --git a/autofs.spec b/autofs.spec index 9487e55..1c4d414 100644 --- a/autofs.spec +++ b/autofs.spec @@ -12,10 +12,29 @@ Summary: A tool for automatically mounting and unmounting filesystems Name: autofs Version: 5.1.8 -Release: 3%{?dist} +Release: 4%{?dist} Epoch: 1 License: GPLv2+ Source: https://www.kernel.org/pub/linux/daemons/autofs/v5/autofs-%{version}.tar.gz +Patch1: autofs-5.1.8-fix-kernel-mount-status-notification.patch +Patch2: autofs-5.1.8-fix-fedfs-build-flags.patch +Patch3: autofs-5.1.8-fix-set-open-file-limit.patch +Patch4: autofs-5.1.8-improve-descriptor-open-error-reporting.patch +Patch5: autofs-5.1.8-fix-root-offset-error-handling.patch +Patch6: autofs-5.1.8-fix-fix-root-offset-error-handling.patch +Patch7: autofs-5.1.8-fix-nonstrict-fail-handling-of-last-offset-mount.patch +Patch8: autofs-5.1.8-dont-fail-on-duplicate-host-export-entry.patch +Patch9: autofs-5.1.8-fix-loop-under-run-in-cache_get_offset_parent.patch +Patch10: autofs-5.1.8-bailout-on-rpc-systemerror.patch +Patch11: autofs-5.1.8-fix-nfsv4-only-mounts-should-not-use-rpcbind.patch +Patch12: autofs-5.1.8-simplify-cache_add-a-little.patch +Patch13: autofs-5.1.8-fix-use-after-free-in-tree_mapent_delete_offset_tree.patch +Patch14: autofs-5.1.8-fix-memory-leak-in-xdr_exports.patch +Patch15: autofs-5.1.8-avoid-calling-pthread_getspecific-with-NULL-key_thread_attempt_id.patch +Patch16: autofs-5.1.8-fix-sysconf-return-handling.patch +Patch17: autofs-5.1.8-remove-nonstrict-parameter-from-tree_mapent_umount_offsets.patch +Patch18: autofs-5.1.8-fix-handling-of-incorrect-return-from-umount_ent.patch +Patch19: autofs-5.1.8-dont-use-initgroups-at-spawn.patch %if %{with_systemd} BuildRequires: systemd-units @@ -25,7 +44,7 @@ BuildRequires: gcc BuildRequires: autoconf, openldap-devel, bison, flex, libxml2-devel BuildRequires: cyrus-sasl-devel, openssl-devel module-init-tools util-linux BuildRequires: e2fsprogs libtirpc-devel libsss_autofs libnsl2-devel -BuildRequires: rpcgen pkgconfig krb5-devel +BuildRequires: pkgconfig krb5-devel BuildRequires: make Conflicts: cyrus-sasl-lib < 2.1.23-9 Requires: bash coreutils sed gawk grep module-init-tools /bin/ps @@ -80,6 +99,25 @@ echo %{version}-%{release} > .version %if %{with_fedfs} %define fedfs_configure_arg --enable-fedfs %endif +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 +%patch18 -p1 +%patch19 -p1 %build LDFLAGS=-Wl,-z,now @@ -188,6 +226,25 @@ fi %dir /etc/auto.master.d %changelog +* Fri May 06 2022 Ian Kent - 1:5.1.8-4 +- fix kernel mount status notification. +- fix set open file limit. +- improve descriptor open error reporting. +- fix root offset error handling. +- fix nonstrict fail handling of last offset mount. +- dont fail on duplicate offset entry tree add. +- fix loop under run in cache_get_offset_parent(). +- bailout on rpc systemerror. +- fix nfsv4 only mounts should not use rpcbind. +- simplify cache_add() a little. +- fix use after free in tree_mapent_delete_offset_tree(). +- fix memory leak in xdr_exports(). +- avoid calling pthread_getspecific() with NULL key_thread_attempt_id. +- fix sysconf(3) return handling. +- remove nonstrict parameter from tree_mapent_umount_offsets(). +- fix handling of incorrect return from umount_ent(). +- dont use initgroups() at spawn. + * Wed Jan 19 2022 Fedora Release Engineering - 1:5.1.8-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild