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.