hw/ufs: Validate MCQ SQ references before use
A guest can program an out-of-range SQATTR.CQID value, or ring an MCQ SQ doorbell before the submission queue exists. Reject SQ creation when the referenced CQ is invalid, and ignore SQ doorbells for queues that have not been created. This prevents a guest-triggerable out-of-bounds read and NULL pointer dereference. Fixes: 5c079578d2e ("hw/ufs: Add support MCQ of UFSHCI 4.0") Reported-by: Rayhan Ramdhany Hanaputra <hanaputrarayhan@gmail.com> Cc: qemu-stable@nongnu.org Signed-off-by: Jeuk Kim <jeuk20.kim@samsung.com>
Jeuk Kim committed
Mar 16, 2026 at 14:39 UTC
332ea29787800fff2b49e9b89ec93bd370a11965
1 file changed
+19
-2
hw/ufs/ufs.c
+19
-2
@@ -517,8 +517,13 @@ static bool ufs_mcq_create_sq(UfsHc *u, uint8_t qid, uint32_t attr)
517
return false;
518
}
519
520
+ if (cqid >= u->params.mcq_maxq) {
521
+ trace_ufs_err_mcq_create_sq_invalid_cqid(cqid);
522
+ return false;
523
+ }
524
+
525
if (!u->cq[cqid]) {
521
- trace_ufs_err_mcq_create_sq_invalid_cqid(qid);
526
+ trace_ufs_err_mcq_create_sq_invalid_cqid(cqid);
527
return false;
528
}
529
@@ -775,6 +780,11 @@ static void ufs_mcq_process_db(UfsHc *u, uint8_t qid, uint32_t db)
780
}
781
782
sq = u->sq[qid];
783
+ if (!sq) {
784
+ trace_ufs_err_mcq_db_wr_invalid_sqid(qid);
785
+ return;
786
+ }
787
+
788
if (sq->size * sizeof(UfsSqEntry) <= db) {
789
trace_ufs_err_mcq_db_wr_invalid_db(qid, db);
790
return;
@@ -788,7 +798,14 @@ static void ufs_write_mcq_op_reg(UfsHc *u, hwaddr offset, uint32_t data,
798
unsigned size)
799
{
800
int qid = offset / sizeof(UfsMcqOpReg);
791
- UfsMcqOpReg *opr = &u->mcq_op_reg[qid];
801
+ UfsMcqOpReg *opr;
802
+
803
+ if (qid >= u->params.mcq_maxq) {
804
+ trace_ufs_err_invalid_register_offset(offset);
805
+ return;
806
+ }
807
+
808
+ opr = &u->mcq_op_reg[qid];
809
810
switch (offset % sizeof(UfsMcqOpReg)) {
811
case offsetof(UfsMcqOpReg, sq.tp):