* [PATCH] resolv: Fix a domain search list check
@ 2022-01-13 16:21 Petr Pavlu
0 siblings, 0 replies; only message in thread
From: Petr Pavlu @ 2022-01-13 16:21 UTC (permalink / raw)
To: fweimer, libc-alpha; +Cc: Petr Pavlu
From: Petr Pavlu <petr.pavlu@suse.com>
Fix a domain search list check in resolv_conf_matches() which verifies
that a resolv_conf extended state matches a given __res_state. The check
counts a length of entries referenced by the resp->dnsrch array and
tests whether it exceeds the combined storage space for the search list,
but wrongly uses a size of resp->dnsrch instead of resp->defdname.
Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
---
Notes:
The following is an artificial example which demonstrates the issue:
> $ cat test.c
> #include <arpa/inet.h>
> #include <netdb.h>
> #include <netinet/in.h>
> #include <resolv.h>
> #include <stdio.h>
> #include <string.h>
> #include <sys/socket.h>
> #include <sys/types.h>
>
> int main(int argc, char *argv[])
> {
> if (argc < 2) {
> fprintf(stderr, "Usage: %s hostname\n", argv[0]);
> return 1;
> }
> const char *hostname = argv[1];
>
> if (res_init() == -1) {
> fprintf(stderr, "res_init() failed\n");
> return 1;
> }
>
> printf("System search domains:\n");
> for (size_t i = 0; i < sizeof(_res.dnsrch) / sizeof(_res.dnsrch[0]); i++)
> if (_res.dnsrch[i] != NULL)
> printf(" %zu: %s\n", i, _res.dnsrch[i]);
>
> printf("Custom search domains:\n");
> memset(_res.dnsrch, 0, sizeof(_res.dnsrch));
> memset(_res.defdname, 0, sizeof(_res.defdname));
> _res.dnsrch[0] = _res.defdname;
> snprintf(_res.defdname, sizeof(_res.defdname), "%s",
> "012345678901234567890123456789012345678901234567890123456789.example.org");
> for (size_t i = 0; i < sizeof(_res.dnsrch) / sizeof(_res.dnsrch[0]); i++)
> if (_res.dnsrch[i] != NULL)
> printf(" %zu: %s\n", i, _res.dnsrch[i]);
>
> struct addrinfo hints, *result;
> memset(&hints, 0, sizeof(hints));
> hints.ai_family = AF_INET;
> hints.ai_socktype = SOCK_STREAM;
> int s = getaddrinfo(hostname, NULL, &hints, &result);
> if (s != 0) {
> fprintf(stderr, "getaddrinfo() failed: %s\n", gai_strerror(s));
> return 1;
> }
>
> printf("Resolved addresses:\n");
> for (struct addrinfo *p = result; p != NULL; p = p->ai_next) {
> struct sockaddr_in *h = (struct sockaddr_in *) p->ai_addr;
> printf(" %s\n", inet_ntoa(h->sin_addr));
> }
> freeaddrinfo(result);
>
> return 0;
> }
> $ gcc -Wall -pedantic -lresolv test.c
> $ cat /etc/resolv
> search 012345678901234567890123456789012345678901234567890123456789.example.org gnu.org
> [...]
Previous behaviour:
> $ ./a.out savannah
> System search domains:
> 0: 012345678901234567890123456789012345678901234567890123456789.example.org
> 1: gnu.org
> Custom search domains:
> 0: 012345678901234567890123456789012345678901234567890123456789.example.org
> Resolved addresses:
> 209.51.188.72
Updated version which recognizes that _res was modified:
> $ ./a.out savannah
> System search domains:
> 0: 012345678901234567890123456789012345678901234567890123456789.example.org
> 1: gnu.org
> Custom search domains:
> 0: 012345678901234567890123456789012345678901234567890123456789.example.org
> getaddrinfo() failed: Name or service not known
resolv/resolv_conf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/resolv/resolv_conf.c b/resolv/resolv_conf.c
index 6dd552bb47..ef872dbc14 100644
--- a/resolv/resolv_conf.c
+++ b/resolv/resolv_conf.c
@@ -310,7 +310,7 @@ resolv_conf_matches (const struct __res_state *resp,
exceeds MAXDNSRCH, or if the combined storage space for
the search list exceeds what can be stored in
resp->defdname. */
- if (i == MAXDNSRCH || search_list_size > sizeof (resp->dnsrch))
+ if (i == MAXDNSRCH || search_list_size > sizeof (resp->defdname))
break;
/* Otherwise, a mismatch indicates a match failure. */
return false;
--
2.26.2
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-01-13 16:21 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-13 16:21 [PATCH] resolv: Fix a domain search list check Petr Pavlu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).