Subject: obscure bug "extern void free (void *__ptr) __attribute__
((__nothrow__ , __leaf__));"
Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -march=x86-64 -mtune=generic -O2 -pipe -fno-plt
-DDEFAULT_PATH_VALUE='/usr/local/sbin:/usr/local/bin:/usr/bin'
-DSTANDARD_UTILS_PATH='/usr/bin' -DSYS_BASHRC='/etc/bash.bashrc'
-DSYS_BASH_LOGOUT='/etc/bash.bash_logout' -DNON_INTERACTIVE_LOGIN_SHELLS
uname output: Linux C1MPAQ 5.10.7-arch1-1 #1 SMP PREEMPT Wed, 13 Jan
2021 12:02:01 + x86_64 GNU/Linux
Machine Type: x86_64-pc-linux-gnu
Bash Version: 5.1 (Archlinux: core/bash 5.1.004-1)
Patch Level: 4
Release Status: release
Description:
An Autoconf configure script from Libreelec does fail, because some file
it generated does unexpectedly contain output from some command it
called in an if-statement that had output directed to >& /dev/null .
Various alterations to the script do produce strange outcomes. Sometimes
it avoids the bug, sometimes it will result in the line "extern void
free (void *__ptr) __attribute__ ((__nothrow__ , __leaf__));" to be
inserted into the file in addition to the behavior. See "Repeat-By" for
more details.
A great mystery is the origin of the line "extern void free ...". A grep
on the Libreelec files doesn't return anything. I could only find it in
/usr/include/ruby-2.7.0/x86_64-linux/rb_mjit_min_header-2.7.2.h . But
then removing that file still resulted in the the line being wrongfully
inserted.
In bash-5.0.018-2 the bug does not appear.
I already reported this to bug-b...@gnu.org , but I was advised that
this bug should be handled by autoconf.
It looks to me like a pointer overflow, which causes bash to write to
the wrong buffer.
Strace: https://filebin.net/9auqyreezma08z12/bug_bash.tar.gz?t=3bjx4xpd
Repeat-By:
git clone https://github.com/LibreELEC/LibreELEC.tv #
0582177d5eb0ec37d88dfa197908d3b03d047863
cd LibreELEC.tv
ARCH=aarch64 PROJECT=Amlogic DEVICE=AMLGX ./scripts/build linux
-> the build fails after a minute at package "ccache" in the
Autoconfig step due to wrongful insertion of silenced command output
into file config.status at line 533
In: build.LibreELEC-AMLGX.aarch64-9.80-devel/build/ccache-3.7.12/configure
Go to line 6532: if diff "$cache_file" confcache >/dev/null 2>&1; then
:; else
Hint: $cache_file is always /dev/null , hence the if-statement will
evaluate false
This diff command is the source of the insertion in
build.LibreELEC-AMLGX.aarch64-9.80-devel/build/ccache-3.7.12/config.status
:
0a1,97:
> # This file is a shell script that caches the results of
configure
> # tests run on this system so they can be shared between
configure
...
Remove the line and the corresponding "fi" that closes the if-statement
-> script inserts "extern void free ..." instead into
./config.status at line 533
Replace line with: if diff "$cache_file" confcache >& /tmp/nothing; then
:; else
-> script inserts not only "extern void free ..." in config.status,
but also the following into /tmp/nothing at the top in addition to the
output:
1c1,97
< extern void free (void *__ptr) __attribute__ ((__nothrow__ ,
__leaf__));
---
> # This file is a shell script that caches the results of
configure
...
Replace line with if cat /tmp/nothing >& /dev/null; then :; else
-> script inserts content of /tmp/nothing into ./config.status at
line 533
Replace line with if false; then :; else # or some other random command,
like "ls >& /dev/null"
-> script works
Content of /tmp/nothing (all characters are exact part of the file):
1c1,97
< extern void free (void *__ptr) __attribute__ ((__nothrow__ , __leaf__));
---
> # This file is a shell script that caches the results of configure
> # tests run on this system so they can be shared between configure
> # scripts and configure runs, see configure's option --config-cache.
> # It is not useful on other systems. If it contains results you don't
> # want to keep, you may remove or edit it.
> #
> # config.status only pays attention to the cache file if you give it
> # the --recheck option to rerun configure.
> #
> # `ac_cv_env_foo' variables (set or unset) will be overridden when
> # loading this file, other *unset* `ac_cv_foo' will be assigned the
> # following values.
>
> ac_cv_build=${ac_cv_build=x86_64-pc-linux-gnu}
> ac_cv_c_bigendian=${ac_cv_c_bigendian=no}
> ac_cv_c_compiler_clang=${ac_cv_c_compiler_clang=no}
> ac_cv_c_compiler_gnu=${ac_cv_c_compiler_gnu=yes}
> ac_cv_c_extern_inline=${ac_cv_c_extern_inline=no}
> ac_cv_c_inline=${ac_cv_c_inline=inline}
> ac_cv_env_CC_set=set
> ac_cv_env_CC_value=/bin/gcc
> ac_cv_env_CFLAGS_set=set
> ac_cv_env_CFLAGS_value='-march=native -O2 -Wall -pipe
-I/home/l0rd/LibreELEC.tv/build.LibreELEC-AMLGX.aarch64-9.80-devel/toolchain/include
-Wno-format-security'
> ac_cv_env_CPPFLAGS_set=set
> a