On 5/11/23 12:37, Théo Maillart wrote:
On Wed, May 10, 2023 at 6:11 PM Paolo Bonzini <pbonz...@redhat.com
<mailto:pbonz...@redhat.com>> wrote:
On 4/26/23 15:37, Théo Maillart wrote:
> --- a/hw/scsi/scsi-generic.c
> +++ b/hw/scsi/scsi-generic.c
> @@ -191,7 +191,7 @@ static int
scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s, int len)
> if ((s->type == TYPE_DISK || s->type == TYPE_ZBC) &&
> (r->req.cmd.buf[1] & 0x01)) {
> page = r->req.cmd.buf[2];
> - if (page == 0xb0) {
> + if (page == 0xb0 && r->buflen >= 12) {
> uint64_t max_transfer = calculate_max_transfer(s);
> stl_be_p(&r->buf[8], max_transfer);
> /* Also take care of the opt xfer len. */
> --
This is not enough because right below there is a store of bytes 12..15.
I agree with you, I was wrong, the test should be r->buflen >= 16
This would let the guest see the wrong maximum transfer length, if it
uses a buffer length of 12.
The best thing to do is to:
1) do the stores in an "uint8_t buf[8]" on the stack, followed by a
memcpy to r->buf + 8.
2) add "&& r->buflen > 8" to the condition similar to what you've done
above.
But I don't think this suggestion is necessary, it would basically do
the same thing that is done in the current version adding an extra
memcpy on the stack.
The memcpy can be limited to the actual size of the buffer, i.e.
memcpy(r->buf + 8, buf, r->buflen - 8).
In fact you need to memcpy both before and after, so that the ldl_be_p
is done on a large-enough buffer.
In my opinion the only problem highlighted by this crash is that of
writing byte 8 to 15 while the buffer size is 4.
Right, but the bytes that _can_ be written should not change before and
after the patch.
Paolo