Skip to content

flash: guard flashFlush() against a NULL flush callback - #11943

Open
xhlsa wants to merge 1 commit into
iNavFlight:maintenance-10.xfrom
xhlsa:up/flashflush-null-guard
Open

xhlsa wants to merge 1 commit into
iNavFlight:maintenance-10.xfrom
xhlsa:up/flashflush-null-guard

Conversation

@xhlsa

@xhlsa xhlsa commented Sep 14, 2026

Copy link
Copy Markdown

Problem

flashFlush() calls flash->flush() unconditionally. The M25P16 (NOR) entry in flashDrivers[] sets .flush = NULL, which has been the case since W25N support was added in #8166.

On a NOR chip, flashfsFlushSync() therefore jumps through NULL whenever it runs with a non-empty write buffer:

  • flashfsReadAbs() or flashfsSeekAbs()/flashfsSeekRel() while buffered data has not been drained yet
  • CLI flash_write on USE_FLASH_TOOLS builds, which always syncs a dirty buffer

In normal blackbox use, the async flush empties the buffer before a read, so the defect is latent rather than a common crash. It was found by code review while bringing up an M25P16-driver chip, not from a field report.

Fix

Call flush only when a flash device is present and the driver provides the callback. The W25N path is unchanged.

The M25P16/W25Q (NOR) drivers do not set flashVTable_t.flush, so
flashFlush() jumps through NULL and hard-faults on blackbox read or seek
on those chips. Also guard against no flash device being detected.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@xhlsa
xhlsa marked this pull request as ready for review September 14, 2026 04:22
@qodo-code-review

Copy link
Copy Markdown
Contributor

ⓘ Qodo reviews are paused because the subscription is no longer active. Ask your workspace admin to reactivate the subscription to resume reviews. Manage billing

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

Tip of the day
💡 Did you know, you can ask Qodo to dismiss a finding you disagree with, with your reason on record

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Guard flashFlush against missing device or callback

🐞 Bug fix 🕐 Less than 5 minutes

Grey Divider

AI Description

• Prevents flashFlush() from dereferencing an absent flash device or flush callback.
• Preserves W25N flushing while making NOR and undetected-device paths safe.
Diagram

graph TD
  A["FlashFS sync"] --> B["flashFlush"] --> C{"Device and callback?"}
  C -->|Yes| D["Driver flush"]
  C -->|No| E["Safe no-op"]
Loading
High-Level Assessment

The centralized guard is the best approach because flush is an optional driver operation and flash may be unset. Assigning a no-op callback to NOR drivers would not protect the undetected-device case and would distribute optional-operation handling across driver definitions.

Files changed (1) +3 / -1

Bug fix (1) +3 / -1
flash.cSafely invoke the optional flash flush callback +3/-1

Safely invoke the optional flash flush callback

• Checks that a flash device was detected and that its driver supplies a flush callback before invocation. This prevents null-function-pointer hard faults for M25P16/W25Q NOR devices and absent hardware while preserving W25N behavior.

src/main/drivers/flash.c

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