On 21/11/2022 12:42, Beata Michalska wrote:
On Mon, Nov 21, 2022 at 10:59:44AM +0100, Kevin Brodsky wrote:
On 18/11/2022 13:21, Beata Michalska wrote:
|diff --git a/lib/test_printf.c b/lib/test_printf.c index 07309c45f327..1b877b68a30d 100644 --- a/lib/test_printf.c +++ b/lib/test_printf.c @@ -24,6 +24,10 @@ #include <linux/property.h> +#ifdef __CHERI__ +#include <cheriintrin.h> +#endif + #include "../tools/testing/selftests/kselftest_module.h" #define BUF_SIZE 256 @@ -755,6 +759,159 @@ errptr(void) #endif } +static void __init +capability_pointer(void) +{ +#ifdef __CHERI__ + enum action { + /* No action - use as is */ + CAP_AXN_NONE, + /* Clear capability tag */ + CAP_TAG_CLEAR, + /* Derive null-capability */ + CAP_NULL_DERIVE + }; +
- struct { + const char *plain_fmt; + const char *fmt; + const char
*expected; + int action; + } const setup[] = { + { + .plain_fmt = "%lp", + .fmt = "%lpx", + .expected = "1:d800400059ab89ab:"PTR_STR, + .action = CAP_AXN_NONE, + }, + { + .plain_fmt = "%#lp", + .fmt = "%#lpx", + .expected = "0x"PTR_STR" [rwRW,0xffff0123456789ab-0xffff0123456799ab]", + .action = CAP_AXN_NONE, + }, + { + .plain_fmt = "%lp", + .fmt = "%lpx", + .expected = "0:d800400059ab89ab:"PTR_STR, + .action = CAP_TAG_CLEAR, + }, + { + .plain_fmt = "%#lp", + .fmt = "%#lpx", + .expected = "0x"PTR_STR" [rwRW,0xffff0123456789ab-0xffff0123456799ab] (invalid)",
- .action = CAP_TAG_CLEAR, + }, + { + .plain_fmt = "%lp", + .fmt =
"%lpx", + .expected = PTR_STR, + .action = CAP_NULL_DERIVE, + }, + { + .plain_fmt = "%#lp", + .fmt = "%#lpx", + .expected = PTR_STR, + .action = CAP_NULL_DERIVE, + } + }; + + char buf[PLAIN_BUF_SIZE]; + const char * const cap_fmt_non_hashed[] = {"%lp", "%#lp"}; + int nchars; + + void * __capability cap = cheri_ddc_get(); + + /* Expecting basic permissions to be set */ + size_t perms = CHERI_PERM_GLOBAL | CHERI_PERM_LOAD | CHERI_PERM_LOAD_CAP | + CHERI_PERM_STORE | CHERI_PERM_STORE_CAP; + + size_t bounds = 4096; + + cap = cheri_address_set(cap, (ptraddr_t)PTR); + cap = cheri_perms_and(cap, perms); + /* + * Basic checks so that the actual output can be safely compared + * to the expected one + */ + if (!cheri_tag_get(cap) || cheri_perms_get(cap) != perms + || cheri_is_sealed(cap)) { + pr_warn("Failed to create capability for testing - skipping"); + skipped_tests += no_hash_pointers ? + ARRAY_SIZE(cap_fmt_non_hashed) + ARRAY_SIZE(setup) * 2 : + ARRAY_SIZE(cap_fmt_non_hashed) + ARRAY_SIZE(setup); + return; + } + + cap = cheri_bounds_set_exact(cap, bounds); + + /* Verify hashing */ + if (no_hash_pointers) { + pr_warn("Skipping capability hashing tests\n"); + skipped_tests += ARRAY_SIZE(cap_fmt_non_hashed); + goto non_hashed; + } + + for (int i = 0; i < ARRAY_SIZE(cap_fmt_non_hashed); ++i) { + nchars = snprintf(buf, PLAIN_BUF_SIZE, cap_fmt_non_hashed[i], + cap); + + total_tests++; + /*
- Should be ADDR_WIDTH in this case , but hey, let's not be picky +
- about it, at least not here ... not yet ... + */ + if (nchars !=
PTR_WIDTH) { + /* + * This also covers the case when the value has not been + * actually hashed, as nchars would then be greater than + * PTR_WIDTH + */ + pr_warn("Something went wrong with hashing capability value\n"); + failed_tests++; + continue; + } + + if (strncmp(buf, PTR_VAL_NO_CRNG, PTR_WIDTH) == 0) { + pr_warn("crng possibly not yet initialized - capability value buffer contains "%s"", + PTR_VAL_NO_CRNG); + } else if (strncmp(buf, ZEROS, strlen(ZEROS)) != 0) { + pr_warn("Unexpected format for supposedly hashed capability value\n"); + failed_tests++; + continue; + } + } + +non_hashed: + for (int i = 0; i < ARRAY_SIZE(setup); ++i) { + void * __capability current_cap; + + switch (setup[i].action) { + case CAP_TAG_CLEAR: + current_cap = cheri_tag_clear(cap); + break; + case CAP_NULL_DERIVE: + /* Null-derived capability */ + current_cap = cheri_address_set(0, cheri_address_get(cap)); + break; + default: + current_cap = cap; + break; + } + + if (no_hash_pointers) + test(setup[i].expected, setup[i].plain_fmt, current_cap); + else + ++skipped_tests; + + test(setup[i].expected, setup[i].fmt, current_cap); + } + + return;|
Not needed any more.
Nothing else to complain about, so if you're happy with it I can remove it myself when applying the patch.
That would be appreciated so go ahead with the change. Thanks
Cool. While running the tests I realised that the skipped/total counters don't make much sense in this file in general (i.e. they are used in a very inconsistent way), we therefore agreed offline not to bother updating them manually in this new test. They could potentially be reintroduced later if the other tests are made more consistent.
I have modified the patch accordingly and it is now in next, thanks for that nice patch and for bearing with me :D
Kevin
BR B.
Kevin
|+ +#endif /* CONFIG_ARM64_MORELLO */ +} + static void __init test_pointer(void) {|