Filip Ochnik spotted that one of the error jumps in gethosts fails to
call __resolv_context_put to release the resolver context.
Fixes commit 352f4ff9a2 ("resolv:
Introduce struct resolv_context [BZ #21668]") and commit
964263bb8d ("getaddrinfo: Release
resolver context on error in gethosts [BZ #21885]").
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
The function uses the internal service_user type, so it is not
really usable from the outside of glibc. Rename the function
to __nss_database_lookup2 for internal use, and change
__nss_database_lookup to always indicate failure to the caller.
__nss_next already was a compatibility symbol. The new
implementation always fails and no longer calls __nss_next2.
unscd, the alternative nscd implementation, does not use
__nss_database_lookup, so it is not affected by this change.
This functionality was deprecated in glibc 2.25.
This commit only includes the core changes to remove the
functionality. It does not remove the RES_USE_INET6 handling in the
individual NSS service modules and the res_use_inet6 function.
These changes will happen in future commits.
The IPv4 address parser in the getaddrinfo function is changed so that
it does not ignore trailing whitespace and all characters after it.
For backwards compatibility, the getaddrinfo function still recognizes
legacy name syntax, such as 192.000.002.010 interpreted as 192.0.2.8
(octal).
This commit does not change the behavior of inet_addr and inet_aton.
gethostbyname already had additional sanity checks (but is switched
over to the new __inet_aton_exact function for completeness as well).
To avoid sending the problematic query names over DNS, commit
6ca53a2453 ("resolv: Do not send queries
for non-host-names in nss_dns [BZ #24112]") is needed.
Continuing the fixes for linknamespace and localplt test failures with
-Os that arise from functions not being inlined in that case, this
patch fixes such failures for feof_unlocked.
The usual approach is followed of adding __feof_unlocked (inlined when
feof_unlocked is), making calls use it when required for namespace
reasons, and using libc_hidden_proto / libc_hidden_weak for the
feof_unlocked weak alias when only localplt but not namespace issues
are involved. In the case of getaddrinfo.c, use of __feof_unlocked
needs to be conditional since that code is also used in nscd (where
__feof_unlocked is not available).
Tested for x86_64 (both without -Os to make sure that case continues
to work, and with -Os to make sure all the relevant linknamespace and
localplt test failures are resolved). Because of other such failures
that remain after this patch, neither of the bugs can yet be closed.
[BZ #15105]
[BZ #19463]
* libio/feof_u.c (feof_unlocked): Rename to __feof_unlocked and
define as weak alias of __feof_unlocked. Use libc_hidden_weak.
* include/stdio.h (feof_unlocked): Use libc_hidden_proto.
(__feof_unlocked): New declaration, and inline function if
[__USE_EXTERN_INLINES].
* iconv/gconv_conf.c (read_conf_file): Call __feof_unlocked
instead of feof_unlocked.
* intl/localealias.c [_LIBC] (FEOF): Likewise.
* nss/nsswitch.c (nss_parse_file): Likewise.
* sysdeps/unix/sysv/linux/readonly-area.c (__readonly_area):
Likewise.
* time/getdate.c (__getdate_r): Likewise.
* sysdeps/posix/getaddrinfo.c [IS_IN (libc)] (feof_unlocked):
Define as macro to call __feof_unlocked.
Hide internal idna functions to allow direct access within libc.so and
libc.a without using GOT nor PLT.
[BZ #18822]
* include/idna.h: New file.
* inet/getnameinfo.c: Include <idna.h> instead of
<libidn/idna.h>.
(__idna_to_unicode_lzlz): Removed.
* sysdeps/posix/getaddrinfo.c: Include <idna.h> instead of
<libidn/idna.h>.
(__idna_to_ascii_lz): Removed.
(__idna_to_unicode_lzlz): Likewise.
The old code uses errno as the primary indicator for success or
failure. This is wrong because errno is only set for specific
combinations of the status return value and the h_errno variable.
This simplifies the code because it is not necessary to propagate the
temporary h_errno value to the thread-local variable. It also increases
compatibility with NSS modules which update only one of the two places.
Mark internal nss symbols with attribute_hidden to allow direct access
within libc.so and libc.a without using GOT nor PLT.
Tested on x86-64 with and without --disable-nscd.
[BZ #18822]
* grp/initgroups.c (__nss_group_database): Removed.
(__nss_initgroups_database): Likewise.
* nscd/gai.c (__nss_hosts_database): Likewise.
* nss/XXX-lookup.c (DATABASE_NAME_SYMBOL): Likewise.
* posix/tst-rfc3484-2.c (__nss_hosts_database): Likewise.
* posix/tst-rfc3484-3.c (__nss_hosts_database): Likewise.
* posix/tst-rfc3484.c (__nss_hosts_database): Likewise.
* sysdeps/posix/getaddrinfo.c (__nss_hosts_database): Likewise.
* nss/getXXent.c (INTERNAL (REENTRANT_GETNAME)): Add
attribute_hidden.
* nss/nsswitch.c (__nss_database_custom): Define only if
USE_NSCD is defined.
(__nss_configure_lookup): Use __nss_database_custom only if
USE_NSCD is defined.
* nss/nsswitch.h (__nss_database_custom): Declare only if
USE_NSCD is defined. Add attribute_hidden.
(__nss_setent): Add attribute_hidden.
(__nss_endent): Likewise.
(__nss_getent_r): Likewise.
(__nss_getent): Likewise.
(DEFINE_DATABASE): Declare __nss_##arg##_database.
struct resolv_context objects provide a temporary resolver context
which does not change during a name lookup operation. Only when the
outmost context is created, the stub resolver configuration is
verified to be current (at present, only against previous res_init
calls). Subsequent attempts to obtain the context will reuse the
result of the initial verification operation.
struct resolv_context can also be extended in the future to store
data which needs to be deallocated during thread cancellation.
Many callers of __res_maybe_init also call _res_hconf_init.
Additional calls to the latter do not hurt because the function
does its work only once. (/etc/hosts.conf is not reloaded or
even checked for changes.) This means that we can simplify the
code by calling _res_hconf_init directly from __res_vinit.
A further simplification could eliminate the canon variable in
gaih_inet and replace it with canonbuf. However, canonbuf is
used as a flag in the nscd code, which makes this somewhat
non-straightforward.
calls with constant strings shows a small (~10%) performance gain, strdup is
typically used in error reporting code, so not performance critical.
Remove the now unused __need_malloc_and_calloc related defines from stdlib.h.
Rename existing uses of str(n)dup to __str(n)dup so it no longer needs to be
redirected to a builtin. Also building GLIBC with -Os now no longer shows
localplt or linkname space failures (partial fix for BZ #15105 and BZ #19463).
[BZ #15105]
[BZ #19463]
* elf/dl-cache.c (_dl_load_cache_lookup): Use __strdup.
* inet/rcmd.c (rcmd_af): Likewise.
* inet/rexec.c (rexec_af): Likewise.
* intl/dcigettext.c (_LIBC): Likewise.
* intl/finddomain.c (_nl_find_domain): Use strdup expansion.
* locale/loadarchive.c (_nl_load_locale_from_archive): Use __strdup.
* locale/setlocale.c (setlocale): Likewise.
* posix/spawn_faction_addopen.c
(posix_spawn_file_actions_addopen): Likewise.
* stdlib/putenv.c (putenv): Use __strndup.
* sunrpc/svc_simple.c (__registerrpc): Use __strdup.
* sysdeps/posix/getaddrinfo.c (gaih_inet): Use __strdup/__strndup.
* include/stdlib.h (__need_malloc_and_calloc): Remove uses.
(__Need_M_And_C) Remove define/undef.
* stdlib/stdlib.h (__need_malloc_and_calloc): Remove uses.
(__malloc_and_calloc_defined): Remove define.
* string/bits/string2.h (__strdup): Remove define.
(strdup): Likewise.
(__strndup): Likewise.
(strndup): Likewise.
_res_hconf.initialized was not suitable for use in a multi-threaded
environment due to the lack of atomics and memory barriers. Use of it was
also unnecessary because _res_hconf_init did the right thing by using
__libc_once. This patch fixes the glibc-internal uses by just calling
_res_hconf_init unconditionally, and switches to a release MO atomic store
for _res_hconf.initialized to fix the glibc side of the synchronization
problem (which will maintain backward compatibility, but cannot fix the
lack of acquire MO on any glibc-external loads).
[BZ #20477]
* resolv/res_hconf.c (do_init): Use atomic access.
* resolv/res_hconf.h: Add comments.
* nscd/aicache.c (addhstaiX): Call _res_hconf_init unconditionally.
* nss/getXXbyYY_r.c (REENTRANT_NAME): Likewise.
* sysdeps/posix/getaddrinfo.c (gaih_inet): Likewise.
When converting a struct hostent response to struct gaih_addrtuple, the
gethosts macro (which is called from gaih_inet) used alloca, without
malloc fallback for large responses. This commit changes this code to
use calloc unconditionally.
This commit also consolidated a second hostent-to-gaih_addrtuple
conversion loop (in gaih_inet) to use the new conversion function.
qsort_r is defined in the same file as qsort, but is not an ISO C
function, so should be a weak alias for __qsort_r. The uses in
getaddrinfo should also call __qsort_r, since getaddrinfo is a POSIX
function and qsort_r isn't. This patch implements this. Because nscd
uses the getaddrinfo sources outside libc, as do the tst-rfc3484
tests, a #define of __qsort_r to qsort_r is added there alongside the
similar defines for other libc-internal symbols used in getaddrinfo.
Tested for x86_64 (testsuite, and that disassembly of installed shared
libraries is unchanged by the patch).
[BZ #17571]
* stdlib/msort.c (qsort_r): Rename to __qsort_r and define as weak
alias of __qsort_r.
(qsort): Call __qsort_r instead of qsort_r.
* include/stdlib.h (qsort_r): Do not call libc_hidden_proto.
(__qsort_r): Declare. Call libc_hidden_proto.
* sysdeps/posix/getaddrinfo.c (getaddrinfo): Call __qsort_r
instead of qsort_r.
* nscd/gai.c (__qsort_r): Define to qsort_r.
* posix/tst-rfc3484.c (__qsort_r): Likewise.
* posix/tst-rfc3484-2.c (__qsort_r): Likewise.
* posix/tst-rfc3484-3.c (__qsort_r): Likewise.
getaddrinfo correctly returns EAI_AGAIN for AF_INET and AF_INET6
queries. For AF_UNSPEC however, an older change
(a682a1bf55) broke the check and due to
that the returned error was EAI_NONAME.
This patch fixes the check so that a non-authoritative not-found is
returned as EAI_AGAIN to the user instead of EAI_NONAME.
This fixes a bug in the way the results from __nscd_getai are collected:
for every returned result a new entry is first added to the
gaih_addrtuple list, but if that result doesn't match the request this
entry remains uninitialized. So for this non-matching result an extra
result with uninitialized content is returned.
To reproduce (with nscd running):
$ getent ahostsv4 localhost
127.0.0.1 STREAM localhost
127.0.0.1 DGRAM
127.0.0.1 RAW
(null) STREAM
(null) DGRAM
(null) RAW
Only gaih_inet() and gaih_inet_serv() use a special bit flag denoted
by the GAIH_OKIFUNSPEC macro. Only the return value of
gaih_inet_serv() is actively checked for the bit flag which is
redundant because it just copies the nonzero property of the value
otherwise returned. The return value of gaih_inet() is only checked
for being zero and then the bit flag is filtered out. As the bit flag
is set only for otherwise nonzero return values, it doesn't affect the
zero comparison. GAIH_EAI just an alias to ~GAIH_OKIFUNSPEC.
Resolves#16072 (CVE-2013-4458).
This patch fixes another stack overflow in getaddrinfo when it is
called with AF_INET6. The AF_UNSPEC case was fixed as CVE-2013-1914,
but the AF_INET6 case went undetected back then.
[BZ #9954]
With the following /etc/hosts:
127.0.0.1 www.my-domain.es
127.0.1.1 www.my-domain.es
192.168.0.1 www.my-domain.es
Using getaddrinfo() on www.my-domain.es, trigger the following assertion:
../sysdeps/posix/getaddrinfo.c:1473: rfc3484_sort: Assertion
`src->results[i].native == -1 || src->results[i].native == a1_native' failed.
This is due to two different bugs:
- In rfc3484_sort() rule 7, src->results[i].native is assigned even if
src->results[i].index is -1, meaning that no interface is associated.
- In getaddrinfo() the source IP address used with the lo interface needs a
special case, as it can be any IP within 127.X.Y.Z.