- 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.
This commit is contained in:
Ian Kent 2020-06-17 09:48:14 +08:00
parent 5674919ce2
commit 19b143ecbf
5 changed files with 488 additions and 1 deletions

View File

@ -0,0 +1,283 @@
autofs-5.1.6 - fix autofs mount options construction
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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)

View File

@ -0,0 +1,26 @@
autofs-5.1.6 - fix double quoting of ampersand in auto.smb as well
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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 }

View File

@ -0,0 +1,48 @@
autofs-5.1.6 - fix quoted string length calc in expandsunent()
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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;

View File

@ -0,0 +1,116 @@
autofs-5.1.6 - initialize struct addrinfo for getaddrinfo() calls
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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,

View File

@ -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 <ikent@redhat.com> - 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 <ikent@redhat.com> - 1:5.1.6-4
- fix changelog message.
- actually commit the patches referred to in the commit.