Control: tag -1 + pending Hi,
TL;DR: The in-sbin-confusion-in-elf test in Lintian's test suite is broken beyond repair: Lintian's arm64 result (which failed the test) is actually the correct result, and the amd64 result (which passed the test) is wrong due false negatives which lintian has no chance to find. The cause are very likely different per-architecture compile time string optimizations. So I will remove the test in-sbin-confusion-in-elf from the test suite. The tag bin-sbin-mismatch can't be tested on C-compiled binaries properly if compile-time string optimizations are in use. Long story including steps to get to that conclusion: I've now digged into the second of these test suite failures on arm64 as I could neither reproduce it on armhf nor i386 (which were easier available to me as I have Sid boxes with these architectures permanently running). And on arm64 I can indeed reproduce it. And it is much more weird than I expected: Paul Gevers wrote: > # Hints do not match > # > # --- > ../../autopkgtest_tmp/build-and-evaluate-test-packages/eval/checks/files/contents/bin-sbin-confusion-in-elf/hints.specified.calibrated > # +++ > ../../autopkgtest_tmp/build-and-evaluate-test-packages/eval/checks/files/contents/bin-sbin-confusion-in-elf/hints.actual.parsed > # +bin-sbin-confusion-in-elf (binary): bin-sbin-mismatch sbin/our-script -> > usr/bin/our-script [usr/bin/calls-sbin] > # +bin-sbin-confusion-in-elf (binary): bin-sbin-mismatch bin/our-script -> > usr/bin/our-script [usr/bin/calls-sbin] > # > # Failed test 'Lintian passes for bin-sbin-confusion-in-elf' > # at /usr/share/lintian/lib/Test/Lintian/Run.pm line 343. > # Looks like you failed 1 test of 1. > ../../autopkgtest_tmp/build-and-evaluate-test-packages/eval/checks/files/contents/bin-sbin-confusion-in-elf/generic.t > ........................................................ > Still need to figure out where the issue with bin-sbin-mismatch. But > that tag is known (at least to me) for weird false positives. The tag's implementation is not the cause. This seems not a direct bug in Lintian. So Lintian's test suite has a sample C program calls-sbin.c which the test suite expects to trigger once. Here's the source code: ---8<--- #include <stdio.h> #include <string.h> /* may not work as expected on ELF due to ld's SHF_MERGE */ #define BIN_PATH "/bin/our-script" #define SBIN_PATH "/sbin/our-script" #define USR_BIN_PATH "/usr/bin/our-script" #define USR_SBIN_PATH "/usr/sbin/our-script" int main(void) { printf("Calling %s\n", BIN_PATH); printf("Calling %s\n", SBIN_PATH); printf("Calling %s\n", USR_BIN_PATH); printf("Calling %s\n", USR_SBIN_PATH); return 0; } --->8--- Both files, our-script and calls-sbin are only installed into /usr/bin/. So how often should this tag trigger then? Once? Twice? Thrice? The test suite thinks only once which I find confusing. I'd expected at least twice. But the expected emitted tags by the test suite are: bin-sbin-confusion-in-elf (binary): bin-sbin-mismatch usr/sbin/our-script -> usr/bin/our-script [usr/bin/calls-sbin] On arm64 these three tags are emitted: bin-sbin-confusion-in-elf (binary): bin-sbin-mismatch usr/sbin/our-script -> usr/bin/our-script [usr/bin/calls-sbin] bin-sbin-confusion-in-elf (binary): bin-sbin-mismatch sbin/our-script -> usr/bin/our-script [usr/bin/calls-sbin] bin-sbin-confusion-in-elf (binary): bin-sbin-mismatch bin/our-script -> usr/bin/our-script [usr/bin/calls-sbin] Which is more what I would have expected on amd64 as well. So far for the basic confusion. Now to the more weird thing. Not weird is IMHO that these four paths from the source are all in the arm64 binary of calls-sbin: [arm64] $ strings ./debian/test-out/packages/checks/files/contents/bin-sbin-confusion-in-elf/bin-sbin-confusion-in-elf-1.0/debian/bin-sbin-confusion-in-elf/usr/bin/calls-sbin | fgrep bin /bin/our-script /sbin/our-script /usr/bin/our-script /usr/sbin/our-script But in the amd64 binary, there are only two of them, with one being the correct one: [amd64] $ strings ./debian/test-out/packages/checks/files/contents/bin-sbin-confusion-in-elf/bin-sbin-confusion-in-elf-1.0/debian/bin-sbin-confusion-in-elf/usr/bin/calls-sbin | fgrep bin /usr/bin/our-script /usr/sbin/our-script This fits with the test suite only expecting this tag to be emitted. But then again, the output of both architectures is the same: [arm64] $ ./debian/test-out/packages/checks/files/contents/bin-sbin-confusion-in-elf/bin-sbin-confusion-in-elf-1.0/debian/bin-sbin-confusion-in-elf/usr/bin/calls-sbin Calling /bin/our-script Calling /sbin/our-script Calling /usr/bin/our-script Calling /usr/sbin/our-script [amd64] $ ./debian/test-out/packages/checks/files/contents/bin-sbin-confusion-in-elf/bin-sbin-confusion-in-elf-1.0/debian/bin-sbin-confusion-in-elf/usr/bin/calls-sbin Calling /bin/our-script Calling /sbin/our-script Calling /usr/bin/our-script Calling /usr/sbin/our-script So the more weird thing is: I think the current test is wrong and the tag should be emitted three times. But reason for this is not lintian but the C compiler on amd64. (And in some way the developer who didn't question the IMHO unexpected outcome and committed what he got into the test suite.) The diff between those two outputs of "strings" (amd64 first, arm64 second) are: c1 < /lib64/ld-linux-x86-64.so.2 --- > /lib/ld-linux-aarch64.so.1 4a5 > abort 6,7c7 < GLIBC_2.2.5 < GLIBC_2.3.4 --- > GLIBC_2.17 12,13c12,14 < PTE1 < u+UH --- > RB@! > `B@9@ > /bin/our-script 14a16 > /sbin/our-script 17,18c19 < ;*3$" < 4032d603fcdab9b3c37bd8c1c7d5883bc724dd.debug --- > d2b24ab8a4b9b4c8f515cf5be93d20e5f55443.debug 21d21 < .note.gnu.property 32d31 < .plt.got 40a40 > .got So only two these strings are in the amd64 binary. Using ltrace (not available for arm64) I got an idea what might have happened here, just why not on arm64 (but also on armhf): $ ltrace ./debian/test-out/packages/checks/files/contents/bin-sbin-confusion-in-elf/bin-sbin-confusion-in-elf-1.0/debian/bin-sbin-confusion-in-elf/usr/bin/calls-sbin __printf_chk(1, 0x55e617f8e004, 0x55e617f8e014, 0x55e617f8fdc0Calling /bin/our-script ) = 24 __printf_chk(1, 0x55e617f8e004, 0x55e617f8e028, 0Calling /sbin/our-script ) = 25 __printf_chk(1, 0x55e617f8e004, 0x55e617f8e010, 0Calling /usr/bin/our-script ) = 28 __printf_chk(1, 0x55e617f8e004, 0x55e617f8e024, 0Calling /usr/sbin/our-script ) = 29 +++ exited (status 0) +++ So looking at the second hex column, the memory addresses of 1st and 3rd row as well as 2nd and 4th row only differ by 4 bytes. Which means that the compiler figured out that two of the constants are substrings of the other two constants and optimized them out. I also remember that Debian (or GCC) has different default compile time optimization settings per architecture. So it seems that these substrings get eliminated by jumping directly into one of the other strings at character position 4. Hence it is impossible for lintian to find the other two string occurences. Accordingly this specific test (bin-sbin-confusion-in-elf, whose expected result obviously was just taken unreflected from Lintian's output of the amd64 test binary) is broken beyond repair as it depends on architecture-specific compile time optimization settings (here: string constants optimization) being applied. And I don't want to write some heavy obfuscation stuff just so that the compiler can't optimize it. So from my point of view, the test in-sbin-confusion-in-elf needs to be removed from the test suite. Will do after this mail. This will also fix the second part of this bug report. (And now I'd like to go back to other Lintian issues which don't consume hours of debugging time first. Or just do an upload and fix remaining issues later. :-) Regards, Axel -- ,''`. | Axel Beckert <a...@debian.org>, https://people.debian.org/~abe/ : :' : | Debian Developer, ftp.ch.debian.org Admin `. `' | 4096R: 2517 B724 C5F6 CA99 5329 6E61 2FF9 CD59 6126 16B5 `- | 1024D: F067 EA27 26B9 C3FC 1486 202E C09E 1D89 9593 0EDE