[PATCH] lib: sbi_sse: fix shared memory double-fetch in sse_write_attrs
liutong
liutong at iscas.ac.cn
Sun Jun 28 02:21:10 PDT 2026
sse_write_attrs() reads attribute values from S-mode shared memory in
two passes: first to validate, then to apply. Since the shared memory
remains writable by S-mode between the two reads, the values used for
application may differ from what was validated.
Fix this by snapshotting the shared memory data into a local buffer
and performing both validation and application against that snapshot.
Signed-off-by: liutong <liutong at iscas.ac.cn>
---
lib/sbi/sbi_sse.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/lib/sbi/sbi_sse.c b/lib/sbi/sbi_sse.c
index 818afb87..0a6505b7 100644
--- a/lib/sbi/sbi_sse.c
+++ b/lib/sbi/sbi_sse.c
@@ -1064,25 +1064,28 @@ static int sse_write_attrs(struct sbi_sse_event *e, uint32_t base_attr_id,
unsigned long attr = 0, val;
uint32_t id, end_id = base_attr_id + attr_count;
unsigned long *attrs = (unsigned long *)input_phys;
+ unsigned long local_attrs[SBI_SSE_ATTR_MAX];
sbi_hart_protection_map_range(input_phys, sizeof(unsigned long) * attr_count);
+ /* Snapshot shared memory into a local buffer to prevent TOCTOU */
+ copy_attrs(local_attrs, attrs, attr_count);
+
+ sbi_hart_protection_unmap_range(input_phys, sizeof(unsigned long) * attr_count);
+
for (id = base_attr_id; id < end_id; id++) {
- val = attrs[attr++];
+ val = local_attrs[attr++];
ret = sse_event_set_attr_check(e, id, val);
if (ret)
- goto out;
+ return ret;
}
attr = 0;
for (id = base_attr_id; id < end_id; id++) {
- val = attrs[attr++];
+ val = local_attrs[attr++];
sse_event_set_attr(e, id, val);
}
-out:
- sbi_hart_protection_unmap_range(input_phys, sizeof(unsigned long) * attr_count);
-
return ret;
}
--
2.34.1
More information about the opensbi
mailing list