@samitouri / QOSamiQemu / commits / c6aa2d0ac1

aspeed/hace: Prevent total_req_len overflow

In accumulate mode, total_req_len is incremented with plen (hwaddr) for each hash request. Repeated additions can overflow total_req_len (uint32_t) and potentially bypass validation checks in has_padding(). Add a helper function to detect overflow before incrementing total_req_len and reject the request if overflow would occur. Reported-by: Katherine Leaver <katherine.j.leaver@gmail.com> Cc: qemu-stable@nongnu.org Fixes: 5cd7d8564a8b ("aspeed/hace: Support AST2600 HACE") Link: https://lore.kernel.org/qemu-devel/20260504213421.710035-3-clg@redhat.com Signed-off-by: Cédric Le Goater <clg@redhat.com>

Cédric Le Goater committed May 4, 2026 at 23:34 UTC c6aa2d0ac161f2a58a8fbab9a15e846278661158
1 file changed +19 -2
hw/misc/aspeed_hace.c
+19 -2
@@ -205,6 +205,19 @@ static uint64_t hash_get_source_addr(AspeedHACEState *s)
205 return src_addr;
206 }
207
208 +static bool hash_accumulate_len(AspeedHACEState *s, hwaddr plen)
209 +{
210 + if (plen > UINT32_MAX - s->total_req_len) {
211 + qemu_log_mask(LOG_GUEST_ERROR,
212 + "%s: total_req_len overflow, current=0x%x, adding=0x%"
213 + HWADDR_PRIx "\n", __func__, s->total_req_len, plen);
214 + return false;
215 + }
216 +
217 + s->total_req_len += plen;
218 + return true;
219 +}
220 +
221 static int hash_prepare_direct_iov(AspeedHACEState *s, struct iovec *iov,
222 bool acc_mode, bool *acc_final_request)
223 {
@@ -232,7 +245,9 @@ static int hash_prepare_direct_iov(AspeedHACEState *s, struct iovec *iov,
245 iov_idx = 1;
246
247 if (acc_mode) {
235 - s->total_req_len += plen;
248 + if (!hash_accumulate_len(s, plen)) {
249 + return -1;
250 + }
251
252 if (has_padding(s, &iov[0], plen, &total_msg_len,
253 &pad_offset)) {
@@ -299,7 +314,9 @@ static int hash_prepare_sg_iov(AspeedHACEState *s, struct iovec *iov,
314
315 iov[iov_idx].iov_base = haddr;
316 if (acc_mode) {
302 - s->total_req_len += plen;
317 + if (!hash_accumulate_len(s, plen)) {
318 + return -1;
319 + }
320
321 if (has_padding(s, &iov[iov_idx], plen, &total_msg_len,
322 &pad_offset)) {