Skip to content

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 page_allocator_allocate (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)
        // 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;
        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;
        // 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);
        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(base, region, page_bytes);
    
    int main(void) {
        WriteFmt("[INFO] Starting PageProtect tests\n\n");
    
        TestFunction tests[] = {
        };
    
        return run_test_suite(tests, sizeof(tests) / sizeof(tests[0]), NULL, 0, "PageProtect");
    }
    }
    
    bool PageProtect(void *ptr, size bytes, PageProtection prot) {
        if (!ptr || !bytes) {
            return false;
                break;
            default :
                LOG_ERROR("PageProtect: unknown protection bit {}", (u32)prot);
                return false;
        }
        DWORD old_prot = 0;
        if (!VirtualProtect(ptr, (SIZE_T)bytes, win_prot, &old_prot)) {
            LOG_ERROR("PageProtect: VirtualProtect failed (error {})", (u32)GetLastError());
            return false;
        }
                break;
            default :
                LOG_ERROR("PageProtect: unknown protection bit {}", (u32)prot);
                return false;
        }
        }
        if (mprotect(ptr, (size_t)bytes, posix_prot) != 0) {
            LOG_SYS_ERROR("PageProtect: mprotect failed");
            return false;
        }
Last updated on