Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:Update
glibc.33856
getaddrinfo-parse-ipv4-address.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File getaddrinfo-parse-ipv4-address.patch of Package glibc.33856
2019-02-04 Florian Weimer <fweimer@redhat.com> [BZ #20018] nscd: Do not rely on new GLIBC_PRIVATE ABI after CVE-2016-10739 fix. * nscd/nscd-inet_addr.c: New file. Build resolv/inet_addr.c for nscd, without public symbols. * nscd/Makefile (nscd-modules): Add it. * nscd/gai.c: Include <arpa/inet.h> and change visibility of __inet_aton_exact. 2019-01-21 Florian Weimer <fweimer@redhat.com> [BZ #20018] CVE-2016-10739 resolv: Reject trailing characters in host names * include/arpa/inet.h (__inet_aton_exact): Declare. (inet_aton): Remove hidden prototype. No longer used internally. * nscd/gai.c (__inet_aton): Do not define. * nscd/gethstbynm3_r.c (__inet_aton): Likewise. * nss/digits_dots.c (__inet_aton): Likewise. (__nss_hostname_digits_dots_context): Call __inet_aton_exact. * resolv/Versions (GLIBC_PRIVATE): Export __inet_aton_exact from libc. * resolv/inet_addr.c (inet_aton_end): Remame from __inet_aton. Make static. Add endp parameter. (__inet_aton_exact): New function. (__inet_aton_ignore_trailing): New function, aliased to inet_aton. (__inet_addr): Call inet_aton_end. * resolv/res_init.c (res_vinit_1): Truncate nameserver for IPv4, not just IPv6. Call __inet_aton_exact. * sysdeps/posix/getaddrinfo.c (gaih_inet): Call __inet_aton_exact. 2019-01-18 Florian Weimer <fweimer@redhat.com> [BZ #24112] resolv: Do not send queries for non-host-names in nss_dns. * resolv/nss_dns/dns-host.c (check_name): New function. (_nss_dns_gethostbyname2_r): Use it. (_nss_dns_gethostbyname_r): Likewise. (_nss_dns_gethostbyname4_r): Likewise. Index: glibc-2.22/include/arpa/inet.h =================================================================== --- glibc-2.22.orig/include/arpa/inet.h +++ glibc-2.22/include/arpa/inet.h @@ -1,10 +1,10 @@ #include <inet/arpa/inet.h> #ifndef _ISOMAC -extern int __inet_aton (const char *__cp, struct in_addr *__inp); -libc_hidden_proto (__inet_aton) +/* Variant of inet_aton which rejects trailing garbage. */ +extern int __inet_aton_exact (const char *__cp, struct in_addr *__inp); +libc_hidden_proto (__inet_aton_exact) -libc_hidden_proto (inet_aton) libc_hidden_proto (inet_ntop) libc_hidden_proto (inet_pton) extern __typeof (inet_pton) __inet_pton; Index: glibc-2.22/nscd/Makefile =================================================================== --- glibc-2.22.orig/nscd/Makefile +++ glibc-2.22/nscd/Makefile @@ -36,7 +36,7 @@ nscd-modules := nscd connections pwdcach getsrvbynm_r getsrvbypt_r servicescache \ dbg_log nscd_conf nscd_stat cache mem nscd_setup_thread \ xmalloc xstrdup aicache initgrcache gai res_hconf \ - netgroupcache + netgroupcache nscd-inet_addr ifeq ($(build-nscd)$(have-thread-library),yesyes) Index: glibc-2.22/nscd/gai.c =================================================================== --- glibc-2.22.orig/nscd/gai.c +++ glibc-2.22/nscd/gai.c @@ -19,7 +19,6 @@ /* This file uses the getaddrinfo code but it compiles it without NSCD support. We just need a few symbol renames. */ -#define __inet_aton inet_aton #define __ioctl ioctl #define __getsockname getsockname #define __socket socket @@ -32,6 +31,12 @@ /* nscd uses 1MB or 2MB thread stacks. */ #define __libc_use_alloca(size) (size <= __MAX_ALLOCA_CUTOFF) +/* We do not want to export __inet_aton_exact. Get the prototype and + change its visibility to hidden. */ +#include <arpa/inet.h> +__typeof__ (__inet_aton_exact) __inet_aton_exact + __attribute__ ((visibility ("hidden"))); + /* We are nscd, so we don't want to be talking to ourselves. */ #undef USE_NSCD Index: glibc-2.22/nscd/gethstbynm3_r.c =================================================================== --- glibc-2.22.orig/nscd/gethstbynm3_r.c +++ glibc-2.22/nscd/gethstbynm3_r.c @@ -38,8 +38,6 @@ #define HAVE_LOOKUP_BUFFER 1 #define HAVE_AF 1 -#define __inet_aton inet_aton - /* We are nscd, so we don't want to be talking to ourselves. */ #undef USE_NSCD Index: glibc-2.22/nscd/nscd-inet_addr.c =================================================================== --- /dev/null +++ glibc-2.22/nscd/nscd-inet_addr.c @@ -0,0 +1,32 @@ +/* Legacy IPv4 text-to-address functions. Version for nscd. + Copyright (C) 2019 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <arpa/inet.h> + +/* We do not want to export __inet_aton_exact. Get the prototype and + change the visibility to hidden. */ +#include <arpa/inet.h> +__typeof__ (__inet_aton_exact) __inet_aton_exact + __attribute__ ((visibility ("hidden"))); + +/* Do not provide definitions of the public symbols exported from + libc. */ +#undef weak_alias +#define weak_alias(from, to) + +#include <resolv/inet_addr.c> Index: glibc-2.22/nss/digits_dots.c =================================================================== --- glibc-2.22.orig/nss/digits_dots.c +++ glibc-2.22/nss/digits_dots.c @@ -28,7 +28,6 @@ #include "nsswitch.h" #ifdef USE_NSCD -# define inet_aton __inet_aton # include <nscd/nscd_proto.h> #endif @@ -145,7 +144,7 @@ __nss_hostname_digits_dots (const char * 255.255.255.255? The test below will succeed spuriously... ??? */ if (af == AF_INET) - ok = __inet_aton (name, (struct in_addr *) host_addr); + ok = __inet_aton_exact (name, (struct in_addr *) host_addr); else { assert (af == AF_INET6); Index: glibc-2.22/resolv/Versions =================================================================== --- glibc-2.22.orig/resolv/Versions +++ glibc-2.22/resolv/Versions @@ -27,6 +27,7 @@ libc { __h_errno; __resp; __res_maybe_init; __res_iclose; + __inet_aton_exact; } } Index: glibc-2.22/resolv/inet_addr.c =================================================================== --- glibc-2.22.orig/resolv/inet_addr.c +++ glibc-2.22/resolv/inet_addr.c @@ -86,28 +86,15 @@ static const char rcsid[] = "$BINDId: in #endif /* - * Ascii internet address interpretation routine. - * The value returned is in network order. - */ -in_addr_t -__inet_addr(const char *cp) { - struct in_addr val; - - if (__inet_aton(cp, &val)) - return (val.s_addr); - return (INADDR_NONE); -} -weak_alias (__inet_addr, inet_addr) - -/* * Check whether "cp" is a valid ascii representation * of an Internet address and convert to a binary address. * Returns 1 if the address is valid, 0 if not. * This replaces inet_addr, the return value from which * cannot distinguish between failure and a local broadcast address. + * Write a pointer to the first non-converted character to *endp. */ -int -__inet_aton(const char *cp, struct in_addr *addr) +static int +inet_aton_end(const char *cp, struct in_addr *addr, const char **endp) { static const in_addr_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff }; in_addr_t val; @@ -210,6 +197,7 @@ __inet_aton(const char *cp, struct in_ad if (addr != NULL) addr->s_addr = res.word | htonl (val); + *endp = cp; #ifdef _LIBC __set_errno (saved_errno); @@ -222,6 +210,41 @@ ret_0: #endif return (0); } -weak_alias (__inet_aton, inet_aton) -libc_hidden_def (__inet_aton) -libc_hidden_weak (inet_aton) + +int +__inet_aton_exact (const char *cp, struct in_addr *addr) +{ + struct in_addr val; + const char *endp; + /* Check that inet_aton_end parsed the entire string. */ + if (inet_aton_end (cp, &val, &endp) != 0 && *endp == 0) + { + *addr = val; + return 1; + } + else + return 0; +} +libc_hidden_def (__inet_aton_exact) + +/* inet_aton ignores trailing garbage. */ +int +__inet_aton_ignore_trailing (const char *cp, struct in_addr *addr) +{ + const char *endp; + return inet_aton_end (cp, addr, &endp); +} +weak_alias (__inet_aton_ignore_trailing, inet_aton) + +/* ASCII IPv4 Internet address interpretation routine. The value + returned is in network order. */ +in_addr_t +__inet_addr (const char *cp) +{ + struct in_addr val; + const char *endp; + if (inet_aton_end (cp, &val, &endp)) + return val.s_addr; + return INADDR_NONE; +} +weak_alias (__inet_addr, inet_addr) Index: glibc-2.22/resolv/nss_dns/dns-host.c =================================================================== --- glibc-2.22.orig/resolv/nss_dns/dns-host.c +++ glibc-2.22/resolv/nss_dns/dns-host.c @@ -249,11 +249,26 @@ _nss_dns_gethostbyname3_r (const char *n hidden_def (_nss_dns_gethostbyname3_r) +/* Verify that the name looks like a host name. There is no point in + sending a query which will not produce a usable name in the + response. */ +static enum nss_status +check_name (const char *name, int *h_errnop) +{ + if (res_hnok (name)) + return NSS_STATUS_SUCCESS; + *h_errnop = HOST_NOT_FOUND; + return NSS_STATUS_NOTFOUND; +} + enum nss_status _nss_dns_gethostbyname2_r (const char *name, int af, struct hostent *result, char *buffer, size_t buflen, int *errnop, int *h_errnop) { + enum nss_status status = check_name (name, h_errnop); + if (status != NSS_STATUS_SUCCESS) + return status; return _nss_dns_gethostbyname3_r (name, af, result, buffer, buflen, errnop, h_errnop, NULL, NULL); } @@ -264,7 +279,10 @@ _nss_dns_gethostbyname_r (const char *na char *buffer, size_t buflen, int *errnop, int *h_errnop) { - enum nss_status status = NSS_STATUS_NOTFOUND; + enum nss_status status = check_name (name, h_errnop); + if (status != NSS_STATUS_SUCCESS) + return status; + status = NSS_STATUS_NOTFOUND; if (_res.options & RES_USE_INET6) status = _nss_dns_gethostbyname3_r (name, AF_INET6, result, buffer, @@ -282,6 +300,9 @@ _nss_dns_gethostbyname4_r (const char *n char *buffer, size_t buflen, int *errnop, int *herrnop, int32_t *ttlp) { + enum nss_status status = check_name (name, herrnop); + if (status != NSS_STATUS_SUCCESS) + return status; if (__res_maybe_init (&_res, 0) == -1) return NSS_STATUS_UNAVAIL; @@ -311,7 +332,6 @@ _nss_dns_gethostbyname4_r (const char *n int ans2p_malloced = 0; int olderr = errno; - enum nss_status status; int n = __libc_res_nsearch (&_res, name, C_IN, T_QUERY_A_AND_AAAA, host_buffer.buf->buf, 2048, &host_buffer.ptr, &ans2p, &nans2p, &resplen2, &ans2p_malloced); Index: glibc-2.22/resolv/res_init.c =================================================================== --- glibc-2.22.orig/resolv/res_init.c +++ glibc-2.22/resolv/res_init.c @@ -294,8 +294,16 @@ __res_vinit(res_state statp, int preinit cp = buf + sizeof("nameserver") - 1; while (*cp == ' ' || *cp == '\t') cp++; + + /* Ignore trailing contents on the name server line. */ + { + char *el; + if ((el = strpbrk (cp, " \t\n")) != NULL) + *el = '\0'; + } + if ((*cp != '\0') && (*cp != '\n') - && __inet_aton(cp, &a)) { + && __inet_aton_exact(cp, &a)) { statp->nsaddr_list[nserv].sin_addr = a; statp->nsaddr_list[nserv].sin_family = AF_INET; statp->nsaddr_list[nserv].sin_port = @@ -305,9 +313,6 @@ __res_vinit(res_state statp, int preinit } else { struct in6_addr a6; char *el; - - if ((el = strpbrk(cp, " \t\n")) != NULL) - *el = '\0'; if ((el = strchr(cp, SCOPE_DELIMITER)) != NULL) *el = '\0'; if ((*cp != '\0') && @@ -370,7 +375,7 @@ __res_vinit(res_state statp, int preinit cp++; n = *cp; *cp = 0; - if (__inet_aton(net, &a)) { + if (__inet_aton_exact(net, &a)) { statp->sort_list[nsort].addr = a; if (ISSORTMASK(n)) { *cp++ = n; @@ -380,7 +385,7 @@ __res_vinit(res_state statp, int preinit cp++; n = *cp; *cp = 0; - if (__inet_aton(net, &a)) { + if (__inet_aton_exact(net, &a)) { statp->sort_list[nsort].mask = a.s_addr; } else { statp->sort_list[nsort].mask = Index: glibc-2.22/resolv/tst-aton.c =================================================================== --- glibc-2.22.orig/resolv/tst-aton.c +++ glibc-2.22/resolv/tst-aton.c @@ -16,6 +16,7 @@ static struct tests { "-1", 0, 0 }, { "256", 1, 0x00000100 }, { "256.", 0, 0 }, + { "255a", 0, 0 }, { "256a", 0, 0 }, { "0x100", 1, 0x00000100 }, { "0200.0x123456", 1, 0x80123456 }, @@ -40,7 +41,12 @@ static struct tests { "1.2.256.4", 0, 0 }, { "1.2.3.0x100", 0, 0 }, { "323543357756889", 0, 0 }, - { "10.1.2.3.4", 0, 0}, + { "10.1.2.3.4", 0, 0 }, + { "192.0.2.1", 1, 0xc0000201 }, + { "192.0.2.2\nX", 1, 0xc0000202 }, + { "192.0.2.3 Y", 1, 0xc0000203 }, + { "192.0.2.3Z", 0, 0 }, + { "192.000.002.010", 1, 0xc0000208 }, }; Index: glibc-2.22/sysdeps/posix/getaddrinfo.c =================================================================== --- glibc-2.22.orig/sysdeps/posix/getaddrinfo.c +++ glibc-2.22/sysdeps/posix/getaddrinfo.c @@ -477,7 +477,7 @@ gaih_inet (const char *name, const struc } #endif - if (__inet_aton (name, (struct in_addr *) at->addr) != 0) + if (__inet_aton_exact (name, (struct in_addr *) at->addr) != 0) { if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET) at->family = AF_INET;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor