Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
66 changes: 66 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,72 @@ jobs:
env:
XAIOS_QEMU_SMOKE_TIMEOUT: "120"

parser-fuzz:
name: Parser Fuzzing
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v6
with:
submodules: recursive

- name: Install toolchain
run: |
sudo apt-get update
sudo apt-get install -y clang lld llvm python3

# Every one of these parsers is reachable before authentication: the SSH
# binary packet layer, the DNS/DNSSEC response path, and the SFTP request
# decoder. The corpus is carried between runs so each campaign starts
# from the coverage the previous one reached instead of from one seed.
- name: Restore fuzzing corpus
uses: actions/cache@v5
with:
path: build/fuzz
key: parser-fuzz-corpus-${{ github.sha }}
restore-keys: |
parser-fuzz-corpus-

- name: Run bounded coverage-guided campaign
run: make parser-fuzz
env:
XAIOS_FUZZ_RUNS: "300000"

- name: Upload crashes and corpus
if: always()
uses: actions/upload-artifact@v7
with:
name: parser-fuzz-evidence
path: |
build/fuzz/*-corpus/**
build/fuzz/crash-*
build/fuzz/leak-*
build/fuzz/timeout-*
if-no-files-found: ignore
retention-days: 14

persistence-reboot:
name: Persistence Across Reboot
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
submodules: recursive

- name: Install toolchain
run: |
sudo apt-get update
sudo apt-get install -y clang lld llvm meson ninja-build qemu-system-arm qemu-efi-aarch64 mtools python3 python3-cryptography

# Boots twice against one VirtIO volume and requires the second boot to
# reload the state the first wrote. Nothing else in CI covers durability
# across a restart, which is how a persistence subsystem that wrote to a
# snapshot-backed device went unnoticed.
- name: Verify snapshot state survives a reboot
run: make qemu-persistence-reboot
env:
XAIOS_QEMU_PERSISTENCE_TIMEOUT: "180"

model-storage-interoperability:
name: ModelFS SFTP Interoperability
runs-on: ubuntu-latest
Expand Down
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,11 @@ hosted-test: engine-cli
-Ikernel/include kernel/fs/vfs.c tests/storage/test_vfs.c \
-o build/hosted/test-vfs
./build/hosted/test-vfs
$(HOST_CC) $(HOST_CFLAGS) \
-Ikernel/include kernel/fs/mutable_fs.c kernel/dev/block_device.c \
tests/storage/test_mutable_fs_mirror.c \
-o build/hosted/test-mutable-fs-mirror
./build/hosted/test-mutable-fs-mirror
$(HOST_CC) $(HOST_CFLAGS) \
-Iuserspace/include -Iuserspace/sshd -Iuserspace/apps/terminal \
-Ikernel/include \
Expand Down
8 changes: 6 additions & 2 deletions boot/uefi/include/uefi_min.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,12 @@ struct efi_graphics_output_protocol_mode {
};

struct efi_graphics_output_protocol {
void *query_mode;
void *set_mode;
efi_status_t(EFIAPI *query_mode)(
efi_graphics_output_protocol_t *self, uint32_t mode_number,
uint64_t *size_of_info,
efi_graphics_output_mode_information_t **info);
efi_status_t(EFIAPI *set_mode)(efi_graphics_output_protocol_t *self,
uint32_t mode_number);
void *blt;
efi_graphics_output_protocol_mode_t *mode;
};
Expand Down
49 changes: 49 additions & 0 deletions boot/uefi/loader_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,54 @@ static void collect_firmware_entropy(efi_system_table_t *system_table,
boot_info->entropy_seed_size = XAIOS_BOOT_INFO_ENTROPY_SEED_BYTES;
}

/* Firmware hands over whatever mode it happened to be in, which on VMware
Fusion is 1024x768. The console renders an 8x8 font into that, so the guest
looks like a DOS box on a modern display. Pick the largest mode the firmware
offers in a directly addressable 32-bit format, bounded so an unusually
large mode cannot produce a framebuffer the kernel will not map. */
#define LOADER_MAX_DISPLAY_WIDTH UINT32_C(2560)
#define LOADER_MAX_DISPLAY_HEIGHT UINT32_C(1600)

static void select_display_mode(efi_graphics_output_protocol_t *gop) {
if (gop == 0 || gop->query_mode == 0 || gop->set_mode == 0 ||
gop->mode == 0 || gop->mode->max_mode == 0U) {
return;
}
uint32_t best_mode = gop->mode->mode;
uint64_t best_pixels = 0U;
if (gop->mode->info != 0) {
best_pixels = (uint64_t)gop->mode->info->horizontal_resolution *
(uint64_t)gop->mode->info->vertical_resolution;
}
for (uint32_t candidate = 0U; candidate < gop->mode->max_mode; ++candidate) {
efi_graphics_output_mode_information_t *info = 0;
uint64_t size_of_info = 0U;
if (is_error(gop->query_mode(gop, candidate, &size_of_info, &info)) ||
info == 0) {
continue;
}
/* Only the two packed 32-bit formats are drawable by the kernel. */
if (info->pixel_format > 1U) continue;
if (info->horizontal_resolution == 0U || info->vertical_resolution == 0U ||
info->pixels_per_scan_line < info->horizontal_resolution) {
continue;
}
if (info->horizontal_resolution > LOADER_MAX_DISPLAY_WIDTH ||
info->vertical_resolution > LOADER_MAX_DISPLAY_HEIGHT) {
continue;
}
uint64_t pixels = (uint64_t)info->horizontal_resolution *
(uint64_t)info->vertical_resolution;
if (pixels > best_pixels) {
best_pixels = pixels;
best_mode = candidate;
}
}
if (best_mode != gop->mode->mode) {
(void)gop->set_mode(gop, best_mode);
}
}

static void collect_framebuffer(efi_system_table_t *system_table,
xaios_boot_info_t *boot_info) {
if (system_table == 0 || system_table->boot_services == 0 ||
Expand All @@ -174,6 +222,7 @@ static void collect_framebuffer(efi_system_table_t *system_table,
gop->mode->framebuffer_size == 0U) {
return;
}
select_display_mode(gop);
const efi_graphics_output_mode_information_t *info = gop->mode->info;
if (info->horizontal_resolution == 0U || info->vertical_resolution == 0U ||
info->pixels_per_scan_line < info->horizontal_resolution ||
Expand Down
Loading
Loading