bool has_symtab;
bool is_little_endian;
bool lto_used;
+ bool rhivos_clang_fail;
bool not_branch_protection_pending_pass;
bool seen_annobin_plugin_in_dw_at_producer;
bool not_seen_annobin_plugin_in_dw_at_producer;
}
#endif
+static inline bool
+test_enabled (enum test_index check)
+{
+ struct test * test = tests + check;
+
+ if (check >= TEST_MAX)
+ return false;
+
+ if (test->future && ! enable_future_tests)
+ return false;
+
+ return test->enabled;
+}
+
+static inline bool
+skip_test (enum test_index check)
+{
+ struct test * test = tests + check;
+
+ if (! test_enabled (check))
+ /* We do not issue a SKIP message for disabled tests. */
+ return true;
+
+ if (test->state == STATE_FAILED || test->state == STATE_MAYBE)
+ /* The test has already failed. No need to test it again. */
+ return true;
+
+ return false;
+}
+
+/* Returns true if we want to run the given test but it has
+ not yet generated any result. */
+
+static bool
+untested (enum test_index check)
+{
+ struct test * test = tests + check;
+
+ if (! test_enabled (check))
+ return false;
+
+ if (test->state == STATE_UNTESTED)
+ return true;
+
+ return false;
+}
+
static void
-pass (annocheck_data * data, uint testnum, const char * source, const char * reason)
+pass (annocheck_data * data, enum test_index testnum, const char * source, const char * reason)
{
assert (testnum < TEST_MAX);
- if (! tests[testnum].enabled)
+ if (! test_enabled (testnum))
return;
- if (tests[testnum].future && ! enable_future_tests)
- return;
-
/* If we have already seen a FAIL then do not also report a PASS. */
if (tests[testnum].state == STATE_FAILED)
return;
- if (tests[testnum].state == STATE_UNTESTED)
- tests[testnum].state = STATE_PASSED;
-
+ // If we have already passed this test then do not pass it again.
if (tests[testnum].result_announced)
return;
+ if (tests[testnum].state == STATE_UNTESTED)
+ tests[testnum].state = STATE_PASSED;
+
per_file.num_pass ++;
tests[testnum].result_announced = true;
if (fixed_format_messages)
{
const char * fname = sanitize_filename (filename);
+
einfo (INFO, FIXED_FORMAT_STRING, "PASS", tests[testnum].name, fname);
if (fname != filename)
free ((void *) fname);
}
static void
-skip (annocheck_data * data, uint testnum, const char * source, const char * reason)
+skip (annocheck_data * data, enum test_index testnum, const char * source, const char * reason)
{
assert (testnum < TEST_MAX);
test * test = tests + testnum;
- if (! test->enabled)
+ if (! test_enabled (testnum))
return;
- if (test->future && ! enable_future_tests)
- return;
-
if (test->state == STATE_SKIPPED)
return;
}
static inline void
-show_url (uint testnum, const char * filename)
+show_url (enum test_index testnum, const char * filename)
{
if (PROVIDE_A_URL)
einfo (PARTIAL, "%s: %s: info: For more information visit: %s\n",
static void
fail (annocheck_data * data,
- uint testnum,
+ enum test_index testnum,
const char * source,
const char * reason)
{
assert (testnum < TEST_MAX);
- test * test = tests + testnum;
-
- if (! test->enabled)
+ if (! test_enabled (testnum))
return;
if (skip_test_for_current_func (data, testnum))
return;
- if (test->future && ! enable_future_tests)
- {
- einfo (VERBOSE2, "%s: look: %s", get_filename (data), reason);
- einfo (VERBOSE2, "%s: ^^^^: Test %s is not yet enabled, but if it was enabled, it would have FAILed here...",
- get_filename (data), test->name);
- return;
- }
-
per_file.num_fails ++;
+ test * test = tests + testnum;
+
#ifdef LIBANNOCHECK
libannocheck_record_test_fail (testnum, source, reason);
#else
static bool
maybe (annocheck_data * data,
- uint testnum,
+ enum test_index testnum,
const char * source,
const char * reason)
{
assert (testnum < TEST_MAX);
- test * test = tests + testnum;
-
- if (! test->enabled)
+ if (! test_enabled (testnum))
return false;
if (skip_test_for_current_func (data, testnum))
return false;
- if (test->future && ! enable_future_tests)
- {
- einfo (VERBOSE2, "%s: look: %s", get_filename (data), reason);
- einfo (VERBOSE2, "%s: ^^^^: Test %s is not yet enabled, but if it was enabled, it would have generated a MAYB result",
- get_filename (data), test->name);
- return false;
- }
-
per_file.num_maybes ++;
+ test * test = tests + testnum;
+
#ifdef LIBANNOCHECK
libannocheck_record_test_maybe (testnum, source, reason);
#else
}
static void
-vvinfo (annocheck_data * data, uint testnum, const char * source, const char * extra)
+vvinfo (annocheck_data * data, enum test_index testnum, const char * source, const char * extra)
{
- assert (testnum < TEST_MAX);
-
- test * test = tests + testnum;
-
- if (! test->enabled)
+ if (! test_enabled (testnum))
return;
if (fixed_format_messages)
return;
+ test * test = tests + testnum;
+
einfo (VERBOSE2, "%s: info: %s: %s (source %s)", get_filename (data), test->name, extra, source);
}
return ! per_file.langs[LANG_C] && ! per_file.langs[LANG_CXX];
}
-static inline bool
-skip_test (enum test_index check)
-{
- struct test * test = tests + check;
-
- if (check >= TEST_MAX || ! test->enabled)
- /* We do not issue a SKIP message for disabled tests. */
- return true;
-
- if (test->state == STATE_FAILED || test->state == STATE_MAYBE)
- /* The test has already failed. No need to test it again. */
- return true;
-
- return false;
-}
-
-/* Returns true if we want to run the given test but it has
- not yet generated any result. */
-
-static bool
-untested (enum test_index check)
-{
- struct test * test = tests + check;
-
- if (check >= TEST_MAX || ! test->enabled)
- return false;
-
- if (test->state == STATE_UNTESTED)
- return true;
-
- return false;
-}
-
static void
set_lang (annocheck_data * data,
enum lang lang,
{
if (version == 0)
{
- if (tests[TEST_GO_REVISION].enabled
- && tests[TEST_GO_REVISION].state == STATE_UNTESTED)
+ if (untested (TEST_GO_REVISION))
{
/* This is not a MAYB result, because stripped GO binaries can trigger this result. */
einfo (VERBOSE2, "%s: info: GO compilation detected, but version is unknown. Source: %s",
}
else if (version < MIN_GO_REVISION)
{
- if (tests[TEST_GO_REVISION].enabled
- && tests[TEST_GO_REVISION].state != STATE_FAILED)
+ if (! skip_test (TEST_GO_REVISION))
{
/* Note - in the future MIN_GO_REVISION may no longer be supported by
Red Hat even though it is still viable from a security point of view. */
if (update_current_tool)
per_file.current_tool = tool;
+ if (test_enabled (TEST_RHIVOS)
+ && (tool == TOOL_CLANG || tool == TOOL_LLVM)
+ && ! per_file.rhivos_clang_fail)
+ {
+ per_file.rhivos_clang_fail = true;
+ fail (data, TEST_RHIVOS, source, "Building with Clang/LLVM is not supported for RHIVOS");
+ }
+
if (per_file.seen_tool_versions[tool] == 0)
{
if (version == 0)
expect_fortify_3 (void)
{
return per_file.profile == PROFILE_EL10
+ // || per_file.profile == PROFILE_RHIVOS
|| per_file.profile == PROFILE_RAWHIDE;
}
static bool
is_rhel_10 (void)
{
- return per_file.profile == PROFILE_EL10;
+ return per_file.profile == PROFILE_EL10
+ // || per_file.profile == PROFILE_RHIVOS
+ ;
}
static void
}
/* Handle mutually exclusive tests. */
- if (tests [TEST_BRANCH_PROTECTION].enabled && tests [TEST_NOT_BRANCH_PROTECTION].enabled)
+ if (test_enabled (TEST_BRANCH_PROTECTION) && test_enabled (TEST_NOT_BRANCH_PROTECTION))
{
#ifdef AARCH64_BRANCH_PROTECTION_SUPPORTED
tests [TEST_NOT_BRANCH_PROTECTION].enabled = false;
#endif
}
- if (tests [TEST_DYNAMIC_TAGS].enabled && tests [TEST_NOT_DYNAMIC_TAGS].enabled)
+ if (test_enabled (TEST_DYNAMIC_TAGS) && test_enabled (TEST_NOT_DYNAMIC_TAGS))
{
#ifdef AARCH64_BRANCH_PROTECTION_SUPPORTED
tests [TEST_NOT_DYNAMIC_TAGS].enabled = false;
case 0: /* ??? */
case 4: /* CF_FULL. */
case 8: /* CF_FULL | CF_SET */
- if (tests[TEST_PROPERTY_NOTE].enabled)
+ if (test_enabled (TEST_PROPERTY_NOTE))
/* Do not PASS here. The binary might be linked with other objects which do
not have this option enabled, and so the property note will not be correct.
See BZ 1991943 and 2010692. */
if ((property & GNU_PROPERTY_AARCH64_FEATURE_1_BTI) == 0)
{
- if (tests[TEST_BRANCH_PROTECTION].enabled)
+ if (test_enabled (TEST_BRANCH_PROTECTION))
return "the BTI property is not enabled";
}
case '0': /* ??? */
case '4': /* CF_FULL. */
case '8': /* CF_FULL | CF_SET */
- if (tests[TEST_PROPERTY_NOTE].enabled)
+ if (test_enabled (TEST_PROPERTY_NOTE))
/* Do not PASS here. The binary might be linked with other objects which do
not have this option enabled, and so the property note will not be correct.
See BZ 1991943 and 2010692. */
case DT_RPATH:
// Strictly speaking RHVOS binaries are not supposed to use DT_RPATH, but
- // too many do. So for now --profile=rhivos enabled TEST_RUN_PATH instead.
+ // too many do. So for now --profile=rhivos enables TEST_RUN_PATH instead.
// fail (data, TEST_RHIVOS, SOURCE_DYNAMIC_SECTION, "the DT_RPATH dynamic tag is present");
if (! skip_test (TEST_RUN_PATH))
{
case DT_RUNPATH:
// Strictly speaking RHVOS binaries are not supposed to use DT_RUNRPATH, but
- // too many do. So for now --profile=rhivos enabled TEST_RUN_PATH instead.
+ // too many do. So for now --profile=rhivos enables TEST_RUN_PATH instead.
// fail (data, TEST_RHIVOS, SOURCE_DYNAMIC_SECTION, "the DT_RUNPATH dynamic tag is present");
if (! skip_test (TEST_RUN_PATH))
{
case DT_SONAME:
per_file.has_soname = true;
- if (! skip_test (TEST_RHIVOS))
+ if (test_enabled (TEST_RHIVOS))
{
const char * soname = elf_strptr (data->elf, sec->shdr.sh_link, dyn->d_un.d_val);
}
}
+#if 0
if (has_dt_hash && ! has_dt_gnu_hash)
fail (data, TEST_RHIVOS, SOURCE_DYNAMIC_SECTION, "DT_HASH seen without DT_GNU_HASH");
-
+#else
+ if (has_dt_hash)
+ fail (data, TEST_RHIVOS, SOURCE_DYNAMIC_SECTION, "RHIVOS does not support the use of the .hash section. Please use --hash-style=gnu");
+#endif
+
if (dynamic_relocs_seen && tests[TEST_BIND_NOW].state != STATE_PASSED)
{
if (! is_executable ())
break;
case 1:
- if (tests[TEST_DYNAMIC_TAGS].enabled) /* The PAC_PLT flag is Not currently used. */
+ if (test_enabled (TEST_DYNAMIC_TAGS)) /* The PAC_PLT flag is Not currently used. */
{
future_fail (data, TEST_DYNAMIC_TAGS, SOURCE_DYNAMIC_SECTION, "the PAC_PLT flag is missing from dynamic tags");
pass (data, TEST_DYNAMIC_TAGS, SOURCE_DYNAMIC_SECTION, "the BTI_PLT flag is present in the dynamic tags");
}
}
- if (tests[TEST_FIPS].enabled)
+ if (test_enabled (TEST_FIPS))
{
/* Look for golang build options stored in the .rodata section. */
static const char * cgo_build="build\tCGO_ENABLED=1";
cf BZ 1995224. */
if (gap > 0x3c || per_file.e_machine != EM_AARCH64)
{
- if (tests[TEST_GAPS].enabled)
+ if (test_enabled (TEST_GAPS))
{
if (sym != NULL && gap_expected_for_sym (sym))
{
if (! per_file.build_notes_seen
&& ! per_file.build_string_notes_seen
- && tests[TEST_NOTES].enabled)
+ && test_enabled (TEST_NOTES))
{
if (per_file.e_machine == EM_ARM)
/* The annobin plugin for gcc is not used when building ARM binaries
}
}
- if (tests[TEST_GAPS].enabled)
+ if (test_enabled (TEST_GAPS))
{
if (tests [TEST_GAPS].state != STATE_UNTESTED)
;
}
else if (per_file.e_machine == EM_AARCH64)
{
- if (tests[TEST_BRANCH_PROTECTION].enabled)
+ if (test_enabled (TEST_BRANCH_PROTECTION))
{
if (per_file.has_property_note)
pass (data, i, SOURCE_FINAL_SCAN, "properly formatted .note.gnu.property section found");
pass (data, i, SOURCE_FINAL_SCAN, "CET enabled property note found");
else if (per_file.has_property_note)
{
- if (tests[TEST_CF_PROTECTION].enabled)
+ if (test_enabled (TEST_CF_PROTECTION))
fail (data, i, SOURCE_FINAL_SCAN, "a property note was found but it shows that cf-protection is not enabled");
else
pass (data, i, SOURCE_FINAL_SCAN, "a property note was found. (Not CET enabled, but this is not being checked)");
}
else if (LLVM_compiler_used ())
skip (data, i, SOURCE_FINAL_SCAN, "sanitize_cfi is not currently required for LLVM compilation");
- else if (tests[TEST_PROPERTY_NOTE].enabled)
+ else if (test_enabled (TEST_PROPERTY_NOTE))
{
if (tests[TEST_PROPERTY_NOTE].state == STATE_UNTESTED)
fail (data, i, SOURCE_FINAL_SCAN, "no .note.gnu.property section = no control flow information");
Example: FAIL: the DT_DEPAUDIT dynamic tag is present
Example: FAIL: the DT_FILTER dynamic tag is present
Example: FAIL: the DT_PREINIT_ARRAY dynamic tag is present
- Example: FAIL: DT_HASH seen without DT_GNU_HASH
+ Example: FAIL: RHIVOS does not support the use of the .hash section. Please use --hash-style=gnu
Example: FAIL: not linked with -Wl,-z,now
Example: FAIL: dlopen/dlclose found in symbol table
Example: FAIL: GNU TLS version 1 functions found in symbol table
Example: FAIL: LOAD segment with Write and Execute permissions seen
+ Example: FAIL: Building with Clang/LLVM is not supported for RHIVOS
Deleopment for the RHIVOS environment requires that some extra
hardening measures are applied. This test attempts to check for most of
Enabling this test automatically enables the ‘--test-bind-now’,
‘--test-gnu-relro’, ‘--test-gnu-stack’. ‘--test-rwx-seg’ and
-‘--test-run-path’ tests.
+‘--test-run-path’ tests. In addition the following extra checks are
+run:
+
+‘Clang/LLVM is not used.’
+‘The linker option --initfirst has not been used.’
+‘The linker option --audit has not been used.’
+‘The linker option --depaudit has not been used.’
+‘The linker option --auxiliary has not been used.’
+‘The linker option --filter has not been used.’
+‘Shared libraries names match their filenames and do not include’
+ the directory separator character.
+‘The binary does not have a pre-init array.’
+‘The linker option --hash-style=hash or’
+ ‘--hash-style=both’ has been used.
+‘Dynamically loaded code is used.’
+‘Loadable segments with both the Write and Execute permissions’
+ are found in the binary.
This test is normally only enabled if the ‘--profile=rhivos’ option
is used to select the RHIVOS profile. But it can be enabled
Node: Test production\7f90223
Node: Test property note\7f91063
Node: Test rhivos\7f93551
-Node: Test run path\7f95311
-Node: Test rwx seg\7f97550
-Node: Test short enums\7f98972
-Node: Test stack clash\7f100014
-Node: Test stack prot\7f101504
-Node: Test stack realign\7f102857
-Node: Test textrel\7f104147
-Node: Test threads\7f105458
-Node: Test unicode\7f106290
-Node: Test warnings\7f107826
-Node: Test writable got\7f108682
-Node: Test zero call used regs\7f109980
-Node: Hardened Command Line Options\7f111266
-Node: Waiving Hardened Results\7f118676
-Node: Absence of compiled code\7f120698
-Node: Notes\7f127081
-Node: Size\7f127727
-Node: Timing\7f130445
-Node: Libannocheck\7f131104
-Node: libannocheck_init\7f133059
-Node: libannocheck_finish\7f133985
-Node: libannocheck_get_version\7f134533
-Node: libannocheck_get_error_message\7f134946
-Node: libannocheck_get_known_tests\7f135586
-Node: libannocheck_enable_all_tests\7f136766
-Node: libannocheck_disable_all_tests\7f137249
-Node: libannocheck_enable_test\7f137809
-Node: libannocheck_disable_test\7f138489
-Node: libannocheck_enable_profile\7f139170
-Node: libannocheck_get_known_profiles\7f139692
-Node: libannocheck_run_tests\7f140395
-Node: Configure Options\7f141244
-Node: Legacy Scripts\7f143780
-Node: Who Built Me\7f144563
-Node: ABI Checking\7f147454
-Node: Hardening Checks\7f149701
-Node: Checking Archives\7f154049
-Node: GNU FDL\7f156602
+Node: Test run path\7f96169
+Node: Test rwx seg\7f98408
+Node: Test short enums\7f99830
+Node: Test stack clash\7f100872
+Node: Test stack prot\7f102362
+Node: Test stack realign\7f103715
+Node: Test textrel\7f105005
+Node: Test threads\7f106316
+Node: Test unicode\7f107148
+Node: Test warnings\7f108684
+Node: Test writable got\7f109540
+Node: Test zero call used regs\7f110838
+Node: Hardened Command Line Options\7f112124
+Node: Waiving Hardened Results\7f119534
+Node: Absence of compiled code\7f121556
+Node: Notes\7f127939
+Node: Size\7f128585
+Node: Timing\7f131303
+Node: Libannocheck\7f131962
+Node: libannocheck_init\7f133917
+Node: libannocheck_finish\7f134843
+Node: libannocheck_get_version\7f135391
+Node: libannocheck_get_error_message\7f135804
+Node: libannocheck_get_known_tests\7f136444
+Node: libannocheck_enable_all_tests\7f137624
+Node: libannocheck_disable_all_tests\7f138107
+Node: libannocheck_enable_test\7f138667
+Node: libannocheck_disable_test\7f139347
+Node: libannocheck_enable_profile\7f140028
+Node: libannocheck_get_known_profiles\7f140550
+Node: libannocheck_run_tests\7f141253
+Node: Configure Options\7f142102
+Node: Legacy Scripts\7f144638
+Node: Who Built Me\7f145421
+Node: ABI Checking\7f148312
+Node: Hardening Checks\7f150559
+Node: Checking Archives\7f154907
+Node: GNU FDL\7f157460
\1f
End Tag Table