Skip to content

seagate: clamp fw-activate-history entry count, bound JSON string copies - #3993

Merged
igaw merged 1 commit into
linux-nvme:masterfrom
prabhakarpujeri:fix-seagate-fw-history
Sep 8, 2026
Merged

igaw merged 1 commit into
linux-nvme:masterfrom
prabhakarpujeri:fix-seagate-fw-history

Conversation

@prabhakarpujeri

Copy link
Copy Markdown

Problem

The Seagate 0xC2 vendor log page is device-supplied, and the
fw-activate-history display paths trusted two fields in it:

  1. numValidFwActHisEnt (a device u32) was used directly as the loop
    bound against the compiled-in fwActHisEnt[20] table — a count >
    20 walks past the table in both the plain and JSON views.
  2. The JSON view copied previousFW / newFW with
    sprintf(char[8], "%s", …) from fixed-width u8[8] fields that carry
    no NUL guarantee — a malformed page gives a device-controlled stack
    overflow (the plain view copies by size into 9-byte buffers and is
    safe).

Fix

  • Clamp numValidFwActHisEnt to the table size immediately after the
    single log read, so both display paths can only walk real entries.
  • Make the JSON view copy the fixed-width strings by size into 9-byte
    zeroed buffers, exactly mirroring the plain-print path construction.

The clamp mutates only the local stack struct and only on the success
path; nothing prints the raw count afterwards, so the display simply
tops out at the table size.

Validation

  • Full meson build clean (nvme.link, all plugins).
  • ASan/UBSan harness replicating the exact old and new expressions with
    adversarial fixtures (numValidFwActHisEnt = 0xffffffff, 8-byte FW
    fields without NULs): pre-fix path reports stack-buffer-overflow in
    old_json_path; fixed path passes clamp-max-20, pass-through on
    small counts, and 8-byte NUL-termination checks (4/4).

…copy

The 0xC2 vendor log page is device-supplied.  Two lapses on the
fw-activate-history display paths:

- numValidFwActHisEnt (device u32) was used as the loop bound against
  the compiled-in fwActHisEnt[20] table.  Clamp it to the table size
  right after the read so both the plain and JSON views can only walk
  the entries actually present.
- the JSON view used sprintf(prev_fw, "%s", previousFW) into 8-byte
  buffers, but previousFW/newFW are fixed-width fields with no NUL
  guarantee, so a malformed page would walk past the buffer giving a
  device-controlled stack overflow.  Switch to 9-byte zeroed buffers
  with an explicit size copy, mirroring the plain-print path.

Signed-off-by: Prabhakar Pujeri <prabhakar.pujeri@dell.com>
@igaw
igaw merged commit 95c2d2b into linux-nvme:master Sep 8, 2026
31 of 32 checks passed
@igaw

igaw commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator

Thanks!

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.

2 participants