From: DJ Delorie <dj@redhat.com>
To: Siddhesh Poyarekar <siddhesh@sourceware.org>
Cc: libc-alpha@sourceware.org
Subject: Re: [PATCH v2 01/12] Simplify allocations and fix merge and continue actions [BZ #28931]
Date: Wed, 16 Mar 2022 16:47:06 -0400 [thread overview]
Message-ID: <xnmthpiq0l.fsf@greed.delorie.com> (raw)
In-Reply-To: <20220314094835.1159523-2-siddhesh@sourceware.org> (message from Siddhesh Poyarekar via Libc-alpha on Mon, 14 Mar 2022 15:18:24 +0530)
LGTM
Reviewed-by: DJ Delorie <dj@redhat.com>
Siddhesh Poyarekar via Libc-alpha <libc-alpha@sourceware.org> writes:
> diff --git a/nss/Makefile b/nss/Makefile
> +tests += tst-nss-gai-actions
New test OK.
> diff --git a/nss/tst-nss-gai-actions.c b/nss/tst-nss-gai-actions.c
> +enum
> +{
> + ACTION_MERGE = 0,
> + ACTION_CONTINUE,
> +};
> +
> +struct test_params
> +{
> + int action;
> + int family;
> + bool canon;
> +};
> +
> +struct support_chroot *chroot_env;
Ok.
> +static void
> +prepare (int argc, char **argv)
> +{
> + chroot_env = support_chroot_create
> + ((struct support_chroot_configuration)
> + {
> + .resolv_conf = "",
> + .hosts = "",
> + .host_conf = "multi on\n",
> + });
> +}
I'm curious why you chose to go this route rather than using the
test-container framework, which would have done most of this for you?
(but ok)
> +/* Create the /etc/hosts file from outside the chroot. */
> +static void
> +write_hosts (void)
> +{
> + const int count = 512;
> +
> + FILE *fp = xfopen (chroot_env->path_hosts, "w");
> + fputs ("127.0.0.1 localhost localhost.localdomain\n"
> + "::1 localhost localhost.localdomain\n",
> + fp);
> + for (int i = 1; i < count; ++i)
> + fprintf (fp, "192.0.%d.%d gnu.org\n", (i / 256) & 0xff, i & 0xff);
That's a lot of gnu.org :-)
> + xfclose (fp);
> +}
Ok.
> +static const char *
> +family_str (int family)
> +{
> + switch (family)
> + {
> + case AF_UNSPEC:
> + return "AF_UNSPEC";
> + case AF_INET:
> + return "AF_INET";
> + default:
> + __builtin_unreachable ();
> + }
> +}
Ok.
> +static const char *
> +action_str (int action)
> +{
> + switch (action)
> + {
> + case ACTION_MERGE:
> + return "merge";
> + case ACTION_CONTINUE:
> + return "continue";
> + default:
> + __builtin_unreachable ();
> + }
> +}
Ok.
> +/* getaddrinfo test. To be run from a subprocess. */
> +static void
> +test_gai (void *closure)
> +{
> + struct test_params *params = closure;
> +
> + struct addrinfo hints =
> + {
> + .ai_family = params->family,
> + };
> +
> + struct addrinfo *ai;
> +
> + if (params->canon)
> + hints.ai_flags = AI_CANONNAME;
> +
> + /* Use /etc/hosts in the chroot. */
> + xchroot (chroot_env->path_chroot);
> +
> + printf ("***** Testing \"files [SUCCESS=%s] files\" for family %s, %s\n",
> + action_str (params->action), family_str (params->family),
> + params->canon ? "AI_CANONNAME" : "");
> +
> + int ret = getaddrinfo ("gnu.org", "80", &hints, &ai);
> +
> + switch (params->action)
> + {
> + case ACTION_MERGE:
> + if (ret == 0)
> + {
> + char *formatted = support_format_addrinfo (ai, ret);
> +
> + printf ("merge unexpectedly succeeded:\n %s\n", formatted);
> + support_record_failure ();
> + free (formatted);
> + }
> + else
> + return;
> + case ACTION_CONTINUE:
> + {
> + char *formatted = support_format_addrinfo (ai, ret);
> +
> + /* Verify that the result appears exactly once. */
> + const char *expected = "address: STREAM/TCP 192.0.0.1 80\n"
> + "address: DGRAM/UDP 192.0.0.1 80\n"
> + "address: RAW/IP 192.0.0.1 80\n";
> +
> + const char *contains = strstr (formatted, expected);
> + const char *contains2 = NULL;
> +
> + if (contains != NULL)
> + contains2 = strstr (contains + strlen (expected), expected);
> +
> + if (contains == NULL || contains2 != NULL)
> + {
> + printf ("continue failed:\n%s\n", formatted);
> + support_record_failure ();
> + }
> +
> + free (formatted);
> + break;
> + }
> + default:
> + __builtin_unreachable ();
> + }
> +}
Ok.
> +static void
> +test_in_subprocess (int action)
> +{
> + char buf[32];
> +
> + snprintf (buf, sizeof (buf), "files [SUCCESS=%s] files",
> + action_str (action));
> + __nss_configure_lookup ("hosts", buf);
> +
> + struct test_params params =
> + {
> + .action = action,
> + .family = AF_UNSPEC,
> + .canon = false,
> + };
> + support_isolate_in_subprocess (test_gai, ¶ms);
> + params.family = AF_INET;
> + support_isolate_in_subprocess (test_gai, ¶ms);
> + params.canon = true;
> + support_isolate_in_subprocess (test_gai, ¶ms);
> +}
Ok.
> +static int
> +do_test (void)
> +{
> + support_become_root ();
> + if (!support_can_chroot ())
> + FAIL_UNSUPPORTED ("Cannot chroot\n");
> +
> + write_hosts ();
> + test_in_subprocess (ACTION_CONTINUE);
> + test_in_subprocess (ACTION_MERGE);
> +
> + support_chroot_free (chroot_env);
> + return 0;
> +}
Ok.
> +#define PREPARE prepare
> +#include <support/test-driver.c>
Ok.
> diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
> index 18dccd5924..454a27eb2f 100644
> --- a/sysdeps/posix/getaddrinfo.c
> +++ b/sysdeps/posix/getaddrinfo.c
> @@ -458,11 +458,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
>
> if (name != NULL)
> {
> - at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
> - at->family = AF_UNSPEC;
> - at->scopeid = 0;
> - at->next = NULL;
> -
Moved below, ok.
> - if (__inet_aton_exact (name, (struct in_addr *) at->addr) != 0)
> + uint32_t addr[4];
> + if (__inet_aton_exact (name, (struct in_addr *) addr) != 0)
Use temp buffer because not allocated, ok.
> + at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
> + at->scopeid = 0;
> + at->next = NULL;
> +
Ok.
> if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
> - at->family = AF_INET;
> + {
> + memcpy (at->addr, addr, sizeof (at->addr));
> + at->family = AF_INET;
> + }
Ok.
> else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED))
> {
> - at->addr[3] = at->addr[0];
> + at->addr[3] = addr[0];
Ok.
> @@ -493,49 +496,62 @@ gaih_inet (const char *name, const struct gaih_service *service,
>
> if (req->ai_flags & AI_CANONNAME)
> canon = name;
> +
> + goto process_list;
ok.
> }
> - else if (at->family == AF_UNSPEC)
> +
> + char *scope_delim = strchr (name, SCOPE_DELIMITER);
> + int e;
> +
> + if (scope_delim == NULL)
> + e = inet_pton (AF_INET6, name, addr);
> + else
> + e = __inet_pton_length (AF_INET6, name, scope_delim - name, addr);
Moved out of scope, ok.
> +
> + if (e > 0)
Moved up, ok.
> {
> - char *scope_delim = strchr (name, SCOPE_DELIMITER);
> - int e;
> - if (scope_delim == NULL)
> - e = inet_pton (AF_INET6, name, at->addr);
Move up, ok.
> + at = alloca_account (sizeof (struct gaih_addrtuple),
> + alloca_used);
> + at->scopeid = 0;
> + at->next = NULL;
> +
> + if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
> + {
> + memcpy (at->addr, addr, sizeof (at->addr));
> + at->family = AF_INET6;
> + }
> + else if (req->ai_family == AF_INET
> + && IN6_IS_ADDR_V4MAPPED (addr))
> + {
> + at->addr[0] = addr[3];
> + at->addr[1] = addr[1];
> + at->addr[2] = addr[2];
> + at->addr[3] = addr[3];
> + at->family = AF_INET;
> + }
Moved, ok.
> else
> - e = __inet_pton_length (AF_INET6, name, scope_delim - name,
> - at->addr);
> - if (e > 0)
> {
> - if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
> - at->family = AF_INET6;
> - else if (req->ai_family == AF_INET
> - && IN6_IS_ADDR_V4MAPPED (at->addr))
> - {
> - at->addr[0] = at->addr[3];
> - at->family = AF_INET;
> - }
> - else
> - {
> - result = -EAI_ADDRFAMILY;
> - goto free_and_return;
> - }
> -
> - if (scope_delim != NULL
> - && __inet6_scopeid_pton ((struct in6_addr *) at->addr,
> - scope_delim + 1,
> - &at->scopeid) != 0)
> - {
> - result = -EAI_NONAME;
> - goto free_and_return;
> - }
Moved, ok.
> + result = -EAI_ADDRFAMILY;
> + goto free_and_return;
> + }
Moved, ok.
> - if (req->ai_flags & AI_CANONNAME)
> - canon = name;
> + if (scope_delim != NULL
> + && __inet6_scopeid_pton ((struct in6_addr *) at->addr,
> + scope_delim + 1,
> + &at->scopeid) != 0)
> + {
> + result = -EAI_NONAME;
> + goto free_and_return;
Moved, ok.
> }
> +
> + if (req->ai_flags & AI_CANONNAME)
> + canon = name;
> +
> + goto process_list;
> }
Ok.
> - if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0)
> + if ((req->ai_flags & AI_NUMERICHOST) == 0)
Ok.
> {
> - struct gaih_addrtuple **pat = &at;
Ok.
> + bool do_merge = false;
Ok.
> @@ -579,7 +596,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
> result = -EAI_MEMORY;
> goto free_and_return;
> }
> - *pat = addrmem;
> + at = addrmem;
Ok.
> struct gaih_addrtuple *addrfree = addrmem;
> + struct gaih_addrtuple **pat = &at;
> +
Ok.
> free (air);
>
> - if (at->family == AF_UNSPEC)
> - {
> - result = -EAI_NONAME;
> - goto free_and_return;
> - }
> -
Ok.
> @@ -732,6 +745,21 @@ gaih_inet (const char *name, const struct gaih_service *service,
>
> while (!no_more)
> {
> + /* Always start afresh; continue should discard previous results
> + and the hosts database does not support merge. */
> + at = NULL;
> + free (canonbuf);
> + free (addrmem);
> + canon = canonbuf = NULL;
> + addrmem = NULL;
> +
> + if (do_merge)
> + {
> + __set_h_errno (NETDB_INTERNAL);
> + __set_errno (EBUSY);
> + break;
> + }
> +
Ok.
> - status = DL_CALL_FCT (fct4, (name, pat,
> + status = DL_CALL_FCT (fct4, (name, &at,
Ok.
> + /* gethostbyname4_r may write into AT, so reset it. */
> + at = NULL;
This is alloca-ted, so no leak here. ok.
> @@ -774,7 +804,9 @@ gaih_inet (const char *name, const struct gaih_service *service,
> no_data = 1;
>
> if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL)
> - canon = (*pat)->name;
> + canon = at->name;
> +
> + struct gaih_addrtuple **pat = &at;
Ok.
> while (*pat != NULL)
> {
> @@ -826,6 +858,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
>
> if (fct != NULL)
> {
> + struct gaih_addrtuple **pat = &at;
> +
Ok.
> + /* The hosts database does not support MERGE. */
> + if (nss_next_action (nip, status) == NSS_ACTION_MERGE)
> + do_merge = true;
> +
Ok.
> process_list:
> - if (at->family == AF_UNSPEC)
> + if (at == NULL)
Ok.
next prev parent reply other threads:[~2022-03-16 20:47 UTC|newest]
Thread overview: 68+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-08 10:07 [PATCH 00/12] getaddrinfo facelift and fixes Siddhesh Poyarekar
2022-03-08 10:07 ` [PATCH 01/12] Simplify allocations and fix merge and continue actions [BZ #28931] Siddhesh Poyarekar
2022-03-08 13:52 ` Siddhesh Poyarekar
2022-03-08 21:12 ` Carlos O'Donell
2022-03-09 17:13 ` Siddhesh Poyarekar
2022-03-08 10:07 ` [PATCH 02/12] gaih_inet: Simplify canon name resolution Siddhesh Poyarekar
2022-03-08 10:07 ` [PATCH 03/12] getaddrinfo: Fix leak with AI_ALL [BZ #28852] Siddhesh Poyarekar
2022-03-08 11:00 ` Andreas Schwab
2022-03-08 13:45 ` Siddhesh Poyarekar
2022-03-08 10:07 ` [PATCH 04/12] gaih_inet: Simplify service resolution Siddhesh Poyarekar
2022-03-08 10:07 ` [PATCH 05/12] gaih_inet: make numeric lookup a separate routine Siddhesh Poyarekar
2022-03-08 10:07 ` [PATCH 06/12] gaih_inet: Split simple gethostbyname into its own function Siddhesh Poyarekar
2022-03-08 10:07 ` [PATCH 07/12] gaih_inet: Split nscd lookup code " Siddhesh Poyarekar
2022-03-08 10:07 ` [PATCH 08/12] gaih_inet: separate nss lookup loop " Siddhesh Poyarekar
2022-03-08 10:07 ` [PATCH 09/12] gaih_inet: make gethosts into a function Siddhesh Poyarekar
2022-03-08 10:07 ` [PATCH 10/12] gaih_inet: split loopback lookup into its own function Siddhesh Poyarekar
2022-03-08 10:07 ` [PATCH 11/12] gaih_inet: Split result generation " Siddhesh Poyarekar
2022-03-08 10:07 ` [PATCH 12/12] gethosts: Return EAI_MEMORY on allocation failure Siddhesh Poyarekar
2022-03-14 9:48 ` [PATCH v2 00/12] getaddrinfo facelift and fixes Siddhesh Poyarekar
2022-03-14 9:48 ` [PATCH v2 01/12] Simplify allocations and fix merge and continue actions [BZ #28931] Siddhesh Poyarekar
2022-03-14 10:30 ` Andreas Schwab
2022-03-14 14:15 ` Siddhesh Poyarekar
2022-03-16 20:47 ` DJ Delorie [this message]
2022-03-17 1:39 ` Siddhesh Poyarekar
2022-03-14 9:48 ` [PATCH v2 02/12] gaih_inet: Simplify canon name resolution Siddhesh Poyarekar
2022-03-16 21:12 ` DJ Delorie
2022-03-14 9:48 ` [PATCH v2 03/12] getaddrinfo: Fix leak with AI_ALL [BZ #28852] Siddhesh Poyarekar
2022-03-16 23:42 ` DJ Delorie
2022-03-17 2:30 ` Siddhesh Poyarekar
2022-03-14 9:48 ` [PATCH v2 04/12] gaih_inet: Simplify service resolution Siddhesh Poyarekar
2022-03-17 0:48 ` DJ Delorie
2022-03-14 9:48 ` [PATCH v2 05/12] gaih_inet: make numeric lookup a separate routine Siddhesh Poyarekar
2022-03-17 4:10 ` DJ Delorie
2022-03-14 9:48 ` [PATCH v2 06/12] gaih_inet: Split simple gethostbyname into its own function Siddhesh Poyarekar
2022-03-17 4:20 ` DJ Delorie
2022-03-14 9:48 ` [PATCH v2 07/12] gaih_inet: Split nscd lookup code " Siddhesh Poyarekar
2022-03-17 4:31 ` DJ Delorie
2022-03-17 6:22 ` Siddhesh Poyarekar
2022-03-14 9:48 ` [PATCH v2 08/12] gaih_inet: separate nss lookup loop " Siddhesh Poyarekar
2022-03-17 4:42 ` DJ Delorie
2022-03-17 4:59 ` Siddhesh Poyarekar
2022-03-14 9:48 ` [PATCH v2 09/12] gaih_inet: make gethosts into a function Siddhesh Poyarekar
2022-03-17 4:44 ` DJ Delorie
2022-03-14 9:48 ` [PATCH v2 10/12] gaih_inet: split loopback lookup into its own function Siddhesh Poyarekar
2022-03-17 4:51 ` DJ Delorie
2022-03-14 9:48 ` [PATCH v2 11/12] gaih_inet: Split result generation " Siddhesh Poyarekar
2022-03-17 5:05 ` DJ Delorie
2022-03-17 5:11 ` Siddhesh Poyarekar
2022-03-14 9:48 ` [PATCH v2 12/12] gethosts: Return EAI_MEMORY on allocation failure Siddhesh Poyarekar
2022-03-17 5:06 ` DJ Delorie
2022-03-14 13:21 ` [PATCH 00/12] getaddrinfo facelift and fixes Cristian Rodríguez
2022-03-14 14:16 ` Siddhesh Poyarekar
2022-03-17 8:11 ` [PATCH v3 " Siddhesh Poyarekar
2022-03-17 8:11 ` [PATCH v3 01/12] Simplify allocations and fix merge and continue actions [BZ #28931] Siddhesh Poyarekar
2022-03-17 21:47 ` DJ Delorie
2022-03-17 8:11 ` [PATCH v3 02/12] gaih_inet: Simplify canon name resolution Siddhesh Poyarekar
2022-03-17 8:11 ` [PATCH v3 03/12] getaddrinfo: Fix leak with AI_ALL [BZ #28852] Siddhesh Poyarekar
2022-03-17 8:11 ` [PATCH v3 04/12] gaih_inet: Simplify service resolution Siddhesh Poyarekar
2022-03-17 8:11 ` [PATCH v3 05/12] gaih_inet: make numeric lookup a separate routine Siddhesh Poyarekar
2022-03-17 8:11 ` [PATCH v3 06/12] gaih_inet: Split simple gethostbyname into its own function Siddhesh Poyarekar
2022-03-17 8:11 ` [PATCH v3 07/12] gaih_inet: Split nscd lookup code " Siddhesh Poyarekar
2022-03-17 22:02 ` DJ Delorie
2022-03-17 8:11 ` [PATCH v3 08/12] gaih_inet: separate nss lookup loop " Siddhesh Poyarekar
2022-03-17 22:05 ` DJ Delorie
2022-03-17 8:11 ` [PATCH v3 09/12] gaih_inet: make gethosts into a function Siddhesh Poyarekar
2022-03-17 8:11 ` [PATCH v3 10/12] gaih_inet: split loopback lookup into its own function Siddhesh Poyarekar
2022-03-17 8:11 ` [PATCH v3 11/12] gaih_inet: Split result generation " Siddhesh Poyarekar
2022-03-17 8:11 ` [PATCH v3 12/12] gethosts: Return EAI_MEMORY on allocation failure Siddhesh Poyarekar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=xnmthpiq0l.fsf@greed.delorie.com \
--to=dj@redhat.com \
--cc=libc-alpha@sourceware.org \
--cc=siddhesh@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).