Skip to content

Use 4KiB L3 pages for mixed-permission 2MiB block#2

Merged
jserv merged 1 commit intomainfrom
4k-page
May 4, 2026
Merged

Use 4KiB L3 pages for mixed-permission 2MiB block#2
jserv merged 1 commit intomainfrom
4k-page

Conversation

@jserv
Copy link
Copy Markdown
Contributor

@jserv jserv commented May 4, 2026

guest_build_page_tables OR-merged perms when multiple regions shared a 2MiB block, collapsing small static binaries' .text RX + .data RW + heap RW into one RWX block. The pair-only post-build fixup in bootstrap.c only handled adjacent array pairs, and exec.c had no fixup at all so execve into a small binary left the merged RWX state.

The new finalize_block_perms at the end of guest_build_page_tables splits any 2MiB block where the input regions disagree on perms or leave gaps, applies the union of perms per 4KiB page, and leaves uncovered pages invalid. Idempotent across overlapping regions, so no visited-set is needed.

Bundled adjustments: VDSO declared as an explicit boot region in bootstrap.c and exec.c (it previously rode the shim's RX block); MAX_REGIONS / MAX_BOOT_REGIONS bumped to 8 + 2*ELF_MAX_SEGMENTS and silent segment truncation in execve turned into a fatal abort; build_boot_regions / load_interpreter / finalize_block_perms switched to bool returns where the only meaningful values are success/failure; BLOCK_2MB family and \d+(KB|MB|GB|TB) literals swept to IEC binary prefixes (BLOCK_2MIB, KiB/MiB/GiB/TiB) across src/ and tests/. Lowercase 'kB' in /proc/meminfo and /proc/self/status emulation kept verbatim for Linux ABI compat.


Summary by cubic

Fixes mixed-permission 2MiB blocks by splitting them into 4KiB L3 pages and applying per-page permissions, preventing OR-merged RWX and leaving gaps invalid. Ensures correct W^X for small static binaries on both bootstrap and execve, and keeps the vDSO RX when sharing a block with the shim.

  • Bug Fixes

    • Added finalize pass in guest_build_page_tables to split any 2MiB block with mixed perms or gaps, union perms per 4KiB page, and leave uncovered pages invalid.
    • Made the vDSO an explicit boot/exec region so the trampoline page stays RX after block splitting.
  • Refactors

    • Increased MAX_REGIONS/MAX_BOOT_REGIONS to 8 + 2*ELF_MAX_SEGMENTS; exec segment overflow now aborts instead of truncating.
    • Switched build_boot_regions/load_interpreter/finalize_block_perms to bool returns.
    • Renamed BLOCK_2MBBLOCK_2MIB and standardized units to KiB/MiB/GiB/TiB across code and tests (kept Linux ABI kB strings in /proc emulation).

Written for commit fb5e253. Summary will update on new commits.

guest_build_page_tables OR-merged perms when multiple regions shared a
2MiB block, collapsing small static binaries' .text RX + .data RW + heap
RW into one RWX block. The pair-only post-build fixup in bootstrap.c
only handled adjacent array pairs, and exec.c had no fixup at all so
execve into a small binary left the merged RWX state.

The new finalize_block_perms at the end of guest_build_page_tables
splits any 2MiB block where the input regions disagree on perms or leave
gaps, applies the union of perms per 4KiB page, and leaves uncovered
pages invalid. Idempotent across overlapping regions, so no visited-set
is needed.

Bundled adjustments: VDSO declared as an explicit boot region in
bootstrap.c and exec.c (it previously rode the shim's RX block);
MAX_REGIONS / MAX_BOOT_REGIONS bumped to 8 + 2*ELF_MAX_SEGMENTS and
silent segment truncation in execve turned into a fatal abort;
build_boot_regions / load_interpreter / finalize_block_perms switched
to bool returns where the only meaningful values are success/failure;
BLOCK_2MB family and \d+(KB|MB|GB|TB) literals swept to IEC binary
prefixes (BLOCK_2MIB, KiB/MiB/GiB/TiB) across src/ and tests/.
Lowercase 'kB' in /proc/meminfo and /proc/self/status emulation kept
verbatim for Linux ABI compat.
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 38 files

@jserv jserv merged commit 7aab53e into main May 4, 2026
5 checks passed
@jserv jserv deleted the 4k-page branch May 4, 2026 19:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant