PageProtect
Description
Change the protection of a range of pages. ptr and bytes must be page-aligned and page-sized respectively; the typical pattern is to apply this to a region returned by PageAllocator allocation (which is always page-grain).
Parameters
| Name | Direction | Description |
|---|---|---|
ptr |
in,out | First byte of the region; must be page-aligned. |
bytes |
in | Region size; must be a multiple of the OS page size. |
prot |
in | New protection bits. |
Success
Returns true. The new protection is in effect for the entire [ptr, ptr+bytes) range.
Failure
Returns false and logs the failing syscall (mprotect / VirtualProtect). The region’s protection is unchanged in the failure case.
Usage example (Cross-references)
Usage examples (Cross-references)
- In
Debug.c:386:
size page_size = PageAllocatorPageSize(&self->page);
size rounded = (padded + page_size - 1) & ~(page_size - 1);
if (!PageProtect(ptr, rounded, PAGE_PROT_NONE)) {
LOG_ERROR("DebugAllocator: PageProtect(PROT_NONE) failed on {x}", (u64)ptr);
}- In
Debug.c:387:
size rounded = (padded + page_size - 1) & ~(page_size - 1);
if (!PageProtect(ptr, rounded, PAGE_PROT_NONE)) {
LOG_ERROR("DebugAllocator: PageProtect(PROT_NONE) failed on {x}", (u64)ptr);
}
} else {- In
Page.c:532:
}
bool PageProtect(void *ptr, size bytes, PageProtection prot) {
if (!ptr || !bytes) {
return false;- In
Page.c:550:
break;
default :
LOG_ERROR("PageProtect: unknown protection bit {}", (u32)prot);
return false;
}- In
Page.c:555:
DWORD old_prot = 0;
if (!VirtualProtect(ptr, (SIZE_T)bytes, win_prot, &old_prot)) {
LOG_ERROR("PageProtect: VirtualProtect failed (error {})", (u32)GetLastError());
return false;
}- In
Page.c:572:
break;
default :
LOG_ERROR("PageProtect: unknown protection bit {}", (u32)prot);
return false;
}- In
Page.c:578:
long ret = direct_sys3(MISRA_SYS_mprotect, (long)(u64)ptr, (long)bytes, (long)posix_prot);
if (ret != 0) {
LOG_SYS_ERROR(ErrnoOf((i32)ret), "PageProtect: mprotect failed");
return false;
}- In
Page.c:586:
// off): mprotect returns -1 and the system error is recovered
// through ErrnoOf below.
LOG_SYS_ERROR(ErrnoOf(-1), "PageProtect: mprotect failed");
return false;
}- In
PageProtect.c:25:
// protection here; that would need SIGSEGV handling.)
bool ok = true;
ok = ok && PageProtect(region, page_bytes, PAGE_PROT_NONE);
ok = ok && PageProtect(region, page_bytes, PAGE_PROT_READ_WRITE);
ok = ok && bytes[0] == 0xab && bytes[1] == 0xcd;- In
PageProtect.c:26:
bool ok = true;
ok = ok && PageProtect(region, page_bytes, PAGE_PROT_NONE);
ok = ok && PageProtect(region, page_bytes, PAGE_PROT_READ_WRITE);
ok = ok && bytes[0] == 0xab && bytes[1] == 0xcd;- In
PageProtect.c:31:
// Also exercise read-only: write before, drop to READ, restore.
bytes[2] = 0xef;
ok = ok && PageProtect(region, page_bytes, PAGE_PROT_READ);
ok = ok && bytes[2] == 0xef;
ok = ok && PageProtect(region, page_bytes, PAGE_PROT_READ_WRITE);- In
PageProtect.c:33:
ok = ok && PageProtect(region, page_bytes, PAGE_PROT_READ);
ok = ok && bytes[2] == 0xef;
ok = ok && PageProtect(region, page_bytes, PAGE_PROT_READ_WRITE);
AllocatorFree(&page, region);- In
PageProtect.c:41:
int main(void) {
WriteFmt("[INFO] Starting PageProtect tests\n\n");
TestFunction tests[] = {- In
PageProtect.c:47:
};
return run_test_suite(tests, sizeof(tests) / sizeof(tests[0]), NULL, 0, "PageProtect");
}
Last updated on