On Fri, May 29, 2020 at 08:56:20PM +1000, Darren Tucker wrote:

> On Fri, May 29, 2020 at 12:45:12PM +0200, Otto Moerbeek wrote:
> [...]
> > This fails on arm64:
> > 
> > /usr/src/usr.bin/ssh/ssh/../misc.c:1181:51: error: passing 'void *' to 
> > parameter of incompatible type
> >       'va_list' (aka '__builtin_va_list')
> >         ret = vdollar_percent_expand(&err, 1, 0, string, NULL);
> >                                                          ^~~~
> > /usr/include/sys/_null.h:10:14: note: expanded from macro 'NULL'
> > #define NULL    ((void *)0)
> >                 ^~~~~~~~~~~
> > /usr/src/usr.bin/ssh/ssh/../misc.c:1060:33: note: passing argument to
> > parameter 'ap' here
> >     const char *string, va_list ap)
> >                                 ^
> > 1 error generated.
> 
> Sigh, I just found that out in portable too.  Here's the message I just
> sent to the other openssh developers.  If you have any better
> suggestions or an ok I'd be happy to hear it.

I made a quick fix locally which does the same as the diff below.
Wouldn't know another portable way.

        -Otto

> 
> ---------------------------------------------------------------------
> 
> A brief recap:
>  - percent_expand originally was variadic, which made sense since it
>    could take a variable number of %-tokens.
>  - When we added environment variables, we put it in the same function as
>    percent_expand instead of a separate one to prevent unanticipated
>    interactions between the two.  this became vdollar_percent_expand.
>  - There's wrapper functions around that to do percent, dollar or both
>    expansions.
>  - dollar_expand is not variadic because the variadic args are for
>    percent expansion which it doesn't do.
>  - originally I passed a NULL as the va_list to vdollar_percent_expand.
>    Damien pointed out that there's no guarantee va_list is a pointer
>    equivalent, so it was changed to a real va_list which was memset-0ed.
> 
> After commiting, I found out that this memset blew up on i386:
> 
> misc.c:1182:23: error: ´memset´ call operates on objects of type
> ´char´ while the size is based on a different type ´va_list´ (´char *´) 
> [-Werror,-Wsizeof-pointer-memaccess]
>       memset(ap, 0, sizeof(ap));  /* unused */
> 
> To unbreak the build, I switched it back to passing NULL, which works on at
> least i386 and amd64.  Now I'm trying to fix the mess properly.
> 
> As far as I can tell, there's no standards-compliant way to either pass
> an unused va_list or initialize an unused real va_list.  Googling
> indicates that calling va_start from a non-variadic function will
> generate a compiler warning, although our clang seems OK with it.
> 
> This diff below makes dollar_expand variadic, with any such arguments
> ignored in the workhorse function.
> 
> Does anyone know a better way to fix this?  Passing an uninitialized
> va_list seems wrong even if the called function doesn't use it.
> 
> Index: misc.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/ssh/misc.c,v
> retrieving revision 1.151
> diff -u -p -r1.151 misc.c
> --- misc.c    29 May 2020 09:02:44 -0000      1.151
> +++ misc.c    29 May 2020 09:41:47 -0000
> @@ -1172,13 +1172,22 @@ vdollar_percent_expand(int *parseerror, 
>  #undef EXPAND_MAX_KEYS
>  }
>  
> +/*
> + * Expand only environment variables.
> + * Note that although this function is variadic like the other similar
> + * functions, any such arguments will be unused.
> + */
> +
>  char *
> -dollar_expand(int *parseerr, const char *string)
> +dollar_expand(int *parseerr, const char *string, ...)
>  {
>       char *ret;
>       int err;
> +     va_list ap;
>  
> -     ret = vdollar_percent_expand(&err, 1, 0, string, NULL);
> +     va_start(ap, string);
> +     ret = vdollar_percent_expand(&err, 1, 0, string, ap);
> +     va_end(ap);
>       if (parseerr != NULL)
>               *parseerr = err;
>       return ret;
> Index: misc.h
> ===================================================================
> RCS file: /cvs/src/usr.bin/ssh/misc.h,v
> retrieving revision 1.86
> diff -u -p -r1.86 misc.h
> --- misc.h    29 May 2020 04:25:40 -0000      1.86
> +++ misc.h    29 May 2020 09:41:48 -0000
> @@ -69,7 +69,7 @@ long         convtime(const char *);
>  const char *fmt_timeframe(time_t t);
>  char *tilde_expand_filename(const char *, uid_t);
>  
> -char *dollar_expand(int *, const char *string);
> +char *dollar_expand(int *, const char *string, ...);
>  char *percent_expand(const char *, ...) __attribute__((__sentinel__));
>  char *percent_dollar_expand(const char *, ...) __attribute__((__sentinel__));
>  char *tohex(const void *, size_t);
> 
> -- 
> Darren Tucker (dtucker at dtucker.net)
> GPG key 11EAA6FA / A86E 3E07 5B19 5880 E860  37F4 9357 ECEF 11EA A6FA (new)
>     Good judgement comes with experience. Unfortunately, the experience
> usually comes from bad judgement.

Reply via email to