From 767101326fbb64ab882d70c0b613dbd67e24c860 Mon Sep 17 00:00:00 2001 From: Moksh Panicker Date: Fri, 25 Sep 2026 14:00:07 +0530 Subject: [PATCH] lib: sbi: pmu: Validate reserved bits in counter config match flags 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. Verified with an isolated test 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 correctly return SBI_ERR_INVALID_PARAM, while valid flag combinations (SKIP_MATCH, CLEAR_VALUE, AUTO_START, and the inhibit flags) are unaffected. Signed-off-by: Moksh Panicker --- include/sbi/sbi_ecall_interface.h | 9 ++++++++- lib/sbi/sbi_pmu.c | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/include/sbi/sbi_ecall_interface.h b/include/sbi/sbi_ecall_interface.h index fd4e77ca..c0485d5c 100644 --- a/include/sbi/sbi_ecall_interface.h +++ b/include/sbi/sbi_ecall_interface.h @@ -302,7 +302,14 @@ struct sbi_pmu_event_info { SBI_PMU_CFG_FLAG_SET_SINH | \ 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 e79f6b60..b2c14c12 100644 --- a/lib/sbi/sbi_pmu.c +++ b/lib/sbi/sbi_pmu.c @@ -924,6 +924,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