From 19b143ecbf679050ec5c1332d703b01bb50a4fd4 Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Jun 17 2020 01:48:14 +0000 Subject: - initialize struct addrinfo for getaddrinfo() calls. - fix quoted string length calc in expandsunent(). - fix double quoting of ampersand in auto.smb as well. - fix autofs mount options construction. --- diff --git a/autofs-5.1.6-fix-autofs-mount-options-construction.patch b/autofs-5.1.6-fix-autofs-mount-options-construction.patch new file mode 100644 index 0000000..a0c56e6 --- /dev/null +++ b/autofs-5.1.6-fix-autofs-mount-options-construction.patch @@ -0,0 +1,283 @@ +autofs-5.1.6 - fix autofs mount options construction + +From: Ian Kent + +There's an off by one length error in the autofs mount options +construction. + +Consolidate the options construction into make_options_string() and +use snprintf() to verify the options length calculation is correct. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 46 ++----------------------- + daemon/indirect.c | 23 +----------- + include/mounts.h | 3 +- + lib/mounts.c | 98 +++++++++++++++++++++++++++++++++++++++++++++-------- + 5 files changed, 92 insertions(+), 79 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 90f67336..2565b04d 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -10,6 +10,7 @@ xx/xx/2020 autofs-5.1.7 + - fix trailing dollar sun entry expansion. + - initialize struct addrinfo for getaddrinfo() calls. + - fix quoted string length calc in expandsunent(). ++- fix autofs mount options construction. + + 07/10/2019 autofs-5.1.6 + - support strictexpire mount option. +diff --git a/daemon/direct.c b/daemon/direct.c +index b82d6e95..c4948729 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -348,29 +348,10 @@ int do_mount_autofs_direct(struct autofs_point *ap, + } + + if (!mp->options) { +- mp->options = make_options_string(ap->path, ap->kpipefd, str_direct); ++ mp->options = make_options_string(ap->path, ++ ap->kpipefd, str_direct, ap->flags); + if (!mp->options) + return 0; +- +- if ((ap->flags & MOUNT_FLAG_STRICTEXPIRE) && +- ((get_kver_major() == 5 && get_kver_minor() > 3) || +- (get_kver_major() > 5))) { +- char *tmp = realloc(mp->options, strlen(mp->options) + 12); +- if (tmp) { +- strcat(tmp, ",strictexpire"); +- mp->options = tmp; +- } +- } +- +- if ((ap->flags & MOUNT_FLAG_IGNORE) && +- ((get_kver_major() == 5 && get_kver_minor() > 4) || +- (get_kver_major() > 5))) { +- char *tmp = realloc(mp->options, strlen(mp->options) + 7); +- if (tmp) { +- strcat(tmp, ",ignore"); +- mp->options = tmp; +- } +- } + } + + /* In case the directory doesn't exist, try to mkdir it */ +@@ -676,29 +657,10 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char * + } + + if (!mp->options) { +- mp->options = make_options_string(ap->path, ap->kpipefd, str_offset); ++ mp->options = make_options_string(ap->path, ++ ap->kpipefd, str_offset, ap->flags); + if (!mp->options) + return MOUNT_OFFSET_OK; +- +- if ((ap->flags & MOUNT_FLAG_STRICTEXPIRE) && +- ((get_kver_major() == 5 && get_kver_minor() > 3) || +- (get_kver_major() > 5))) { +- char *tmp = realloc(mp->options, strlen(mp->options) + 12); +- if (tmp) { +- strcat(tmp, ",strictexpire"); +- mp->options = tmp; +- } +- } +- +- if ((ap->flags & MOUNT_FLAG_IGNORE) && +- ((get_kver_major() == 5 && get_kver_minor() > 4) || +- (get_kver_major() > 5))) { +- char *tmp = realloc(mp->options, strlen(mp->options) + 7); +- if (tmp) { +- strcat(tmp, ",ignore"); +- mp->options = tmp; +- } +- } + } + + strcpy(mountpoint, root); +diff --git a/daemon/indirect.c b/daemon/indirect.c +index 32257323..43bcb346 100644 +--- a/daemon/indirect.c ++++ b/daemon/indirect.c +@@ -78,32 +78,13 @@ static int do_mount_autofs_indirect(struct autofs_point *ap, const char *root) + } + } + +- options = make_options_string(ap->path, ap->kpipefd, str_indirect); ++ options = make_options_string(ap->path, ++ ap->kpipefd, str_indirect, ap->flags); + if (!options) { + error(ap->logopt, "options string error"); + goto out_err; + } + +- if ((ap->flags & MOUNT_FLAG_STRICTEXPIRE) && +- ((get_kver_major() == 5 && get_kver_minor() > 3) || +- (get_kver_major() > 5))) { +- char *tmp = realloc(options, strlen(options) + 12); +- if (tmp) { +- strcat(tmp, ",strictexpire"); +- options = tmp; +- } +- } +- +- if ((ap->flags & MOUNT_FLAG_IGNORE) && +- ((get_kver_major() == 5 && get_kver_minor() > 4) || +- (get_kver_major() > 5))) { +- char *tmp = realloc(options, strlen(options) + 7); +- if (tmp) { +- strcat(tmp, ",ignore"); +- options = tmp; +- } +- } +- + /* In case the directory doesn't exist, try to mkdir it */ + if (mkdir_path(root, mp_mode) < 0) { + if (errno != EEXIST && errno != EROFS) { +diff --git a/include/mounts.h b/include/mounts.h +index 1214aed9..c8fddf00 100644 +--- a/include/mounts.h ++++ b/include/mounts.h +@@ -94,7 +94,8 @@ void free_amd_entry_list(struct list_head *entries); + unsigned int query_kproto_ver(void); + unsigned int get_kver_major(void); + unsigned int get_kver_minor(void); +-char *make_options_string(char *path, int kernel_pipefd, const char *extra); ++char *make_options_string(char *path, int pipefd, ++ const char *type, unsigned int flags); + char *make_mnt_name_string(char *path); + int ext_mount_add(struct list_head *, const char *, unsigned int); + int ext_mount_remove(struct list_head *, const char *); +diff --git a/lib/mounts.c b/lib/mounts.c +index 83d053c8..a2d1f149 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -599,43 +599,111 @@ void free_amd_entry_list(struct list_head *entries) + } + } + ++static int cacl_max_options_len(unsigned int flags) ++{ ++ unsigned int kver_major = get_kver_major(); ++ unsigned int kver_minor = get_kver_minor(); ++ int max_len; ++ ++ /* %d and %u are maximum lenght of 10 and mount type is maximum ++ * length of 9 (e. ",indirect"). ++ * The base temaplate is "fd=%d,pgrp=%u,minproto=5,maxproto=%d" ++ * plus the length of mount type plus 1 for the NULL. ++ */ ++ max_len = 79 + 1; ++ ++ if (kver_major < 5 || (kver_major == 5 && kver_minor < 4)) ++ goto out; ++ ++ /* maybe add ",strictexpire" */ ++ if (flags & MOUNT_FLAG_STRICTEXPIRE) ++ max_len += 13; ++ ++ if (kver_major == 5 && kver_minor < 5) ++ goto out; ++ ++ /* maybe add ",ignore" */ ++ if (flags & MOUNT_FLAG_IGNORE) ++ max_len += 7; ++out: ++ return max_len; ++} ++ + /* + * Make common autofs mount options string + */ +-char *make_options_string(char *path, int pipefd, const char *extra) ++char *make_options_string(char *path, int pipefd, ++ const char *type, unsigned int flags) + { ++ unsigned int kver_major = get_kver_major(); ++ unsigned int kver_minor = get_kver_minor(); + char *options; +- int len; ++ int max_len, len, new; ++ ++ max_len = cacl_max_options_len(flags); + +- options = malloc(MAX_OPTIONS_LEN + 1); ++ options = malloc(max_len); + if (!options) { + logerr("can't malloc options string"); + return NULL; + } + +- if (extra) +- len = snprintf(options, MAX_OPTIONS_LEN, ++ if (type) ++ len = snprintf(options, max_len, + options_template_extra, + pipefd, (unsigned) getpgrp(), +- AUTOFS_MAX_PROTO_VERSION, extra); ++ AUTOFS_MAX_PROTO_VERSION, type); + else +- len = snprintf(options, MAX_OPTIONS_LEN, options_template, ++ len = snprintf(options, max_len, options_template, + pipefd, (unsigned) getpgrp(), + AUTOFS_MAX_PROTO_VERSION); + +- if (len >= MAX_OPTIONS_LEN) { +- logerr("buffer to small for options - truncated"); +- len = MAX_OPTIONS_LEN - 1; ++ if (len < 0) ++ goto error_out; ++ ++ if (len >= max_len) ++ goto truncated; ++ ++ if (kver_major < 5 || (kver_major == 5 && kver_minor < 4)) ++ goto out; ++ ++ /* maybe add ",strictexpire" */ ++ if (flags & MOUNT_FLAG_STRICTEXPIRE) { ++ new = snprintf(options + len, ++ max_len, "%s", ",strictexpire"); ++ if (new < 0) ++ goto error_out; ++ len += new; ++ if (len >= max_len) ++ goto truncated; + } + +- if (len < 0) { +- logerr("failed to malloc autofs mount options for %s", path); +- free(options); +- return NULL; ++ if (kver_major == 5 && kver_minor < 5) ++ goto out; ++ ++ /* maybe add ",ignore" */ ++ if (flags & MOUNT_FLAG_IGNORE) { ++ new = snprintf(options + len, ++ max_len, "%s", ",ignore"); ++ if (new < 0) ++ goto error_out; ++ len += new; ++ if (len >= max_len) ++ goto truncated; + } ++out: + options[len] = '\0'; +- + return options; ++ ++truncated: ++ logerr("buffer to small for options - truncated"); ++ len = max_len -1; ++ goto out; ++ ++error_out: ++ logerr("error constructing mount options string for %s", path); ++ free(options); ++ return NULL; + } + + char *make_mnt_name_string(char *path) diff --git a/autofs-5.1.6-fix-double-quoting-of-ampersand-in-auto.smb-as-well.patch b/autofs-5.1.6-fix-double-quoting-of-ampersand-in-auto.smb-as-well.patch new file mode 100644 index 0000000..ce941ea --- /dev/null +++ b/autofs-5.1.6-fix-double-quoting-of-ampersand-in-auto.smb-as-well.patch @@ -0,0 +1,26 @@ +autofs-5.1.6 - fix double quoting of ampersand in auto.smb as well + +From: Ian Kent + +The example program mount script installed to /etc/auto.smb incorrectly +adds a quote for the & character that causes mount failures. But the +produced map entry is already surrounded by double quotes. This may have +been handled by mount.cifs at some point but it's failing now. + +Signed-off-by: Ian Kent +--- + samples/auto.smb | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/samples/auto.smb b/samples/auto.smb +index 4842b689..f6d41d35 100755 +--- a/samples/auto.smb ++++ b/samples/auto.smb +@@ -75,7 +75,6 @@ $SMBCLIENT $smbopts -gL "$key" 2>/dev/null| awk -v "key=$key" -v "opts=$opts" -F + dir = $2 + loc = $2 + # Enclose mount dir and location in quotes +- gsub(/\&/,"\\\\&",loc) + print " \\\n\t \"/" dir "\"", "\"://" key "/" loc "\"" + } + END { if (!first) print "\n"; else exit 1 } diff --git a/autofs-5.1.6-fix-quoted-string-length-calc-in-expandsunent.patch b/autofs-5.1.6-fix-quoted-string-length-calc-in-expandsunent.patch new file mode 100644 index 0000000..3025201 --- /dev/null +++ b/autofs-5.1.6-fix-quoted-string-length-calc-in-expandsunent.patch @@ -0,0 +1,48 @@ +autofs-5.1.6 - fix quoted string length calc in expandsunent() + +From: Ian Kent + +The expandsunent() function in modules/parse_sun.c fails to properly +handle the ending " in a quoted string causing the length calculation +to not account for the ending quote and also doesn't properly account +for the remainder of the string being expanded. + +Also, when called again (after being called to get the length) the +allocated buffer is too small leading to out of bounds accesses. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 6 ++++-- + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 2c500a48..90f67336 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -9,6 +9,7 @@ xx/xx/2020 autofs-5.1.7 + - remove intr hosts map mount option. + - fix trailing dollar sun entry expansion. + - initialize struct addrinfo for getaddrinfo() calls. ++- fix quoted string length calc in expandsunent(). + + 07/10/2019 autofs-5.1.6 + - support strictexpire mount option. +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index f6c22d15..80fdf476 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -213,9 +213,11 @@ int expandsunent(const char *src, char *dst, const char *key, + *dst++ = *src; + src++; + } +- if (*src && dst) { ++ if (*src) { + len++; +- *dst++ = *src++; ++ if (dst) ++ *dst++ = *src; ++ src++; + } + break; + diff --git a/autofs-5.1.6-initialize-struct-addrinfo-for-getaddrinfo-calls.patch b/autofs-5.1.6-initialize-struct-addrinfo-for-getaddrinfo-calls.patch new file mode 100644 index 0000000..7ae9cab --- /dev/null +++ b/autofs-5.1.6-initialize-struct-addrinfo-for-getaddrinfo-calls.patch @@ -0,0 +1,116 @@ +autofs-5.1.6 - initialize struct addrinfo for getaddrinfo() calls + +From: Ian Kent + +The getaddrinfo() call may have become more fussy about initialization +of the passed in struct addrinfo that receives the results. + +It's good practice to initialize it prior to the gataddrinfo() call just +in case. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/parse_subs.c | 1 + + lib/rpc_subs.c | 1 + + modules/dclist.c | 1 + + modules/parse_amd.c | 3 +++ + modules/replicated.c | 2 ++ + 6 files changed, 9 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 07a85cde..2c500a48 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -8,6 +8,7 @@ xx/xx/2020 autofs-5.1.7 + - samples: fix Makefile targets' directory dependencies + - remove intr hosts map mount option. + - fix trailing dollar sun entry expansion. ++- initialize struct addrinfo for getaddrinfo() calls. + + 07/10/2019 autofs-5.1.6 + - support strictexpire mount option. +diff --git a/lib/parse_subs.c b/lib/parse_subs.c +index cdda2e1a..0ee00d51 100644 +--- a/lib/parse_subs.c ++++ b/lib/parse_subs.c +@@ -475,6 +475,7 @@ unsigned int get_network_proximity(const char *name) + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG | AI_CANONNAME; + ++ ni = NULL; + ret = getaddrinfo(name_or_num, NULL, &hints, &ni); + if (ret) { + logerr("hostname lookup for %s failed: %s", +diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c +index 8b23627a..643b7687 100644 +--- a/lib/rpc_subs.c ++++ b/lib/rpc_subs.c +@@ -691,6 +691,7 @@ static int create_client(struct conn_info *info, CLIENT **client) + else + hints.ai_socktype = SOCK_STREAM; + ++ ai = NULL; + ret = getaddrinfo(info->host, NULL, &hints, &ai); + if (ret) { + error(LOGOPT_ANY, +diff --git a/modules/dclist.c b/modules/dclist.c +index ba32134d..c34c3a91 100644 +--- a/modules/dclist.c ++++ b/modules/dclist.c +@@ -355,6 +355,7 @@ static char *getdnsdomainname(unsigned int logopt) + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + ++ ni = NULL; + ret = getaddrinfo(name, NULL, &hints, &ni); + if (ret) { + error(logopt, +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index d8b9ea24..943a48b6 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -269,6 +269,7 @@ static int match_my_name(struct autofs_point *ap, const char *name, struct subst + hints.ai_socktype = SOCK_DGRAM; + + /* Get host canonical name */ ++ cni = NULL; + ret = getaddrinfo(v->val, NULL, &hints, &cni); + if (ret) { + error(logopt, MODPREFIX +@@ -280,6 +281,7 @@ static int match_my_name(struct autofs_point *ap, const char *name, struct subst + hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG | AI_CANONNAME; + + /* Resolve comparison name to its names and compare */ ++ ni = NULL; + ret = getaddrinfo(exp_name, NULL, &hints, &ni); + if (ret) { + error(logopt, MODPREFIX +@@ -775,6 +777,7 @@ static char *normalize_hostname(unsigned int logopt, const char *host, + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + ++ ni = NULL; + ret = getaddrinfo(host, NULL, &hints, &ni); + if (ret) { + error(logopt, MODPREFIX +diff --git a/modules/replicated.c b/modules/replicated.c +index 91fce882..03d4ba1e 100644 +--- a/modules/replicated.c ++++ b/modules/replicated.c +@@ -982,6 +982,7 @@ static int add_host_addrs(struct host **list, const char *host, int ent_num, + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + ++ ni = NULL; + ret = getaddrinfo(name, NULL, &hints, &ni); + if (ret) + goto try_name; +@@ -1002,6 +1003,7 @@ try_name: + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + ++ ni = NULL; + ret = getaddrinfo(name, NULL, &hints, &ni); + if (ret) { + error(LOGOPT_ANY, diff --git a/autofs.spec b/autofs.spec index 0cc94d3..588f667 100644 --- a/autofs.spec +++ b/autofs.spec @@ -8,7 +8,7 @@ Summary: A tool for automatically mounting and unmounting filesystems Name: autofs Version: 5.1.6 -Release: 6%{?dist} +Release: 7%{?dist} Epoch: 1 License: GPLv2+ Source: https://www.kernel.org/pub/linux/daemons/autofs/v5/autofs-%{version}.tar.gz @@ -22,6 +22,10 @@ Patch007: autofs-samples-fix-Makefile-targets-directory-dependencies.patch Patch008: autofs-5.1.6-remove-intr-hosts-map-mount-option.patch Patch009: autofs-5.1.6-fix-trailing-dollar-sun-entry-expansion.patch Patch010: autofs-5.1.6-fix-double-quoting-in-auto.smb.patch +Patch011: autofs-5.1.6-initialize-struct-addrinfo-for-getaddrinfo-calls.patch +Patch012: autofs-5.1.6-fix-quoted-string-length-calc-in-expandsunent.patch +Patch013: autofs-5.1.6-fix-double-quoting-of-ampersand-in-auto.smb-as-well.patch +Patch014: autofs-5.1.6-fix-autofs-mount-options-construction.patch %if %{with_systemd} BuildRequires: systemd-units @@ -92,6 +96,10 @@ echo %{version}-%{release} > .version %patch008 -p1 %patch009 -p1 %patch010 -p1 +%patch011 -p1 +%patch012 -p1 +%patch013 -p1 +%patch014 -p1 %build LDFLAGS=-Wl,-z,now @@ -191,6 +199,12 @@ fi %dir /etc/auto.master.d %changelog +* Wed Jun 17 2020 Ian Kent - 1:5.1.6-7 +- initialize struct addrinfo for getaddrinfo() calls. +- fix quoted string length calc in expandsunent(). +- fix double quoting of ampersand in auto.smb as well. +- fix autofs mount options construction. + * Mon Jun 01 2020 Ian Kent - 1:5.1.6-4 - fix changelog message. - actually commit the patches referred to in the commit.