riscv-software-src / riscv-software-src/opensbi

DBTR: validate trig_count before mapping shared memory in sbi_dbtr_install_trig()

Open
#426 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C
Stars
1.5k
Forks
712
PR merge metrics
No merged PRs in 30d

Description

Problem

sbi_dbtr_install_trig() uses the caller-provided trig_count to compute the shared-memory range length before checking whether that count is reasonable:

sbi_hart_protection_map_range((unsigned long)shmem_base,
                              trig_count * sizeof(*entry));

The same trig_count * sizeof(*entry) expression is also used on several cleanup paths. On RV64, a sufficiently large trig_count can make this byte-size calculation wrap, so the mapped range can be smaller than the later loop expects.

The function does check hs->available_trigs < trig_count, but that happens only after the shared-memory mapping and after the first validation loop has already iterated over entries using trig_count.

Observed result

In a local QEMU virt test with DBTR shared memory set up first, the normal control case returned successfully. The overflow case then hit an M-mode trap and did not return before timeout.

Suggested fix

Validate trig_count before using it in the byte-size calculation or in the trigger-entry loop. For example, reject counts larger than the implementation limit before mapping:

if (trig_count > RV_MAX_TRIGGERS)
        return SBI_ERR_INVALID_PARAM;

Scope

I have only validated the firmware fault/hang behavior on QEMU. I am not claiming a broader impact beyond this memory-safety/availability issue.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at sbi_dbtr_install_trig() and trace every use of trig_count, especially the shared-memory mapping, cleanup paths, and validation loop. Reproduce the normal and overflow cases on QEMU virt, then verify that oversized counts are rejected before any size calculation or entry iteration and that the control case still succeeds.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
operating-systems, security
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
62/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.