Skip to content

Improve guest exception handling to prevent infinite loops #1118

Open

Description

@simongdavies

When the guest exception handler itself fails (due to corrupted stack, unmapped memory etc.), the guest enters an unrecoverable state— causing either an infinite page fault loop (hang) or a triple fault (crash). This occurs because:

  1. The exception handler entry point requires a working stack (for context_save!() pushes)
  2. The Rust handler uses format!() which allocates on the heap
  3. There's no detection of nested/recursive exceptions

A triple fault is not a terrible outcome as at least the guest terminates but having the infinite page loop is more of a problem, if the host is monitoring execution and kills the guest via the InterruptHandle then it should be able to successfully terminate the guest , but if it is not doing this then a badly behaved guest could cause resource (CPU) starvation.

There are a couple of things that we can do to protect against this:

Configure a small permanent fixed stack in the ISS that can be used for a double fault handler.
Detect exception handler re-entrancy and exit immediately with outb data that the host can translate to a DoubleFault error.

This is another reason that we should consider not allowing guest code to run in ring 0.

Activity

  1. changed the title [-]Improve guest exception handling to infinite loops[/-] [+]Improve guest exception handling to prevent infinite loops[/+] on Dec 15, 2025
  2. syntactically commented on Dec 16, 2025

    @syntactically
    Member

    An IST exception stack is added in 6211e98, since the interrupt handler becomes involved in growing the main stack, and the handler always runs on the top of that stack since there isn't any expected reentrancy.

    Separately, I think that it is a bug that the handler can allocate. When doing the snapshot CoW, it is careful not to allocate before that is done since that would go badly, but it would be preferable not to allocate at all, and I don't believe there is a strong reason to be allocating.

    Having the assembly entry stub check for reentrancy is a reasonable idea, but I'm unsure if it is worth it if the exception handler is small and well-behaved (which it probably should be).

  3. added
    lifecycle/confirmedBug is verified or proposal seems reasonable
    and removed on Dec 17, 2025
  4. added theissue type on Dec 17, 2025
  5. added this to the v0.13.0 milestone on Dec 17, 2025
  6. modified the milestones: v0.13.0, Backlog on Feb 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    lifecycle/confirmedBug is verified or proposal seems reasonable

    Type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions