Hi,

On 20/06/17 14:29, Adrian Bunk wrote:
> Source: miller
> Version: 5.2.0-1
> Severity: serious
> 
> https://buildd.debian.org/status/package.php?p=miller&suite=sid
> 
> ...
> Tests completed: 2713
> FAIL run (exit status: 1)
[...]
> The same build failure on powerpc is an indication that it
> could be a 32bit big endian problem.

This error comes from the substr test in miller's testsuite:
> announce DSL SUBSTR
> 
> run_mlr put -q '
>   int n = strlen($x);
>   print "input= <<".$x.">>";
>   for (i = -n-2; i <= n+2; i += 1) {
>     for (j = -n-2; j <= n+2; j += 1) {
>       print "i: ".fmtnum(i,"%3d")
>         ."   j:".fmtnum(j,"%3d")
>         ."   substr(".$x.",".fmtnum(i,"%3d").",".fmtnum(j,"%3d")."): <<"
>         .substr($x, i, j) .">>";
>     }
>     print;
> }
> ' << EOF
> x=
> x=o
> x=o1
> x=o123456789
> EOF

When "fmtnum(i, "%3d")" is called, control eventually gets to this
function in c/lib/mlrutil.c:
> char* mlr_alloc_string_from_ll_and_format(long long value, char* fmt) {
>       int n = snprintf(NULL, 0, fmt, value);
>       char* string = mlr_malloc_or_die(n+1);
>       sprintf(string, fmt, value);
>       return string;
> }

The arguments are:
value = integer in i
fmt = "%3d"

The function will call snprintf "%3d" on a long long value which invokes
undefined behavior (from size integer for given format). The incorrect
result is then returned.

Only mips and powerpc are affected because: their ABI distinguishes
between passing "int" and "long long" (because they are 32-bit), and
they are big endian so the "wrong" part of the integer gets read by
sprintf. The result is always "-1" or "0" because it will read the
sign-extended part.

Thanks,
James

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to