public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
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, &params);
> +  params.family = AF_INET;
> +  support_isolate_in_subprocess (test_gai, &params);
> +  params.canon = true;
> +  support_isolate_in_subprocess (test_gai, &params);
> +}

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.


  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).