Bug 2013694 - stack-realign test always fails on i686
Summary: stack-realign test always fails on i686
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Fedora
Classification: Fedora
Component: annobin
Version: 36
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Nick Clifton
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2021-10-13 14:34 UTC by Petr Pisar
Modified: 2023-04-26 09:48 UTC (History)
7 users (show)

Fixed In Version: annobin-10.16-1.fc36
Clone Of:
Environment:
Last Closed: 2023-04-26 09:48:53 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)
i686 object file (10.23 KB, application/octet-stream)
2021-10-14 12:16 UTC, Petr Pisar
no flags Details
i686 ELF (15.83 KB, application/octet-stream)
2021-10-14 12:18 UTC, Petr Pisar
no flags Details
gcc -shared -Wl,-z,now -m32 -mstackrealign -flto=auto -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 /tmp/test.o -o /tmp/out (18.17 KB, application/octet-stream)
2021-10-15 11:46 UTC, Petr Pisar
no flags Details
Proposed patch (786 bytes, patch)
2021-10-18 15:45 UTC, Nick Clifton
no flags Details | Diff
Proposed patch (1.11 KB, patch)
2021-10-18 15:45 UTC, Nick Clifton
no flags Details | Diff
Proposed patch (608 bytes, patch)
2021-10-19 11:41 UTC, Nick Clifton
no flags Details | Diff
Proposed patch (2.29 KB, patch)
2021-10-19 11:41 UTC, Nick Clifton
no flags Details | Diff

Description Petr Pisar 2021-10-13 14:34:33 UTC
Since annobin 10.09, stack-realign check always fails. Discovered on libgcrypt-1.9.4-1.fc36's i686 libgcrypt.so.20.3.3 library. I reduced the reproducer to:

# cat > /tmp/test.c
int foo(void) { return 42; }

I built it the same way as any of the libgcrypt object files:

# gcc -DHAVE_CONFIG_H -I. -I.. -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m32 -march=i686 -mtune=generic -msse2 -mfpmath=sse -mstackrealign -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -fvisibility=hidden -fno-delete-null-pointer-checks -Wall -c /tmp/test.c  -fPIC -DPIC -o /tmp/test.o

Then I linked it to a DSO:

# gcc -shared -Wl,-z,now -m32 -mstackrealign /tmp/test.o -o /tmp/out

And run annocheck:

# annocheck /tmp/out
annocheck: Version 10.13.
Hardened: out: FAIL: stack-realign test because stack realign support is mandatory
Hardened: Rerun annocheck with --verbose to see more information on the tests.
Hardened: out: Overall: FAIL.

Affected package: annobin-annocheck-10.13-1.fc36.i686. (10.15 is also affected.)

Comment 1 Nick Clifton 2021-10-14 10:32:15 UTC
Hi Petr,

  Please could you upload the test.o binary ?  (I am having trouble reproducing this problem...)

Cheers
  Nick

Comment 2 Nick Clifton 2021-10-14 10:32:55 UTC
Oh - and the "test" binary too please

Comment 3 Nick Clifton 2021-10-14 10:33:24 UTC
s/test/out/

(I need more coffee)

Comment 4 Nick Clifton 2021-10-14 10:40:18 UTC
Also - please could you try annobin 10.15 (now in rawhide).  I think that you might get a better result.

Comment 5 Petr Pisar 2021-10-14 12:16:19 UTC
Created attachment 1832925 [details]
i686 object file

Comment 6 Petr Pisar 2021-10-14 12:18:12 UTC
Created attachment 1832926 [details]
i686 ELF

Comment 7 Petr Pisar 2021-10-14 12:39:56 UTC
10.15 is also affected.

Comment 8 Petr Pisar 2021-10-14 12:59:44 UTC
Shorter compiler options:

# printf 'int foo(void) { return 42; }\n' | gcc -x c -g -m32 -fPIC -shared -mstackrealign - -o /tmp/out && annocheck /tmp/out
annocheck: Version 10.15.
Hardened: out: FAIL: bind-now test because not linked with -Wl,-z,now 
Hardened: out: FAIL: cf-protection test because .note.gnu.property section did not contain the necessary flags 
Hardened: out: FAIL: stack-realign test because stack realign support is mandatory 
Hardened: Rerun annocheck with --verbose to see more information on the tests.
Hardened: out: Overall: FAIL.

Comment 9 Nick Clifton 2021-10-14 14:07:53 UTC
(In reply to Petr Pisar from comment #8)
> Shorter compiler options:
> # printf 'int foo(void) { return 42; }\n' | gcc -x c -g -m32 -fPIC -shared
> -mstackrealign - -o /tmp/out && annocheck /tmp/out

Ah - but you are not running the annobin plugin, so there is nothing to record the fact that the -mstackrealign option was used.
Does this work:

  printf 'int foo(void) { return 42; }\n' | gcc -x c -g -m32 -fPIC -shared \
  -mstackrealign -fplugin=annobin - -o /tmp/out && annocheck /tmp/out


Note - I think that this might also be the problem with libgcrypt.  Looking at the build log:

  https://kojipkgs.fedoraproject.org//packages/libgcrypt/1.9.4/1.fc36/data/logs/i686/build.log

I see that the final link command line for libgcrypt.so.20.3.4 looks like this:

  libtool: link: gcc -shared  -fPIC -DPIC  .libs/libgcrypt_la-visibility.o .libs/libgcrypt_la-misc.o .libs/libgcrypt_la-global.o .libs/libgcrypt_la-sexp.o .libs/libgcrypt_la-hwfeatures.o .libs/libgcrypt_la-stdmem.o .libs/libgcrypt_la-secmem.o .libs/libgcrypt_la-missing-string.o .libs/libgcrypt_la-fips.o .libs/libgcrypt_la-hmac256.o .libs/libgcrypt_la-context.o .libs/libgcrypt_la-hwf-x86.o  -Wl,--whole-archive ../cipher/.libs/libcipher.a ../random/.libs/librandom.a ../mpi/.libs/libmpi.a ../compat/.libs/libcompat.a -Wl,--no-whole-archive  -lgpg-error -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -O2 -flto=auto -m32 -march=i686 -mtune=generic -msse2 -mfpmath=sse -mstackrealign -Wl,--version-script=./libgcrypt.vers -Wl,-z -Wl,relro -Wl,--as-needed -Wl,-z -Wl,now   -Wl,-soname -Wl,libgcrypt.so.20 -o .libs/libgcrypt.so.20.3.4

Note how "-specs=/usr/lib/rpm/redhat/redhat-annobin-cc" is missing.  This matters because
this is an LTO link, which means that the compiler gets run again, which in turn means that
the annobin plugin is needed if you want to record build notes for annocheck to examine.

Strangely, it does appear that the LDFLAGS environment variable is being set correctly:

  + LDFLAGS='-Wl,-z,relro -Wl,--as-needed  -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat /redhat-annobin-cc1 '
  + export LDFLAGS

So presumably that libtool link is not using LDLFLAGS...

Comment 10 Petr Pisar 2021-10-14 15:10:37 UTC
(In reply to Nick Clifton from comment #9)
> (In reply to Petr Pisar from comment #8)
> > Shorter compiler options:
> > # printf 'int foo(void) { return 42; }\n' | gcc -x c -g -m32 -fPIC -shared
> > -mstackrealign - -o /tmp/out && annocheck /tmp/out
> 
> Ah - but you are not running the annobin plugin, so there is nothing to
> record the fact that the -mstackrealign option was used.
> Does this work:
> 
>   printf 'int foo(void) { return 42; }\n' | gcc -x c -g -m32 -fPIC -shared \
>   -mstackrealign -fplugin=annobin - -o /tmp/out && annocheck /tmp/out
>
You are right. This works. I didn't realized that stack realignment is checked from annotations.
 
> Note - I think that this might also be the problem with libgcrypt.  Looking
> at the build log:
> 
>  
> https://kojipkgs.fedoraproject.org//packages/libgcrypt/1.9.4/1.fc36/data/
> logs/i686/build.log
> 
> I see that the final link command line for libgcrypt.so.20.3.4 looks like
> this:
> 
>   libtool: link: gcc -shared  -fPIC -DPIC  .libs/libgcrypt_la-visibility.o
> .libs/libgcrypt_la-misc.o .libs/libgcrypt_la-global.o
> .libs/libgcrypt_la-sexp.o .libs/libgcrypt_la-hwfeatures.o
> .libs/libgcrypt_la-stdmem.o .libs/libgcrypt_la-secmem.o
> .libs/libgcrypt_la-missing-string.o .libs/libgcrypt_la-fips.o
> .libs/libgcrypt_la-hmac256.o .libs/libgcrypt_la-context.o
> .libs/libgcrypt_la-hwf-x86.o  -Wl,--whole-archive
> ../cipher/.libs/libcipher.a ../random/.libs/librandom.a
> ../mpi/.libs/libmpi.a ../compat/.libs/libcompat.a -Wl,--no-whole-archive 
> -lgpg-error -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -O2
> -flto=auto -m32 -march=i686 -mtune=generic -msse2 -mfpmath=sse
> -mstackrealign -Wl,--version-script=./libgcrypt.vers -Wl,-z -Wl,relro
> -Wl,--as-needed -Wl,-z -Wl,now   -Wl,-soname -Wl,libgcrypt.so.20 -o
> .libs/libgcrypt.so.20.3.4
> 
> Note how "-specs=/usr/lib/rpm/redhat/redhat-annobin-cc" is missing.  This
> matters because
> this is an LTO link, which means that the compiler gets run again, which in
> turn means that
> the annobin plugin is needed if you want to record build notes for annocheck
> to examine.
> 
Shouldn't LTO link reuse compiler flags recorded when compiling the object files for the first time? -specs=...redhat-annobin-cc1 was used when compiling the objects.

Strangely when I add the annobin option to the linker command from my original reproduced in comment #0, it won't help:

# gcc -shared -Wl,-z,now -m32 -mstackrealign -flto=auto  -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 /tmp/test.o -o /tmp/out
<mock-chroot> sh-5.1# gcc -DHAVE_CONFIG_H -I. -I.. -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m32 -march=i686 -mtune=generic -msse2 -mfpmath=sse -mstackrealign -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -fvisibility=hidden -fno-delete-null-pointer-checks -Wall -c /tmp/test.c  -fPIC -DPIC -o /tmp/test.o
# gcc -shared -Wl,-z,now -m32 -mstackrealign -flto=auto  -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 /tmp/test.o -o /tmp/out
# annocheck /tmp/out 
annocheck: Version 10.15.
Hardened: out: FAIL: stack-realign test because stack realign support is mandatory 
Hardened: Rerun annocheck with --verbose to see more information on the tests.
Hardened: out: Overall: FAIL.

Did I missed another options to the linker command?
Adding the -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 option to the libgcrypt linker command does not help for me.

> Strangely, it does appear that the LDFLAGS environment variable is being set
> correctly:
> 
>   + LDFLAGS='-Wl,-z,relro -Wl,--as-needed  -Wl,-z,now
> -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat
> /redhat-annobin-cc1 '
>   + export LDFLAGS
> 
> So presumably that libtool link is not using LDLFLAGS...

I observe similar issue in Perl packages. E.g. <https://kojipkgs.fedoraproject.org//packages/perl-Graphics-TIFF/17/1.fc36/data/logs/i686/build.log> does not mention annobin in a linker command (TIFF.so). Perl packages do not use environment variables. They use flags from perl interpreter. Has the annobin option been added to LDFLAGS recently (i.e. after the last perl build, 2021-07-23)?

Comment 11 Nick Clifton 2021-10-14 19:06:56 UTC
(In reply to Petr Pisar from comment #10)
Hi Petr,

> Shouldn't LTO link reuse compiler flags recorded when compiling the object
> files for the first time? -specs=...redhat-annobin-cc1 was used when
> compiling the objects.

You would think so, but no, it does not. :-(  Actually that is not quite true,
there are a few special cases where certain flags are (effectively) recorded,
but -mstackrealign is not one of them.


> # gcc -shared -Wl,-z,now -m32 -mstackrealign -flto=auto 
> -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 /tmp/test.o -o /tmp/out
> # annocheck /tmp/out 
> annocheck: Version 10.15.
> Hardened: out: FAIL: stack-realign test because stack realign support is
> mandatory 

Hmm, OK, that is puzzling.
Could you upload this second "out" file for me to examine please ?

> Did I missed another options to the linker command?

No, it looks right to me.

> > So presumably that libtool link is not using LDFLAGS...
> 
> I observe similar issue in Perl packages. E.g.
> <https://kojipkgs.fedoraproject.org//packages/perl-Graphics-TIFF/17/1.fc36/
> data/logs/i686/build.log> does not mention annobin in a linker command
> (TIFF.so). Perl packages do not use environment variables. They use flags
> from perl interpreter. Has the annobin option been added to LDFLAGS recently
> (i.e. after the last perl build, 2021-07-23)?

Probably.  This is all handled by code in the /usr/lib/rpm/redhat/macros
file (part of the redhat-rpm-config package), and in theory should work for
most packages.  At least those that use the rpm build macros.

Cheers
  Nick

Comment 12 Petr Pisar 2021-10-15 11:46:47 UTC
Created attachment 1833384 [details]
gcc -shared -Wl,-z,now -m32 -mstackrealign -flto=auto -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 /tmp/test.o -o /tmp/out

> > # gcc -shared -Wl,-z,now -m32 -mstackrealign -flto=auto 
> > -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 /tmp/test.o -o /tmp/out
> > # annocheck /tmp/out 
> > annocheck: Version 10.15.
> > Hardened: out: FAIL: stack-realign test because stack realign support is
> > mandatory 

> Hmm, OK, that is puzzling.
> Could you upload this second "out" file for me to examine please ?

Comment 13 Petr Pisar 2021-10-15 12:54:06 UTC
stack-realign failure is triggered by adding -fvisibility=hidden:

# printf 'int foo(void) { return 42; }\n' |  gcc -x c -O2 -flto=auto -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m32 -mstackrealign -fvisibility=hidden -fPIC -DPIC -c - -o /tmp/test.o && gcc -shared -m32 -mstackrealign -flto=auto -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 /tmp/test.o -o /tmp/out && annocheck /tmp/out
<stdin>: warning: -D_FORTIFY_SOURCE not defined
annobin: -: Warning: -D_GLIBCXX_ASSERTIONS not defined
annocheck: Version 10.15.
Hardened: out: FAIL: bind-now test because not linked with -Wl,-z,now 
Hardened: out: FAIL: cf-protection test because .note.gnu.property section did not contain the necessary flags 
Hardened: out: FAIL: stack-realign test because stack realign support is mandatory 
Hardened: Rerun annocheck with --verbose to see more information on the tests.
Hardened: out: Overall: FAIL.

# printf 'int foo(void) { return 42; }\n' |  gcc -x c -O2 -flto=auto -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m32 -mstackrealign -fPIC -DPIC -c - -o /tmp/test.o && gcc -shared -m32 -mstackrealign -flto=auto -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 /tmp/test.o -o /tmp/out && annocheck /tmp/out
<stdin>: warning: -D_FORTIFY_SOURCE not defined
annobin: -: Warning: -D_GLIBCXX_ASSERTIONS not defined
annocheck: Version 10.15.
Hardened: out: FAIL: bind-now test because not linked with -Wl,-z,now 
Hardened: out: FAIL: stack-prot test because stack protection deliberately disabled 
Hardened: out: FAIL: stack-clash test because -fstack-clash-protection not enabled 
Hardened: out: FAIL: cf-protection test because no protection enabled 
Hardened: Rerun annocheck with --verbose to see more information on the tests.
Hardened: out: Overall: FAIL.

In case of -fvisible=hidden, the foo() function is completely optimized out. Disassembling confirms it and the only 16-byte unaligned symbol kept is:

00001149 <__x86.get_pc_thunk.dx>:
    1149:       8b 14 24                mov    (%esp),%edx
    114c:       c3                      ret

But that one is unaligned in both cases. Maybe annobin misses the optimized-out symbol and misinterprets it as a failure.

Comment 14 Petr Pisar 2021-10-18 11:32:48 UTC
(In reply to Nick Clifton from comment #11)
> (In reply to Petr Pisar from comment #10)
> > I observe similar issue in Perl packages. E.g.
> > <https://kojipkgs.fedoraproject.org//packages/perl-Graphics-TIFF/17/1.fc36/
> > data/logs/i686/build.log> does not mention annobin in a linker command
> > (TIFF.so). Perl packages do not use environment variables. They use flags
> > from perl interpreter. Has the annobin option been added to LDFLAGS recently
> > (i.e. after the last perl build, 2021-07-23)?
> 
> Probably.  This is all handled by code in the /usr/lib/rpm/redhat/macros
> file (part of the redhat-rpm-config package), and in theory should work for
> most packages.  At least those that use the rpm build macros.
> 
I tracked the addition of the annobin flag in redhat-rpm-config to "Active GCC plugin during LTO linking" commit on 2021-08-02. I'm now rebuilding perl in Fedora ≥ 35 to utilize the flag. I locally verified that it fixes annocheck test for i686 Perl packages.

Comment 15 Nick Clifton 2021-10-18 12:49:18 UTC
(In reply to Petr Pisar from comment #13)
> stack-realign failure is triggered by adding -fvisibility=hidden:

Ah...

> In case of -fvisible=hidden, the foo() function is completely optimized out.

> Maybe annobin misses the optimized-out symbol 

Well yes, since the symbol is not present in the symbol table.


> and misinterprets it as a failure.

Well it is also connected to the fact that the code has been optimized away as well, but essentially you are correct.

 
> I locally verified that it fixes annocheck test for i686 Perl packages.

Good.  In which case do you mind if I CLOSE/DUPLICATE this BZ as it is essentially the same as #2013658.

Comment 16 Petr Pisar 2021-10-18 13:05:16 UTC
I don't mind. I'm only not sure whether it's good service for Fedora users pointing to a private RHEL bug.

Comment 17 Nick Clifton 2021-10-18 13:28:11 UTC
(In reply to Petr Pisar from comment #16)
> I don't mind. I'm only not sure whether it's good service for Fedora users
> pointing to a private RHEL bug.

Ah, fair enough.  In which case lets leave this BZ open.

The fix should be in annobin-10.16-1.fc36

Comment 18 Petr Pisar 2021-10-18 15:18:00 UTC
Thanks. I confirm that annobin-10.16-2.fc36.i686 does not report the stack-realign failure on the test case with hidden visibility as well as on the libgcrypt build. The only error it reports now is:

Hardened: ../BUILD/libgcrypt-1.9.4/src/.libs/libgcrypt.so.20.3.4: gap:  (0x8000..0xa4b30 probable component: parse_version_number) in annobin notes.
Hardened: ../BUILD/libgcrypt-1.9.4/src/.libs/libgcrypt.so.20.3.4: FAIL: notes test because gaps were detected in the annobin coverage

The range covers parse_version_number, parse_version_string, and write2stderr functions. Their object files src/global.c and src/misc.c are built with -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1. But as you pointed, linker command is missing the annobin flag. That's maybe a bug in libtool. However, a similar bug #1961686 was rejected by libtool.

Comment 19 Nick Clifton 2021-10-18 15:45:22 UTC
Created attachment 1834292 [details]
Proposed patch

Comment 20 Nick Clifton 2021-10-18 15:45:49 UTC
Created attachment 1834293 [details]
Proposed patch

Comment 21 Nick Clifton 2021-10-18 15:55:19 UTC
Hi Petr,

  Does the uploaded patch to the libgcrypt.spec file work ?
  It is just a guess...

Cheers
  Nick

Comment 22 Petr Pisar 2021-10-19 08:31:06 UTC
That does not help. Now the annobin flag is passed to libtool three times, but libtool deletes all of them:

/bin/sh ../libtool  --tag=CC   --mode=link gcc  -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -m64  -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -fvisibility=hidden -fno-delete-null-pointer-checks -Wall    `rpm --eval %build_ldflags` -Wl,--version-script=./libgcrypt.vers -version-info 23:4:3 -Wl,-z,relro -Wl,--as-needed  -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -m64  -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -o libgcrypt.la -rpath /usr/lib64 libgcrypt_la-visibility.lo libgcrypt_la-misc.lo libgcrypt_la-global.lo libgcrypt_la-sexp.lo libgcrypt_la-hwfeatures.lo libgcrypt_la-stdmem.lo libgcrypt_la-secmem.lo libgcrypt_la-missing-string.lo libgcrypt_la-fips.lo libgcrypt_la-hmac256.lo libgcrypt_la-context.lo  libgcrypt_la-hwf-x86.lo ../cipher/libcipher.la ../random/librandom.la ../mpi/libmpi.la ../compat/libcompat.la  -lgpg-error 
libtool: link: gcc -shared  -fPIC -DPIC  .libs/libgcrypt_la-visibility.o .libs/libgcrypt_la-misc.o .libs/libgcrypt_la-global.o .libs/libgcrypt_la-sexp.o .libs/libgcrypt_la-hwfeatures.o .libs/libgcrypt_la-stdmem.o .libs/libgcrypt_la-secmem.o .libs/libgcrypt_la-missing-string.o .libs/libgcrypt_la-fips.o .libs/libgcrypt_la-hmac256.o .libs/libgcrypt_la-context.o .libs/libgcrypt_la-hwf-x86.o  -Wl,--whole-archive ../cipher/.libs/libcipher.a ../random/.libs/librandom.a ../mpi/.libs/libmpi.a ../compat/.libs/libcompat.a -Wl,--no-whole-archive  -lgpg-error -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -O2 -flto=auto -m64 -mtune=generic -Wl,-z -Wl,relro -Wl,--as-needed -Wl,-z -Wl,now -Wl,--version-script=./libgcrypt.vers -Wl,-z -Wl,relro -Wl,--as-needed -Wl,-z -Wl,now -O2 -flto=auto -m64 -mtune=generic   -Wl,-soname -Wl,libgcrypt.so.20 -o .libs/libgcrypt.so.20.3.4

But the way, this gap is reported for x86_64 build either:

$ annocheck --verbose libgcrypt-1.9.4/src/.libs/libgcrypt.so.20.3.4 
annocheck: Version 10.17.
[...]
Hardened: libgcrypt-1.9.4/src/.libs/libgcrypt.so.20.3.4: gap:  (0xefc0..0xf3e40 probable component: parse_version_string) in annobin notes.
Hardened: libgcrypt-1.9.4/src/.libs/libgcrypt.so.20.3.4: FAIL: notes test because gaps were detected in the annobin coverage 

Strange thing is that 0xefc0 points in the middle of an instruction:

000000000000efb0 <parse_version_number>:
    efb0:       41 54                   push   %r12
    efb2:       49 89 f4                mov    %rsi,%r12
    efb5:       55                      push   %rbp
    efb6:       48 89 fd                mov    %rdi,%rbp
    efb9:       53                      push   %rbx
    efba:       0f be 1f                movsbl (%rdi),%ebx
→   efbd:       e8 be fb ff ff          call   eb80 <__ctype_b_loc@plt>
    efc2:       48 8b 30                mov    (%rax),%rsi
    efc5:       80 fb 30                cmp    $0x30,%bl
    efc8:       74 36                   je     f000 <parse_version_number+0x50>
    efca:       48 89 e8                mov    %rbp,%rax
    efcd:       31 d2                   xor    %edx,%edx

I would expect that the gaps will be aligned to functions.

Comment 23 Nick Clifton 2021-10-19 11:40:42 UTC
(In reply to Petr Pisar from comment #22)
> That does not help. Now the annobin flag is passed to libtool three times,
> but libtool deletes all of them:

Darn! :-)  Oh well it was worth a try.

> Strange thing is that 0xefc0 points in the middle of an instruction:

Yeah - this is a "feature" of annocheck's gap detection heuristic.  When it finds a potential gap it moves the start address up until it is aligned to a 32 byte boundary as most architectures align their .text sections to this.  The idea being that this will give the reader a clue as to which object file did not contain the annobin notes.


I have another patch for you which I think might work.  (The trick appears to be to use "-Wc,..." to pass options through libtool).  I will upload the patch pair after I push this comment.  With the patch applied I get the following results when I test a local build (abridged in order to save space):

  % annocheck libgcrypt-1.8.3/src/.libs/libgcrypt.so.20.2.3 -v
  annocheck: Version 10.17.
  Hardened: libgcrypt-1.8.3/src/.libs/libgcrypt.so.20.2.3: FAIL: optimization test because level too low (function: jent_get_nstime) 
  Hardened: libgcrypt-1.8.3/src/.libs/libgcrypt.so.20.2.3: FAIL: optimization test because level too low (function: jent_zfree) 

  [...lots more like this...
   I am not sure why it is being triggered.  Are there chunks of code that are not compiled at -O2 ? ]


  Hardened: libgcrypt-1.8.3/src/.libs/libgcrypt.so.20.2.3: gap:  (0x850c0..0xe2010 probable component: __blowfish_enc_blk1) in annobin notes.
  Hardened: libgcrypt-1.8.3/src/.libs/libgcrypt.so.20.2.3: FAIL: notes test because gaps were detected in the annobin coverage 

  [ ...so a gap is still there, but it is smaller...
    I suspect that this gap comes from the assembly of blowfish-amd64.S, 
    which not being compiled does not get the annobin plugin acting on it...]


  Hardened: libgcrypt-1.8.3/src/.libs/libgcrypt.so.20.2.3: FAIL: cf-protection test because no .note.gnu.property section = no control flow information 
  Hardened: libgcrypt-1.8.3/src/.libs/libgcrypt.so.20.2.3: FAIL: property-note test because no .note.gnu.property section found 

  [ ... This one matters (although it is x86_64 specific).  Without cf-protection
   the code does not benefit from Intel's CET feature, which helps mitigate certain
   types of attack.  Again it is likely this problem is due to the assembler sources
   not being updated to support CET ...]

Anyway, please try the patch set out and see if you get similar results to me.

Cheers
  Nick

Comment 24 Nick Clifton 2021-10-19 11:41:23 UTC
Created attachment 1834610 [details]
Proposed patch

Comment 25 Nick Clifton 2021-10-19 11:41:54 UTC
Created attachment 1834611 [details]
Proposed patch

Comment 26 Petr Pisar 2021-10-19 13:08:28 UTC
I confirm that -Wc can smuggle the annobin flag to the linker:

/bin/sh ../libtool  --tag=CC   --mode=link gcc  -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-
D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -m64  -mtune=generic -fasynchronous-unwind-t
ables -fstack-clash-protection -fcf-protection -fvisibility=hidden -fno-delete-null-pointer-checks -Wall    -Wc,-fplugin=annobin -Wl,--version-script=./libgcrypt.vers -version-info 23:
4:3 -Wl,-z,relro -Wl,--as-needed  -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -O2 -flto=auto -ffat-lto-objects -fexceptions 
-g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -
specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -m64  -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -o libgcrypt.la -rpath /usr/lib64 libgcrypt_la-
visibility.lo libgcrypt_la-misc.lo libgcrypt_la-global.lo libgcrypt_la-sexp.lo libgcrypt_la-hwfeatures.lo libgcrypt_la-stdmem.lo libgcrypt_la-secmem.lo libgcrypt_la-missing-string.lo l
ibgcrypt_la-fips.lo libgcrypt_la-hmac256.lo libgcrypt_la-context.lo  libgcrypt_la-hwf-x86.lo ../cipher/libcipher.la ../random/librandom.la ../mpi/libmpi.la ../compat/libcompat.la  -lgp
g-error 
libtool: link: gcc -shared  -fPIC -DPIC  .libs/libgcrypt_la-visibility.o .libs/libgcrypt_la-misc.o .libs/libgcrypt_la-global.o .libs/libgcrypt_la-sexp.o .libs/libgcrypt_la-hwfeatures.o .libs/libgcrypt_la-stdmem.o .libs/libgcrypt_la-secmem.o .libs/libgcrypt_la-missing-string.o .libs/libgcrypt_la-fips.o .libs/libgcrypt_la-hmac256.o .libs/libgcrypt_la-context.o .libs/libgcrypt_la-hwf-x86.o  -Wl,--whole-archive ../cipher/.libs/libcipher.a ../random/.libs/librandom.a ../mpi/.libs/libmpi.a ../compat/.libs/libcompat.a -Wl,--no-whole-archive  -lgpg-error -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -O2 -flto=auto -m64 -mtune=generic -fplugin=annobin -Wl,--version-script=./libgcrypt.vers -Wl,-z -Wl,relro -Wl,--as-needed -Wl,-z -Wl,now -O2 -flto=auto -m64 -mtune=generic   -Wl,-soname -Wl,libgcrypt.so.20 -o .libs/libgcrypt.so.20.3.4

And I can see the same annocheck results as you.

I searched build.log and I believe that all gcc invocations has -O2 flag.

Comment 27 Petr Pisar 2021-10-21 11:03:32 UTC
I filed bug #2016349 for a maintainer of libgcrypt to apply the patch for linking with annobin plugin.

Comment 28 Nick Clifton 2021-10-21 13:24:26 UTC
(In reply to Petr Pisar from comment #27)
> I filed bug #2016349 for a maintainer of libgcrypt to apply the patch for
> linking with annobin plugin.

Thanks.

Even with the patch applied there are still going to be the problems outlined in comment #23.  
 
The lack of optimization is connected to how librandom is built.  Specifically in libgcrypt-1.8.3/random/Makefile.am there are these lines:

  # The rndjent module needs to be compiled without optimization.  */
  if ENABLE_O_FLAG_MUNGING
  o_flag_munging = sed -e 's/-O\([1-9s][1-9s]*\)/-O0/g' -e 's/-Ofast/-O0/g'
  else
  o_flag_munging = cat
  endif

So it appears to be a deliberate decision.  (I do not know why the decision was made however...)
Assuming that this behaviour needs to be maintained then the associated FAIL results from annocheck will have to be waived.  You may be able to do this automatically using the method outlined in [1] although I have not actually tried it myself.

Fixing the remaining gap should be a simple matter of adding a "-Wa,--generate-missing-build-notes=yes" command line option when assembling any assembler source files[2].

Fixing the cf-protection problem will require editing the assembler source code itself to add some new instructions and generate a note indicating that this has been done.  (Confusingly this note is not the same as the annobin notes...)  See [3] for more details.

Cheers
  Nick

[1] https://sourceware.org/annobin/annobin.html/Waiving-Hardened-Results.html

[2] https://sourceware.org/annobin/annobin.html/Test-notes.html#Test-notes

[3] https://sourceware.org/annobin/annobin.html/Test-cf-protection.html#Test-cf-protection

Comment 29 Ben Cotton 2022-02-08 21:36:39 UTC
This bug appears to have been reported against 'rawhide' during the Fedora 36 development cycle.
Changing version to 36.

Comment 30 Ben Cotton 2023-04-25 18:27:18 UTC
This message is a reminder that Fedora Linux 36 is nearing its end of life.
Fedora will stop maintaining and issuing updates for Fedora Linux 36 on 2023-05-16.
It is Fedora's policy to close all bug reports from releases that are no longer
maintained. At that time this bug will be closed as EOL if it remains open with a
'version' of '36'.

Package Maintainer: If you wish for this bug to remain open because you
plan to fix it in a currently maintained version, change the 'version' 
to a later Fedora Linux version. Note that the version field may be hidden.
Click the "Show advanced fields" button if you do not see it.

Thank you for reporting this issue and we are sorry that we were not 
able to fix it before Fedora Linux 36 is end of life. If you would still like 
to see this bug fixed and are able to reproduce it against a later version 
of Fedora Linux, you are encouraged to change the 'version' to a later version
prior to this bug being closed.

Comment 31 Petr Pisar 2023-04-26 09:48:53 UTC
I conclude that the reported issues has been fixed in F36.


Note You need to log in before you can comment on or make changes to this bug.