Source: lziprecover Version: 1.25~pre1-1 Severity: serious Tags: ftbfs upstream Justification: fails to build from source (but built successfully in the past) X-Debbugs-Cc: debian-ri...@lists.debian.org User: debian-ri...@lists.debian.org Usertags: riscv64
Dear maintainer, lziprecover fails to build on riscv64 with the following error: | riscv64-linux-gnu-g++ -Wdate-time -D_FORTIFY_SOURCE=2 -g -O2 -ffile-prefix-map=/<<PKGBUILDDIR>>=. -fstack-protector-strong -Wformat -Werror=format-security -DPROGVERSION=\"1.25-pre1\" -c -o main.o main.cc | riscv64-linux-gnu-g++ -g -O2 -ffile-prefix-map=/<<PKGBUILDDIR>>=. -fstack-protector-strong -Wformat -Werror=format-security -Wl,-z,relro -o lziprecover arg_parser.o alone_to_lz.o lzip_index.o list.o byte_repair.o dump_remove.o fec_create.o fec_repair.o gf8.o gf16.o lunzcrash.o md5.o merge.o mtester.o nrep_stats.o range_dec.o recursive.o reproduce.o split.o decoder.o main.o -lpthread | main.o: in function `(anonymous namespace)::set_mode((anonymous namespace)::Mode&, (anonymous namespace)::Mode) [clone .part.0]': | /usr/include/riscv64-linux-gnu/bits/stdio2.h:111:(.text+0x8b0): relocation truncated to fit: R_RISCV_PCREL_HI20 against `.LC15' | collect2: error: ld returned 1 exit status | make[1]: *** [Makefile:49: lziprecover] Error 1 | make[1]: Leaving directory '/<<PKGBUILDDIR>>' | dh_auto_build: error: make -j4 returned exit code 2 | make: *** [debian/rules:6: binary-arch] Error 25 | dpkg-buildpackage: error: debian/rules binary-arch subprocess returned exit status 2 | -------------------------------------------------------------------------------- The full build log is available there: https://buildd.debian.org/status/fetch.php?pkg=lziprecover&arch=riscv64&ver=1.25%7Epre1-1&stamp=1728351091&raw=0 After investigation, I have found that this problem occurs when the compiler inlines the newly added compare_prefix() function. This causes an out-of-bound access on a constant. This function is, for instance, called in parse_fec() that way: | else if( compare_prefix( arg, "repair" ) ) | set_mode( program_mode, m_fec_repair ); With the default arguments like in the above calls, compare_prefix() can be simplified as: | // return true if arg is a non-empty prefix of target | bool compare_prefix( const char * const arg, const char * const target) | { | if( arg[0] == target[0] ) | for( int i = 1; i < INT_MAX; ++i ) | { | if( arg[i] == 0 ) return true; | if( arg[i] != target[i] ) break; | } | return false; | } As you can see if the length of the arg string is longer than the target string, the latter is accessed out-of-bounds, possibly up to INT_MAX. Probably INT_MAX should be replaced by "strlen(target) + 1". Regards Aurelien