Hello, May I ask you a question about a way to fix the annocheck gaps test. I am using the gcc, annocheck and redhat-rpm-config RPM versions below on my Fedora 36. ``` $ rpm -q gcc gcc-12.1.1-1.fc36.x86_64 $ rpm -qf /bin/annocheck annobin-annocheck-10.76-1.fc36.x86_64 $ rpm -q redhat-rpm-config redhat-rpm-config-220-1.fc36.noarch ``` I am testing Ruby (https://github.com/ruby/ruby) binaries by annocheck with some flags cases to fix the gap tests. I prepared a git repository to explain my situation to you easily. https://github.com/junaruga/ruby-annocheck-test In the repository there are 3 ruby binary files that I built on my Fedora 36 with the gcc above. The `78425d7e74` or `c46824d094` mean the used commit hash on the ruby/ruby repository. The both commits are on the recently master branch used as development. ``` $ ls binaries/202206*/*/ruby binaries/20220617-commit-78425d7e74/build_with_fedora_build_flags/ruby* binaries/20220617-commit-78425d7e74/build_with_minimal_flags/ruby* binaries/20220620-commit-c46824d094/build_with_minimal_flags/ruby* ``` ``` $ git clone https://github.com/ruby/ruby.git $ cd ruby $ git checkout 78425d7e74 (or c46824d094) ``` ## case 1: binaries/20220617-commit-78425d7e74/build_with_fedora_build_flags/ruby* I built the binary like this. The flags are defined in the `redhat-rpm-config` RPM. ``` ./autogen.sh # Build flags in Fedora. CFLAGS='-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' \ CXXFLAGS='-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' \ 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 -Wl,--build-id=sha1 ' \ ./configure \ --enable-shared \ --enable-mkmf-verbose make V=1 ``` The annocheck passes. ``` $ annocheck binaries/20220617-commit-78425d7e74/build_with_fedora_build_flags/ruby annocheck: Version 10.76. Hardened: ruby: PASS. ``` ## case 2: binaries/20220617-commit-78425d7e74/build_with_minimal_flags/ruby* I built the binary like this. The flags are minimal flags that I intended to pass annocheck tests. ``` ./autogen.sh LDFLAGS=-Wl,-z,now \ ./configure \ --enable-shared \ --with-gcc="gcc -fcf-protection" \ --enable-mkmf-verbose make V=1 ``` The annocheck gaps and pie tests fail. ``` $ annocheck binaries/20220617-commit-78425d7e74/build_with_minimal_flags/ruby annocheck: Version 10.76. Hardened: ruby: MAYB: test: gaps because not all of the .text section is covered by notes Hardened: ruby: FAIL: pie test because not built with '-Wl,-pie' Hardened: Rerun annocheck with --verbose to see more information on the tests. Hardened: ruby: Overall: FAIL. ``` For the pie test failure, I assume that we can fix the test by adding some flags used in the case 1. ``` $ grep -ri pie gcc_specs/ gcc_specs/redhat-hardened-ld:+ %{!static:%{!shared:%{!r:-pie}}} gcc_specs/redhat-hardened-cc1:+ %{!r:%{!fpie:%{!fPIE:%{!fpic:%{!fPIC:%{!fno-pic:-fPIE}}}}}} ``` The problem is the `MAYB: test: gaps because not all of the .text section is covered by notes`. It seems the test was added at the annocheck 10.76 newly. ## case 3: binaries/20220620-commit-c46824d094/build_with_minimal_flags/ruby* I added the flag `-Wa,--generate-missing-build-notes=yes` from the case 2 above. ``` ./autogen.sh LDFLAGS=-Wl,-z,now \ ./configure \ --enable-shared \ --with-gcc="gcc -fcf-protection -Wa,--generate-missing-build-notes=yes" \ --enable-mkmf-verbose make V=1 ``` I could fix the annocheck gaps test below. However here is a question. Is adding the flag: -Wa,--generate-missing-build-notes=yes right to fix? Because in the case 1, the annocheck passed the gaps test without the flag. ``` $ annocheck binaries/20220620-commit-c46824d094/build_with_minimal_flags/ruby annocheck: Version 10.76. Hardened: ruby: FAIL: pie test because not built with '-Wl,-pie' Hardened: Rerun annocheck with --verbose to see more information on the tests. Hardened: ruby: Overall: FAIL. ``` Thanks. Regards, Jun
A related pull-request on the Ruby project: https://github.com/ruby/ruby/pull/6045
(In reply to Jun Aruga from comment #0) Hi Jun, > May I ask you a question about a way to fix the annocheck gaps test. Of course - I am happy to answer questions. > The annocheck gaps and pie tests fail. > Hardened: ruby: MAYB: test: gaps because not all of the .text section is > covered by notes > Hardened: ruby: FAIL: pie test because not built with '-Wl,-pie' > For the pie test failure, I assume that we can fix the test by adding some > flags used in the case 1. Yes - in particular the -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 and the -specs=/usr/lib/rpm/redhat/redhat-hardened-ld options. Also the gaps test failure should be fixed if you add in the -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 option. > The problem is the `MAYB: test: gaps because not all of the .text section is > covered by notes`. It seems the test was added at the annocheck 10.76 newly. Well it is not new, but I have tweaked the code slightly so that the "notes" test now generates a MAYB result if there are no annobin notes to be found at all, but it will PASS if some notes can be found. Whereas the "gaps" test will fail if there are some notes, but they do not cover all of the executable region(s) of the binary. Also the gaps test used to be a separate option controlled by the --ignore-gaps/--report-gaps options. It is now treated as a test like any of others, so it can be disabled by --skip-gaps and re-enabled by --test-gaps. The --ignore-gaps and --report-gaps options still work however - they are now just aliases for the new options. > ./configure \ > --enable-shared \ > --with-gcc="gcc -fcf-protection -Wa,--generate-missing-build-notes=yes" \ > --enable-mkmf-verbose > > make V=1 > ``` > > I could fix the annocheck gaps test below. However here is a question. Is > adding the flag: -Wa,--generate-missing-build-notes=yes right to fix? Not really. It does work, but it looses the benefit of the annobin plugin's recording of security/hardening information. A better option, in my opinion would be: --with-gcc="gcc -fcf-protection -fplugin=annobin" \ This will cause the annobin notes to be generated and so annocheck should be happy - and also able to report if there are other hardening options that have been omitted. Cheers Nick
resolved - I hope.
Thank you for the answer! Sorry for my delayed response. We are seeing a gap test failure with Ruby binary built with the `-O2` flag on Ruby's CI. We want to add the `-fplugin=annobin` flag explained as "Fix By: Compile with -fplugin=annobin" on the page on our GitHub Actions CI, Ubuntu environment. https://sourceware.org/annobin/annobin.html/Test-gaps.html However, we didn't see the gcc annobin deb package on Ubuntu or Debian. https://tracker.debian.org/ https://packages.ubuntu.com/ Is there a way to use the gcc annobin plugin on Ubuntu? What is a workaround for this case? Adding "-Wa,--generate-missing-build-notes=yes"? You can see https://github.com/ruby/ruby/pull/7132#issuecomment-1396945688 for details. Thank you for your help!
(In reply to Jun Aruga from comment #4) Hi Jun, > However, we didn't see the gcc annobin deb package on Ubuntu or Debian. > https://tracker.debian.org/ > https://packages.ubuntu.com/ Ah - it may well be that neither Debian nor Ubuntu use or ship annobin. It was developed initially as an internal testing tool for Fedora, so it is not surprising that other distributions do not use it. > Is there a way to use the gcc annobin plugin on Ubuntu? With difficulty - yes. The gcc annobin plugin sources are part of the annobin project, which is open source, so you can download them and build your own copy of the plugin. Once that is done you could then use the -fplugin=annobin option. You should be able to configure the annobin sources so that you only build the plugin and nothing else. But you will need to have gcc plugin support available in order to build the plugin. (On Fedora this is a separate package from gcc, called "gcc-plugin-devel" I am not sure if the same is true for Ubunto or Debian). > What is a workaround > for this case? Adding "-Wa,--generate-missing-build-notes=yes"? Yes - that should work. Cheers Nick