[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1025868: lintian autopkgtest fails on all but amd64: x86_64-linux-gnu expected build-and-evaluate-test-packages/eval/checks/desktop/gnome/gir/gir/generic.t



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 <abe@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


Reply to: