* [PATCH 0/2] esp.c: fix esp_cdb_ready() FIFO wraparound limit calculation
@ 2025-09-25 12:28 Mark Cave-Ayland
2025-09-25 12:28 ` [PATCH 1/2] " Mark Cave-Ayland
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Mark Cave-Ayland @ 2025-09-25 12:28 UTC (permalink / raw)
To: pbonzini, fam, farosas, lvivier, qemu-devel
This small series fixes a bug in the ESP cmdfifo FIFO wraparound limit
calculation as reported at https://gitlab.com/qemu-project/qemu/-/issues/3082, as
well as adding the reported test case to qtest.
In normal usage the cmdfifo does not overflow, however the test case reported by
the fuzzer was enough to show that the FIFO overflow check in esp_cdb_ready()
was not working correctly.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Mark Cave-Ayland (2):
esp.c: fix esp_cdb_ready() FIFO wraparound limit calculation
qtest/am53c974-test: add additional test for cmdfifo overflow
hw/scsi/esp.c | 6 ++++--
tests/qtest/am53c974-test.c | 40 +++++++++++++++++++++++++++++++++++++
2 files changed, 44 insertions(+), 2 deletions(-)
--
2.39.5
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/2] esp.c: fix esp_cdb_ready() FIFO wraparound limit calculation
2025-09-25 12:28 [PATCH 0/2] esp.c: fix esp_cdb_ready() FIFO wraparound limit calculation Mark Cave-Ayland
@ 2025-09-25 12:28 ` Mark Cave-Ayland
2025-09-25 13:33 ` Philippe Mathieu-Daudé
2025-09-25 12:28 ` [PATCH 2/2] qtest/am53c974-test: add additional test for cmdfifo overflow Mark Cave-Ayland
2025-10-22 17:36 ` [PATCH 0/2] esp.c: fix esp_cdb_ready() FIFO wraparound limit calculation Paolo Bonzini
2 siblings, 1 reply; 7+ messages in thread
From: Mark Cave-Ayland @ 2025-09-25 12:28 UTC (permalink / raw)
To: pbonzini, fam, farosas, lvivier, qemu-devel
The original calculation in commit 3cc70889a3 ("esp.c: prevent cmdfifo overflow
in esp_cdb_ready()") subtracted cmdfifo_cdb_offset from fifo8_num_used() to
calculate the outstanding cmdfifo length, but this is incorrect because
fifo8_num_used() can also include wraparound data.
Instead calculate the maximum offset used by scsi_cdb_length() which is just
the first byte after cmdfifo_cdb_offset, and then peek the entire content
of the cmdfifo. The fifo8_peek_bufptr() result will then return the maximum
length of remaining data up to the end of the internal cmdfifo array, which
can then be used for the overflow check.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Fixes: 3cc70889a3 ("esp.c: prevent cmdfifo overflow in esp_cdb_ready()")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3082
---
hw/scsi/esp.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 1d264c40e5..2809fcdee0 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -447,7 +447,9 @@ static void write_response(ESPState *s)
static bool esp_cdb_ready(ESPState *s)
{
- int len = fifo8_num_used(&s->cmdfifo) - s->cmdfifo_cdb_offset;
+ /* scsi_cdb_length() only reads the first byte */
+ int limit = s->cmdfifo_cdb_offset + 1;
+ int len = fifo8_num_used(&s->cmdfifo);
const uint8_t *pbuf;
uint32_t n;
int cdblen;
@@ -457,7 +459,7 @@ static bool esp_cdb_ready(ESPState *s)
}
pbuf = fifo8_peek_bufptr(&s->cmdfifo, len, &n);
- if (n < len) {
+ if (n < limit) {
/*
* In normal use the cmdfifo should never wrap, but include this check
* to prevent a malicious guest from reading past the end of the
--
2.39.5
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/2] qtest/am53c974-test: add additional test for cmdfifo overflow
2025-09-25 12:28 [PATCH 0/2] esp.c: fix esp_cdb_ready() FIFO wraparound limit calculation Mark Cave-Ayland
2025-09-25 12:28 ` [PATCH 1/2] " Mark Cave-Ayland
@ 2025-09-25 12:28 ` Mark Cave-Ayland
2025-09-25 13:33 ` Philippe Mathieu-Daudé
2025-10-22 17:36 ` [PATCH 0/2] esp.c: fix esp_cdb_ready() FIFO wraparound limit calculation Paolo Bonzini
2 siblings, 1 reply; 7+ messages in thread
From: Mark Cave-Ayland @ 2025-09-25 12:28 UTC (permalink / raw)
To: pbonzini, fam, farosas, lvivier, qemu-devel
Based upon the qtest reproducer posted to Gitlab issue #3082 at
https://gitlab.com/qemu-project/qemu/-/issues/3082.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
tests/qtest/am53c974-test.c | 40 +++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/tests/qtest/am53c974-test.c b/tests/qtest/am53c974-test.c
index ed3ac7db20..a3667275ac 100644
--- a/tests/qtest/am53c974-test.c
+++ b/tests/qtest/am53c974-test.c
@@ -109,6 +109,44 @@ static void test_cmdfifo_overflow2_ok(void)
qtest_quit(s);
}
+/* Reported as https://issues.oss-fuzz.com/issues/439878564 */
+static void test_cmdfifo_overflow3_ok(void)
+{
+ QTestState *s = qtest_init(
+ "-device am53c974,id=scsi -device scsi-hd,drive=disk0 "
+ "-drive id=disk0,if=none,file=null-co://,format=raw -nodefaults");
+ qtest_outl(s, 0xcf8, 0x80001010);
+ qtest_outl(s, 0xcfc, 0xc000);
+ qtest_outl(s, 0xcf8, 0x80001004);
+ qtest_outw(s, 0xcfc, 0x01);
+ qtest_outb(s, 0xc00c, 0x43);
+ qtest_outl(s, 0xc00b, 0x9100);
+ qtest_outl(s, 0xc009, 0x02000000);
+ qtest_outl(s, 0xc000, 0x0b);
+ qtest_outl(s, 0xc00b, 0x00);
+ qtest_outl(s, 0xc00b, 0x00);
+ qtest_outl(s, 0xc00b, 0xc200);
+ qtest_outl(s, 0xc00b, 0x1000);
+ qtest_outl(s, 0xc00b, 0x9000);
+ qtest_outb(s, 0xc008, 0x00);
+ qtest_outb(s, 0xc008, 0x00);
+ qtest_outl(s, 0xc03f, 0x0300);
+ qtest_outl(s, 0xc00b, 0x00);
+ qtest_outw(s, 0xc00b, 0x4200);
+ qtest_outl(s, 0xc00b, 0x00);
+ qtest_outw(s, 0xc00b, 0x1200);
+ qtest_outl(s, 0xc00b, 0x00);
+ qtest_outb(s, 0xc00c, 0x43);
+ qtest_outl(s, 0xc00b, 0x00);
+ qtest_outl(s, 0xc00b, 0x00);
+ qtest_outl(s, 0xc007, 0x00);
+ qtest_outl(s, 0xc007, 0x00);
+ qtest_outl(s, 0xc007, 0x00);
+ qtest_outl(s, 0xc00b, 0x1000);
+ qtest_outl(s, 0xc007, 0x00);
+ qtest_quit(s);
+}
+
/* Reported as crash_0900379669 */
static void test_fifo_pop_buf(void)
{
@@ -266,6 +304,8 @@ int main(int argc, char **argv)
test_cmdfifo_overflow_ok);
qtest_add_func("am53c974/test_cmdfifo_overflow2_ok",
test_cmdfifo_overflow2_ok);
+ qtest_add_func("am53c974/test_cmdfifo_overflow3_ok",
+ test_cmdfifo_overflow3_ok);
qtest_add_func("am53c974/test_fifo_pop_buf",
test_fifo_pop_buf);
qtest_add_func("am53c974/test_target_selected_ok",
--
2.39.5
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] esp.c: fix esp_cdb_ready() FIFO wraparound limit calculation
2025-09-25 12:28 ` [PATCH 1/2] " Mark Cave-Ayland
@ 2025-09-25 13:33 ` Philippe Mathieu-Daudé
2025-09-25 19:54 ` Mark Cave-Ayland
0 siblings, 1 reply; 7+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-09-25 13:33 UTC (permalink / raw)
To: Mark Cave-Ayland, pbonzini, fam, farosas, lvivier, qemu-devel,
Alexander Bulekov
On 25/9/25 14:28, Mark Cave-Ayland wrote:
> The original calculation in commit 3cc70889a3 ("esp.c: prevent cmdfifo overflow
> in esp_cdb_ready()") subtracted cmdfifo_cdb_offset from fifo8_num_used() to
"substracted"
> calculate the outstanding cmdfifo length, but this is incorrect because
> fifo8_num_used() can also include wraparound data.
>
> Instead calculate the maximum offset used by scsi_cdb_length() which is just
> the first byte after cmdfifo_cdb_offset, and then peek the entire content
> of the cmdfifo. The fifo8_peek_bufptr() result will then return the maximum
> length of remaining data up to the end of the internal cmdfifo array, which
> can then be used for the overflow check.
>
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> Fixes: 3cc70889a3 ("esp.c: prevent cmdfifo overflow in esp_cdb_ready()")
Buglink: https://issues.oss-fuzz.com/issues/439878564
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3082
> ---
> hw/scsi/esp.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
> index 1d264c40e5..2809fcdee0 100644
> --- a/hw/scsi/esp.c
> +++ b/hw/scsi/esp.c
> @@ -447,7 +447,9 @@ static void write_response(ESPState *s)
>
> static bool esp_cdb_ready(ESPState *s)
> {
> - int len = fifo8_num_used(&s->cmdfifo) - s->cmdfifo_cdb_offset;
> + /* scsi_cdb_length() only reads the first byte */
> + int limit = s->cmdfifo_cdb_offset + 1;
> + int len = fifo8_num_used(&s->cmdfifo);
> const uint8_t *pbuf;
> uint32_t n;
> int cdblen;
> @@ -457,7 +459,7 @@ static bool esp_cdb_ready(ESPState *s)
> }
>
> pbuf = fifo8_peek_bufptr(&s->cmdfifo, len, &n);
> - if (n < len) {
> + if (n < limit) {
> /*
> * In normal use the cmdfifo should never wrap, but include this check
> * to prevent a malicious guest from reading past the end of the
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] qtest/am53c974-test: add additional test for cmdfifo overflow
2025-09-25 12:28 ` [PATCH 2/2] qtest/am53c974-test: add additional test for cmdfifo overflow Mark Cave-Ayland
@ 2025-09-25 13:33 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 7+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-09-25 13:33 UTC (permalink / raw)
To: Mark Cave-Ayland, pbonzini, fam, farosas, lvivier, qemu-devel
On 25/9/25 14:28, Mark Cave-Ayland wrote:
> Based upon the qtest reproducer posted to Gitlab issue #3082 at
> https://gitlab.com/qemu-project/qemu/-/issues/3082.
>
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> ---
> tests/qtest/am53c974-test.c | 40 +++++++++++++++++++++++++++++++++++++
> 1 file changed, 40 insertions(+)
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] esp.c: fix esp_cdb_ready() FIFO wraparound limit calculation
2025-09-25 13:33 ` Philippe Mathieu-Daudé
@ 2025-09-25 19:54 ` Mark Cave-Ayland
0 siblings, 0 replies; 7+ messages in thread
From: Mark Cave-Ayland @ 2025-09-25 19:54 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, pbonzini, fam, farosas, lvivier,
qemu-devel, Alexander Bulekov
On 25/09/2025 14:33, Philippe Mathieu-Daudé wrote:
> On 25/9/25 14:28, Mark Cave-Ayland wrote:
>> The original calculation in commit 3cc70889a3 ("esp.c: prevent cmdfifo overflow
>> in esp_cdb_ready()") subtracted cmdfifo_cdb_offset from fifo8_num_used() to
>
> "substracted"
I had to look this one up, and I'm disappointed to report that it's considered
obsolete these days ;)
>> calculate the outstanding cmdfifo length, but this is incorrect because
>> fifo8_num_used() can also include wraparound data.
>>
>> Instead calculate the maximum offset used by scsi_cdb_length() which is just
>> the first byte after cmdfifo_cdb_offset, and then peek the entire content
>> of the cmdfifo. The fifo8_peek_bufptr() result will then return the maximum
>> length of remaining data up to the end of the internal cmdfifo array, which
>> can then be used for the overflow check.
>>
>> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
>> Fixes: 3cc70889a3 ("esp.c: prevent cmdfifo overflow in esp_cdb_ready()")
>
> Buglink: https://issues.oss-fuzz.com/issues/439878564
>
>> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3082
>> ---
>> hw/scsi/esp.c | 6 ++++--
>> 1 file changed, 4 insertions(+), 2 deletions(-)
>>
>> diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
>> index 1d264c40e5..2809fcdee0 100644
>> --- a/hw/scsi/esp.c
>> +++ b/hw/scsi/esp.c
>> @@ -447,7 +447,9 @@ static void write_response(ESPState *s)
>> static bool esp_cdb_ready(ESPState *s)
>> {
>> - int len = fifo8_num_used(&s->cmdfifo) - s->cmdfifo_cdb_offset;
>> + /* scsi_cdb_length() only reads the first byte */
>> + int limit = s->cmdfifo_cdb_offset + 1;
>> + int len = fifo8_num_used(&s->cmdfifo);
>> const uint8_t *pbuf;
>> uint32_t n;
>> int cdblen;
>> @@ -457,7 +459,7 @@ static bool esp_cdb_ready(ESPState *s)
>> }
>> pbuf = fifo8_peek_bufptr(&s->cmdfifo, len, &n);
>> - if (n < len) {
>> + if (n < limit) {
>> /*
>> * In normal use the cmdfifo should never wrap, but include this check
>> * to prevent a malicious guest from reading past the end of the
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Thanks for the review!
ATB,
Mark.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 0/2] esp.c: fix esp_cdb_ready() FIFO wraparound limit calculation
2025-09-25 12:28 [PATCH 0/2] esp.c: fix esp_cdb_ready() FIFO wraparound limit calculation Mark Cave-Ayland
2025-09-25 12:28 ` [PATCH 1/2] " Mark Cave-Ayland
2025-09-25 12:28 ` [PATCH 2/2] qtest/am53c974-test: add additional test for cmdfifo overflow Mark Cave-Ayland
@ 2025-10-22 17:36 ` Paolo Bonzini
2 siblings, 0 replies; 7+ messages in thread
From: Paolo Bonzini @ 2025-10-22 17:36 UTC (permalink / raw)
To: Mark Cave-Ayland; +Cc: pbonzini, fam, farosas, lvivier, qemu-devel
Queued, thanks.
Paolo
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-10-22 17:37 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-25 12:28 [PATCH 0/2] esp.c: fix esp_cdb_ready() FIFO wraparound limit calculation Mark Cave-Ayland
2025-09-25 12:28 ` [PATCH 1/2] " Mark Cave-Ayland
2025-09-25 13:33 ` Philippe Mathieu-Daudé
2025-09-25 19:54 ` Mark Cave-Ayland
2025-09-25 12:28 ` [PATCH 2/2] qtest/am53c974-test: add additional test for cmdfifo overflow Mark Cave-Ayland
2025-09-25 13:33 ` Philippe Mathieu-Daudé
2025-10-22 17:36 ` [PATCH 0/2] esp.c: fix esp_cdb_ready() FIFO wraparound limit calculation Paolo Bonzini
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).