Skip to content

Bug: RTT/WDT callback setup can let overflow or early-warning IRQs use new callback state before setup finishes #22411

Description

@andrewlihhh

Description

These RTT/WDT paths share the same basic issue: callback/context is updated first, while pending IRQ or peripheral event state may still fire.

Common sequence:

  1. thread context updates overflow or early-warning callback state
  2. pending IRQ or peripheral event state is not fully cleared yet
  3. overflow / early-warning IRQ arrives in that window
  4. ISR uses the new callback/context before setup has finished

Related issues:

  • Tracking issue: #22405
  • See also #22384, which discusses a similar issue shape in another RIOT driver.

Scope

  • RIOT source snapshot: bbe5252d00f98658fc6493ede1a3e9f8f4102f9d (2026-06-08)
  • Affected files:
    • cpu/esp32/periph/rtt.c
    • cpu/nrf5x_common/periph/rtt.c
    • cpu/sam0_common/periph/wdt.c
  • Grouped cases:
    • esp32-rtt-unique-1-rtt-counter-overflow-cb
    • esp32-rtt-unique-2-rtt-counter-overflow-arg
    • esp32-rtt-unique-3-rtt-counter-overflow-cb
    • nrf5x-rtt-overflow-reinit-bug
    • samd5x-wdt-reinit-bug

Representative code paths

  • ESP32 RTT: rtt_set_overflow_cb() / _rtt_update_hw_alarm() -> _rtt_isr()
  • nRF5x RTT: rtt_set_overflow_cb() -> ISR()
  • SAM0 WDT: wdt_setup_reboot_with_callback() -> isr_wdt()

Representative source snippets

cpu/esp32/periph/rtt.c updates overflow callback/context state:

void rtt_set_overflow_cb(rtt_cb_t cb, void *arg)
{
    rtt_counter.overflow_cb = cb;
    rtt_counter.overflow_arg = arg;
    _rtt_update_hw_alarm();
}

The RTT ISR later consumes that callback/context:

if (rtt_counter.overflow_cb) {
    rtt_counter.overflow_cb(rtt_counter.overflow_arg);
}

cpu/nrf5x_common/periph/rtt.c has the same overflow callback/context pattern:

void rtt_set_overflow_cb(rtt_cb_t cb, void *arg)
{
    overflow_cb = cb;
    overflow_arg = arg;
}
overflow_cb(overflow_arg);

cpu/sam0_common/periph/wdt.c stores early-warning callback/context before the WDT ISR consumes it:

cb = wdt_cb;
cb_arg = arg;
if (cb != NULL) {
    cb(cb_arg);
}

Expected results

Overflow or early-warning IRQ handlers should not use the new callback/context before callback setup has finished.

Actual results

Overflow or early-warning IRQ handlers may use the new callback/context too early.

Analysis

These drivers update callback/context first, while pending overflow or early-warning IRQ state may still fire.

That lets the ISR observe new callback/context even though the pending interrupt condition has not been fully cleared yet.

Suggested Fix

  • disable overflow/early-warning IRQ delivery before replacing callback/context
  • clear pending interrupt/event state before re-enabling
  • re-enable only after callback/context and rest of setup are complete
  • if reconfiguration is unsupported for same instance, document that clearly

Metadata

Metadata

Assignees

No one assigned

    Labels

    AI: VibedPR/Issue appears to be more AI than Human.Type: bugThe issue reports a bug / The PR fixes a bug (including spelling errors)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions