From 3462367b2e36176f26a8ae8a834105427217f44d Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Sep 12 2012 01:36:32 +0000 Subject: - add several upstream bug fix patches. --- diff --git a/autofs-5.0.7-fix-ipv6-proximity-calculation.patch b/autofs-5.0.7-fix-ipv6-proximity-calculation.patch new file mode 100644 index 0000000..b341ecd --- /dev/null +++ b/autofs-5.0.7-fix-ipv6-proximity-calculation.patch @@ -0,0 +1,297 @@ +autofs-5.0.7 - fix ipv6 proximity calculation + +From: Ian Kent + +The socket based ioctl used to get interface information only +return IPv4 information. Change get_proximity() function to use +getifaddrs(3) instead. +--- + + CHANGELOG | 1 + modules/replicated.c | 149 ++++++++++++++------------------------------------ + 2 files changed, 42 insertions(+), 108 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index dc38580..34c70fa 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -2,6 +2,7 @@ + ======================= + - fix nobind sun escaped map entries. + - fix use cache entry after free in lookup_prune_one_cache(). ++- fix ipv6 proximity calculation. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/modules/replicated.c b/modules/replicated.c +index 78046c6..bd6003b 100644 +--- a/modules/replicated.c ++++ b/modules/replicated.c +@@ -52,6 +52,7 @@ + #include + #include + #include ++#include + + #include "rpc_subs.h" + #include "replicated.h" +@@ -110,58 +111,18 @@ void seed_random(void) + return; + } + +-static int alloc_ifreq(struct ifconf *ifc, int sock) +-{ +- int ret, lastlen = ifc_last_len, len = ifc_buf_len; +- char err_buf[MAX_ERR_BUF], *buf; +- +- while (1) { +- buf = malloc(len); +- if (!buf) { +- char *estr = strerror_r(errno, err_buf, MAX_ERR_BUF); +- logerr("malloc: %s", estr); +- return 0; +- } +- +- ifc->ifc_len = len; +- ifc->ifc_req = (struct ifreq *) buf; +- +- ret = ioctl(sock, SIOCGIFCONF, ifc); +- if (ret == -1) { +- char *estr = strerror_r(errno, err_buf, MAX_ERR_BUF); +- logerr("ioctl: %s", estr); +- free(buf); +- return 0; +- } +- +- if (ifc->ifc_len <= lastlen) +- break; +- +- lastlen = ifc->ifc_len; +- len += MAX_IFC_BUF; +- free(buf); +- } +- +- if (lastlen != ifc_last_len) { +- ifc_last_len = lastlen; +- ifc_buf_len = len; +- } +- +- return 1; +-} +- + static unsigned int get_proximity(struct sockaddr *host_addr) + { ++ struct ifaddrs *ifa = NULL; ++ struct ifaddrs *this; + struct sockaddr_in *addr, *msk_addr, *if_addr; + struct sockaddr_in6 *addr6, *msk6_addr, *if6_addr; + struct in_addr *hst_addr; + struct in6_addr *hst6_addr; + int addr_len; +- char buf[MAX_ERR_BUF], *ptr; +- struct ifconf ifc; +- struct ifreq *ifr, nmptr; +- int sock, ret, i; ++ char buf[MAX_ERR_BUF]; + uint32_t mask, ha, ia, *mask6, *ha6, *ia6; ++ int ret; + + addr = NULL; + addr6 = NULL; +@@ -170,13 +131,14 @@ static unsigned int get_proximity(struct sockaddr *host_addr) + mask6 = NULL; + ha6 = NULL; + ia6 = NULL; ++ ha = 0; + + switch (host_addr->sa_family) { + case AF_INET: + addr = (struct sockaddr_in *) host_addr; + hst_addr = (struct in_addr *) &addr->sin_addr; + ha = ntohl((uint32_t) hst_addr->s_addr); +- addr_len = sizeof(hst_addr); ++ addr_len = sizeof(*hst_addr); + break; + + case AF_INET6: +@@ -186,7 +148,7 @@ static unsigned int get_proximity(struct sockaddr *host_addr) + addr6 = (struct sockaddr_in6 *) host_addr; + hst6_addr = (struct in6_addr *) &addr6->sin6_addr; + ha6 = &hst6_addr->s6_addr32[0]; +- addr_len = sizeof(hst6_addr); ++ addr_len = sizeof(*hst6_addr); + break; + #endif + +@@ -194,36 +156,29 @@ static unsigned int get_proximity(struct sockaddr *host_addr) + return PROXIMITY_ERROR; + } + +- sock = open_sock(AF_INET, SOCK_DGRAM, 0); +- if (sock < 0) { ++ ret = getifaddrs(&ifa); ++ if (ret) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr("socket creation failed: %s", estr); ++ logerr("getifaddrs: %s", estr); + return PROXIMITY_ERROR; + } + +- if (!alloc_ifreq(&ifc, sock)) { +- close(sock); +- return PROXIMITY_ERROR; +- } +- +- /* For each interface */ +- +- /* Is the address a local interface */ +- i = 0; +- ptr = (char *) &ifc.ifc_buf[0]; +- +- while (ptr < (char *) ifc.ifc_req + ifc.ifc_len) { +- ifr = (struct ifreq *) ptr; ++ this = ifa; ++ while (this) { ++ if (this->ifa_flags & IFF_POINTOPOINT || ++ this->ifa_addr->sa_data == NULL) { ++ this = this->ifa_next; ++ continue; ++ } + +- switch (ifr->ifr_addr.sa_family) { ++ switch (this->ifa_addr->sa_family) { + case AF_INET: + if (host_addr->sa_family == AF_INET6) + break; +- if_addr = (struct sockaddr_in *) &ifr->ifr_addr; ++ if_addr = (struct sockaddr_in *) this->ifa_addr; + ret = memcmp(&if_addr->sin_addr, hst_addr, addr_len); + if (!ret) { +- close(sock); +- free(ifc.ifc_req); ++ freeifaddrs(ifa); + return PROXIMITY_LOCAL; + } + break; +@@ -234,55 +189,41 @@ static unsigned int get_proximity(struct sockaddr *host_addr) + #else + if (host_addr->sa_family == AF_INET) + break; +- +- if6_addr = (struct sockaddr_in6 *) &ifr->ifr_addr; ++ if6_addr = (struct sockaddr_in6 *) this->ifa_addr; + ret = memcmp(&if6_addr->sin6_addr, hst6_addr, addr_len); + if (!ret) { +- close(sock); +- free(ifc.ifc_req); ++ freeifaddrs(ifa); + return PROXIMITY_LOCAL; + } + #endif +- + default: + break; + } +- +- i++; +- ptr = (char *) &ifc.ifc_req[i]; ++ this = this->ifa_next; + } + +- i = 0; +- ptr = (char *) &ifc.ifc_buf[0]; +- +- while (ptr < (char *) ifc.ifc_req + ifc.ifc_len) { +- ifr = (struct ifreq *) ptr; +- +- nmptr = *ifr; +- ret = ioctl(sock, SIOCGIFNETMASK, &nmptr); +- if (ret == -1) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr("ioctl: %s", estr); +- close(sock); +- free(ifc.ifc_req); +- return PROXIMITY_ERROR; ++ this = ifa; ++ while (this) { ++ if (this->ifa_flags & IFF_POINTOPOINT || ++ this->ifa_addr->sa_data == NULL) { ++ this = this->ifa_next; ++ continue; + } + +- switch (ifr->ifr_addr.sa_family) { ++ switch (this->ifa_addr->sa_family) { + case AF_INET: + if (host_addr->sa_family == AF_INET6) + break; +- if_addr = (struct sockaddr_in *) &ifr->ifr_addr; ++ if_addr = (struct sockaddr_in *) this->ifa_addr; + ia = ntohl((uint32_t) if_addr->sin_addr.s_addr); + +- /* Is the address within a localiy attached subnet */ ++ /* Is the address within a localy attached subnet */ + +- msk_addr = (struct sockaddr_in *) &nmptr.ifr_netmask; ++ msk_addr = (struct sockaddr_in *) this->ifa_netmask; + mask = ntohl((uint32_t) msk_addr->sin_addr.s_addr); + + if ((ia & mask) == (ha & mask)) { +- close(sock); +- free(ifc.ifc_req); ++ freeifaddrs(ifa); + return PROXIMITY_SUBNET; + } + +@@ -304,8 +245,7 @@ static unsigned int get_proximity(struct sockaddr *host_addr) + break; + + if ((ia & mask) == (ha & mask)) { +- close(sock); +- free(ifc.ifc_req); ++ freeifaddrs(ifa); + return PROXIMITY_NET; + } + break; +@@ -316,35 +256,28 @@ static unsigned int get_proximity(struct sockaddr *host_addr) + #else + if (host_addr->sa_family == AF_INET) + break; +- +- if6_addr = (struct sockaddr_in6 *) &ifr->ifr_addr; ++ if6_addr = (struct sockaddr_in6 *) this->ifa_addr; + ia6 = &if6_addr->sin6_addr.s6_addr32[0]; + + /* Is the address within the network of the interface */ + +- msk6_addr = (struct sockaddr_in6 *) &nmptr.ifr_netmask; ++ msk6_addr = (struct sockaddr_in6 *) this->ifa_netmask; + mask6 = &msk6_addr->sin6_addr.s6_addr32[0]; + + if (ipv6_mask_cmp(ha6, ia6, mask6)) { +- close(sock); +- free(ifc.ifc_req); ++ freeifaddrs(ifa); + return PROXIMITY_SUBNET; + } + + /* How do we define "local network" in ipv6? */ + #endif +- break; +- + default: + break; + } +- +- i++; +- ptr = (char *) &ifc.ifc_req[i]; ++ this = this->ifa_next; + } + +- close(sock); +- free(ifc.ifc_req); ++ freeifaddrs(ifa); + + return PROXIMITY_OTHER; + } diff --git a/autofs-5.0.7-fix-nobind-sun-escaped-map-entries.patch b/autofs-5.0.7-fix-nobind-sun-escaped-map-entries.patch new file mode 100644 index 0000000..b5d7ad2 --- /dev/null +++ b/autofs-5.0.7-fix-nobind-sun-escaped-map-entries.patch @@ -0,0 +1,47 @@ +autofs-5.0.7 - fix nobind sun escaped map entries + +From: Ian Kent + +If a map contains a Sun colon escape to indicate the mount is a local +file system and the "nobind" option is present there is no hostname in +the mount location and the mount fails. +--- + + CHANGELOG | 4 ++++ + modules/mount_nfs.c | 5 +++-- + 2 files changed, 7 insertions(+), 2 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 67fdcec..faf4c80 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -1,3 +1,7 @@ ++??/??/2012 autofs-5.0.8 ++======================= ++- fix nobind sun escaped map entries. ++ + 25/07/2012 autofs-5.0.7 + ======================= + - fix ipv6 name for lookup fix. +diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c +index 9b8e5f1..bbbb1de 100644 +--- a/modules/mount_nfs.c ++++ b/modules/mount_nfs.c +@@ -263,13 +263,14 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + } else + strcpy(loc, n_addr); + } else { +- loc = malloc(strlen(this->name) + strlen(this->path) + 2); ++ char *host = this->name ? this->name : "localhost"; ++ loc = malloc(strlen(host) + strlen(this->path) + 2); + if (!loc) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + error(ap->logopt, "malloc: %s", estr); + goto forced_fail; + } +- strcpy(loc, this->name); ++ strcpy(loc, host); + } + strcat(loc, ":"); + strcat(loc, this->path); diff --git a/autofs-5.0.7-fix-parse-buffer-initialization.patch b/autofs-5.0.7-fix-parse-buffer-initialization.patch new file mode 100644 index 0000000..22bd5da --- /dev/null +++ b/autofs-5.0.7-fix-parse-buffer-initialization.patch @@ -0,0 +1,51 @@ +autofs-5.0.7 - fix parse buffer initialization + +From: Ian Kent + +When parsing a master map entry, if the mount point path is longer than +the following map string the lexical analyzer buffer may not have a null +terminator where it is expected. If the map name string also contains a +string that is the same as a map type at the end the map name the map +name is not constructed correctly because of this lack of a string +terminator in the buffer. +--- + + CHANGELOG | 1 + + lib/master_tok.l | 4 +++- + 2 files changed, 4 insertions(+), 1 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 34c70fa..276d6ba 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -3,6 +3,7 @@ + - fix nobind sun escaped map entries. + - fix use cache entry after free in lookup_prune_one_cache(). + - fix ipv6 proximity calculation. ++- fix parse buffer initialization. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/lib/master_tok.l b/lib/master_tok.l +index 0d6edb7..30abb15 100644 +--- a/lib/master_tok.l ++++ b/lib/master_tok.l +@@ -74,7 +74,8 @@ int my_yyinput(char *, int); + #define unput(c) (*(char *) --line = c) + #endif + +-char buff[1024]; ++#define BUFF_LEN 1024 ++char buff[BUFF_LEN]; + char *bptr; + char *optr = buff; + unsigned int tlen; +@@ -174,6 +175,7 @@ OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|--negative-timeout{OPTWS}|--negative-timeo + *bptr = '\0'; + strcpy(master_lval.strtype, buff); + bptr = buff; ++ memset(buff, 0, BUFF_LEN); + return(PATH); + } + diff --git a/autofs-5.0.7-fix-typo-in-automount-8.patch b/autofs-5.0.7-fix-typo-in-automount-8.patch new file mode 100644 index 0000000..0dd7c2b --- /dev/null +++ b/autofs-5.0.7-fix-typo-in-automount-8.patch @@ -0,0 +1,33 @@ +autofs-5.0.7 - fix typo in automount(8) + +From: Ian Kent + + +--- + + CHANGELOG | 1 + + man/automount.8 | 2 +- + 2 files changed, 2 insertions(+), 1 deletions(-) + + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -4,6 +4,7 @@ + - fix use cache entry after free in lookup_prune_one_cache(). + - fix ipv6 proximity calculation. + - fix parse buffer initialization. ++- fix typo in automount(8). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/man/automount.8 ++++ autofs-5.0.7/man/automount.8 +@@ -51,7 +51,7 @@ are over-ridden macro definitions of the + mount entries. + .TP + .I "\-f, \-\-foreground" +-Run the daemon in the forground and log to stderr instead of syslog." ++Run the daemon in the foreground and log to stderr instead of syslog." + .TP + .I "\-r, \-\-random-multimount-selection" + Enables the use of ramdom selection when choosing a host from a diff --git a/autofs-5.0.7-fix-use-cache-entry-after-free-mistake.patch b/autofs-5.0.7-fix-use-cache-entry-after-free-mistake.patch new file mode 100644 index 0000000..a469c16 --- /dev/null +++ b/autofs-5.0.7-fix-use-cache-entry-after-free-mistake.patch @@ -0,0 +1,49 @@ +autofs-5.0.7 - fix use cache entry after free mistake + +From: Ian Kent + +Fix an obvious use after free mistake in lookup_prune_one_cache(). +--- + + CHANGELOG | 1 + + daemon/lookup.c | 7 +++++-- + 2 files changed, 6 insertions(+), 2 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index faf4c80..dc38580 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -1,6 +1,7 @@ + ??/??/2012 autofs-5.0.8 + ======================= + - fix nobind sun escaped map entries. ++- fix use cache entry after free in lookup_prune_one_cache(). + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/daemon/lookup.c b/daemon/lookup.c +index 7909536..e3d9536 100644 +--- a/daemon/lookup.c ++++ b/daemon/lookup.c +@@ -1103,15 +1103,18 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti + if (valid) + cache_delete(mc, key); + else if (!is_mounted(_PROC_MOUNTS, path, MNTS_AUTOFS)) { ++ dev_t devid = ap->dev; + status = CHE_FAIL; ++ if (ap->type == LKP_DIRECT) ++ devid = this->dev; + if (this->ioctlfd == -1) + status = cache_delete(mc, key); + if (status != CHE_FAIL) { + if (ap->type == LKP_INDIRECT) { + if (ap->flags & MOUNT_FLAG_GHOST) +- rmdir_path(ap, path, ap->dev); ++ rmdir_path(ap, path, devid); + } else +- rmdir_path(ap, path, this->dev); ++ rmdir_path(ap, path, devid); + } + } + cache_unlock(mc); diff --git a/autofs.spec b/autofs.spec index 0c603bc..84d3b6c 100644 --- a/autofs.spec +++ b/autofs.spec @@ -8,11 +8,16 @@ Summary: A tool for automatically mounting and unmounting filesystems Name: autofs Version: 5.0.7 -Release: 2%{?dist} +Release: 3%{?dist} Epoch: 1 License: GPLv2+ Group: System Environment/Daemons Source: ftp://ftp.kernel.org/pub/linux/daemons/autofs/v5/autofs-%{version}.tar.bz2 +Patch1: autofs-5.0.7-fix-nobind-sun-escaped-map-entries.patch +Patch2: autofs-5.0.7-fix-use-cache-entry-after-free-mistake.patch +Patch3: autofs-5.0.7-fix-ipv6-proximity-calculation.patch +Patch4: autofs-5.0.7-fix-parse-buffer-initialization.patch +Patch5: autofs-5.0.7-fix-typo-in-automount-8.patch Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) %if %{with_systemd} BuildRequires: systemd-units @@ -69,6 +74,11 @@ echo %{version}-%{release} > .version %define _unitdir %{?_unitdir:/lib/systemd/system} %define systemd_configure_arg --with-systemd %endif +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 %build #CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr --libdir=%{_libdir} @@ -160,6 +170,13 @@ fi %dir /etc/auto.master.d %changelog +* Mon Sep 12 2012 Ian Kent - 1:5.0.7-3 +- fix nobind sun escaped map entries. +- fix use cache entry after free mistake. +- fix ipv6 proximity calculation. +- fix parse buffer initialization. +- fix typo in automount(8). + * Mon Aug 27 2012 Ian Kent - 1:5.0.7-2 - update systemd scriplet macros (bz850040).