[PATCH v3] lib: sbi: pmu: Validate reserved bits in counter config match flags

Moksh Panicker mokshpanicker.7 at gmail.com
Sun Nov 1 02:39:31 PST 2026


The sbi_pmu_ctr_cfg_match() function (SBI_EXT_PMU_COUNTER_CFG_MATCH,
FID #2) does not validate the flags argument against reserved bits.

Per the SBI specification PMU extension, Table 8 (PMU Counter Config
Match Flags) defines bits 0 through 7 only, and Table 9 (PMU Counter
Config Match Errors) requires SBI_ERR_INVALID_PARAM when the flags
parameter has a reserved bit set. Currently any bit from 8 to 63 is
silently accepted and the call succeeds.

sbi_pmu_ctr_start() and sbi_pmu_ctr_stop() already guard their flags
arguments with SBI_PMU_START_FLAGS_MASK and SBI_PMU_STOP_FLAGS_MASK
respectively. This adds the equivalent SBI_PMU_CFG_FLAGS_VALID_MASK
guard for sbi_pmu_ctr_cfg_match(), following the same pattern.

This is unrelated to CVE-2025-63913, which concerns cidx_mask == 0
in the same function and was fixed by commit 69a0f024 ("lib: sbi:
pmu: Return SBI_EINVAL if cidx_mask is 0"), already present in this
tree. That fix does not touch flags validation.

Tested with a small S-mode harness on QEMU virt (platform/generic):
flags with bit 8, bit 20, and all reserved bits set previously
returned SBI_SUCCESS; after this fix they return
SBI_ERR_INVALID_PARAM, while valid flags (none, and CLEAR_VALUE)
still succeed.

Signed-off-by: Moksh Panicker <mokshpanicker.7 at gmail.com>
---
Changes in v3:
- Dropped unrelated SBI_EINVAL conversions that were accidentally included in v2.

Changes in v2:
- Rebased on current master and resent with git send-email as requested.
 include/sbi/sbi_ecall_interface.h | 9 +++++++++
 lib/sbi/sbi_pmu.c                 | 2 ++
 2 files changed, 11 insertions(+)

diff --git a/include/sbi/sbi_ecall_interface.h b/include/sbi/sbi_ecall_interface.h
index fd4e77ca..cfc5db95 100644
--- a/include/sbi/sbi_ecall_interface.h
+++ b/include/sbi/sbi_ecall_interface.h
@@ -303,6 +303,15 @@ struct sbi_pmu_event_info {
 		SBI_PMU_CFG_FLAG_SET_MINH    \
 	)
 
+/* Config match flags valid mask */
+#define SBI_PMU_CFG_FLAGS_VALID_MASK    \
+	( \
+		SBI_PMU_CFG_FLAG_SKIP_MATCH  | \
+		SBI_PMU_CFG_FLAG_CLEAR_VALUE | \
+		SBI_PMU_CFG_FLAG_AUTO_START  | \
+		SBI_PMU_CFG_EVENT_MASK         \
+	)
+
 /* Flags defined for counter start function */
 #define SBI_PMU_START_FLAG_SET_INIT_VALUE (1 << 0)
 #define SBI_PMU_START_FLAG_INIT_FROM_SNAPSHOT (1 << 1)
diff --git a/lib/sbi/sbi_pmu.c b/lib/sbi/sbi_pmu.c
index a043dc7c..2540043c 100644
--- a/lib/sbi/sbi_pmu.c
+++ b/lib/sbi/sbi_pmu.c
@@ -930,6 +930,8 @@ int sbi_pmu_ctr_cfg_match(unsigned long cidx_base, unsigned long cidx_mask,
 	event_type = pmu_event_validate(phs, event_idx, event_data);
 	if (event_type < 0)
 		return SBI_EINVAL;
+	if (flags & ~SBI_PMU_CFG_FLAGS_VALID_MASK)
+		return SBI_ERR_INVALID_PARAM;
 	event_code = get_cidx_code(event_idx);
 
 	if (flags & SBI_PMU_CFG_FLAG_SKIP_MATCH) {
-- 
2.34.1




More information about the opensbi mailing list