Skip to content

Commit af050bb

Browse files
nwfnwf-msr
authored andcommitted
capdirty: first, minimal test in cheritest
1 parent e5a975f commit af050bb

File tree

3 files changed

+75
-0
lines changed

3 files changed

+75
-0
lines changed

bin/cheribsdtest/cheribsdtest.c

+4
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,10 @@ static const struct cheri_test cheri_tests[] = {
878878
.ct_desc = "read capabilities from a faulted copy-on-write page",
879879
.ct_func = cheribsdtest_vm_cow_write, },
880880

881+
{ .ct_name = "cheribsdtest_vm_capdirty",
882+
.ct_desc = "verify capdirty marking and mincore",
883+
.ct_func = cheribsdtest_vm_capdirty, },
884+
881885
#if 0
882886
{ .ct_name = "cheribsdtest_vm_swap",
883887
.ct_desc = "check tags are swapped out by swap pager",

bin/cheribsdtest/cheribsdtest.h

+1
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,7 @@ DECLARE_CHERIBSD_TEST(cheribsdtest_vm_tag_tmpfile_private);
649649
DECLARE_CHERIBSD_TEST(cheribsdtest_vm_tag_tmpfile_private_prefault);
650650
DECLARE_CHERIBSD_TEST(cheribsdtest_vm_cow_read);
651651
DECLARE_CHERIBSD_TEST(cheribsdtest_vm_cow_write);
652+
DECLARE_CHERIBSD_TEST(cheribsdtest_vm_capdirty);
652653
const char *xfail_need_writable_tmp(const char *name);
653654

654655
#if 0

bin/cheribsdtest/cheribsdtest_vm.c

+70
Original file line numberDiff line numberDiff line change
@@ -602,3 +602,73 @@ cheribsdtest_vm_cow_write(const struct cheri_test *ctp __unused)
602602
CHERIBSDTEST_CHECK_SYSCALL(close(fd));
603603
cheribsdtest_success();
604604
}
605+
606+
/*
607+
* Store a cap to a page and check that mincore reports it CAPSTORE.
608+
*
609+
* Due to a shortage of bits in mincore()'s uint8_t reporting bit vector, this
610+
* particular test is not able to distinguish CAPSTORE and CAPDIRTY and so is
611+
* not sensitive to the vm.pmap.enter_capstore_as_capdirty sysctl.
612+
*
613+
* On the other hand, this test is sensitive to the vm.capstore_on_alloc sysctl:
614+
* if that is asserted, our cap-capable anonymous memory will be installed
615+
* CAPSTORE (and possibly even CAPDIRTY, in light of the above) whereas, if this
616+
* sysctl is clear, our initial view of said memory will be !CAPSTORE.
617+
*/
618+
void
619+
cheribsdtest_vm_capdirty(const struct cheri_test *ctp __unused)
620+
{
621+
static const size_t npg = 2;
622+
size_t sz = npg * getpagesize();
623+
uint8_t capstore_on_alloc;
624+
size_t capstore_on_alloc_sz = sizeof(capstore_on_alloc);
625+
626+
void * __capability *pg0;
627+
unsigned char mcv[npg] = { 0 };
628+
629+
CHERIBSDTEST_CHECK_SYSCALL(
630+
sysctlbyname("vm.capstore_on_alloc", &capstore_on_alloc,
631+
&capstore_on_alloc_sz, NULL, 0));
632+
633+
pg0 = CHERIBSDTEST_CHECK_SYSCALL(
634+
mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0));
635+
636+
void * __capability *pg1 = (void *)&((char *)pg0)[getpagesize()];
637+
638+
/*
639+
* Pages are ZFOD and so will not be CAPSTORE, or, really, anything
640+
* else, either.
641+
*/
642+
CHERIBSDTEST_CHECK_SYSCALL(mincore(pg0, sz, &mcv[0]));
643+
CHERIBSDTEST_VERIFY2(mcv[0] == 0, "page 0 status 0");
644+
CHERIBSDTEST_VERIFY2(mcv[1] == 0, "page 1 status 0");
645+
646+
/*
647+
* Write data to page 0, causing it to become allocated and MODIFIED.
648+
* If vm.capstore_on_alloc, then it should be CAPSTORE as well, despite
649+
* having never been the target of a capability store.
650+
*/
651+
*(char *)pg0 = 0x42;
652+
653+
CHERIBSDTEST_CHECK_SYSCALL(mincore(pg0, sz, &mcv[0]));
654+
CHERIBSDTEST_VERIFY2(
655+
(mcv[0] & MINCORE_MODIFIED) != 0, "page 0 modified 1");
656+
CHERIBSDTEST_VERIFY2(
657+
!(mcv[0] & MINCORE_CAPSTORE) == !capstore_on_alloc,
658+
"page 0 capstore 1");
659+
660+
/*
661+
* Write a capability to page 1 and check that it is MODIFIED and
662+
* CAPSTORE regardless of vm.capstore_on_alloc.
663+
*/
664+
*pg1 = (void * __capability)pg0;
665+
666+
CHERIBSDTEST_CHECK_SYSCALL(mincore(pg0, sz, &mcv[0]));
667+
CHERIBSDTEST_VERIFY2(
668+
(mcv[1] & MINCORE_MODIFIED) != 0, "page 1 modified 2");
669+
CHERIBSDTEST_VERIFY2(
670+
(mcv[1] & MINCORE_CAPSTORE) != 0, "page 1 capstore 2");
671+
672+
CHERIBSDTEST_CHECK_SYSCALL(munmap(pg0, sz));
673+
cheribsdtest_success();
674+
}

0 commit comments

Comments
 (0)