qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [Bug 1191606] Re: qemu crashes with iscsi initiator (li


From: Laszlo Ersek
Subject: Re: [Qemu-devel] [Bug 1191606] Re: qemu crashes with iscsi initiator (libiscsi) when using virtio
Date: Thu, 20 Jun 2013 16:47:38 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130513 Thunderbird/17.0.6

On 06/20/13 15:33, ronnie sahlberg wrote:
> http://pastebin.com/EuwZPna1
> 
> Last few thousand lines from the log with your patch.
> 
> 
> The crash happens immediately after qemu has called out to iscsi_ioctl
> with SG_IO to read the serial numbers vpd page.
> We get the reply back from the target but as soon as ioctl_cb returns we 
> crash.
> If you comment out SG_IO in iscsi_ioctl then the crash does not happen
> (but the qemu does nto get serial number either)
> 
> 
> I will look more into it tonight.

  virtqueue_map_sg: mapped gpa=00000000790a9000 at hva=0x7f0cb10a9000 for 
length=4, is_write=1  (out: data)
  virtqueue_map_sg: mapped gpa=000000007726fc70 at hva=0x7f0caf26fc70 for 
length=96, is_write=1 (out: sense)
  virtqueue_map_sg: mapped gpa=00000000764e5aa0 at hva=0x7f0cae4e5aa0 for 
length=16, is_write=1 (out: errors, data_len, sense_len, residual)
  virtqueue_map_sg: mapped gpa=00000000764e5adc at hva=0x7f0cae4e5adc for 
length=1, is_write=1  (out: status)
  virtqueue_map_sg: mapped gpa=00000000764e5a90 at hva=0x7f0cae4e5a90 for 
length=16, is_write=0 (in: type, ioprio, sector)
  virtqueue_map_sg: mapped gpa=000000007ab80578 at hva=0x7f0cb2b80578 for 
length=6, is_write=0  (in: cmd)
  virtio_blk_handle_request: type=0x00000002
  virtqueue_fill: unmapping hva=0x7f0c24008000 for length=4, access_len=1, 
is_write=1
  Bad ram pointer 0x7f0c24008000

This looks related, in virtio_blk_handle_scsi():

    } else if (req->elem.in_num > 3) {
        /*
         * If we have more than 3 input segments the guest wants to actually
         * read data.
         */
        hdr.dxfer_direction = SG_DXFER_FROM_DEV;
        hdr.iovec_count = req->elem.in_num - 3;
        for (i = 0; i < hdr.iovec_count; i++)
            hdr.dxfer_len += req->elem.in_sg[i].iov_len;

        hdr.dxferp = req->elem.in_sg;
    } else {

This sets
- "hdr.iovec_count" to 1,
- "hdr.dxfer_len" to 4,
- "hdr.dxferp" as shown above,

For "struct sg_io_hdr" (which is the type of "hdr"), the typedef &
documentation are in <include/scsi/sg.h>:

    unsigned short iovec_count; /* [i] 0 implies no scatter gather */

    void __user *dxferp;        /* [i], [*io] points to data transfer memory
                                              or scatter gather list */

Now what we're seeing is a corruption of "req->elem.in_sg[0].iov_base",
whose address equals that of "req->elem.in_sg" (it's at offset 0 in the
struct at subscript #0 in the array).

  virtqueue_map_sg: mapped gpa=00000000790a9000 at hva=0x7f0cb10a9000 for 
length=4, is_write=1
  [...]
  virtio_blk_handle_request: type=0x00000002
  virtqueue_fill: unmapping hva=0x7f0c24008000 for length=4, access_len=1, 
is_write=1
  Bad ram pointer 0x7f0c24008000

First I don't understand how access_len can only be "1". But, in any
case, if the "req->elem.in_sg[0].iov_base" pointer is stored in
little-endian order, and the kernel (or iscsi_scsi_command_async()?) for
whatever reason misinterprets "hdr.dxferp" to point at an actual receive
buffer (instead of an iovec array), that would be consistent with the
symptoms:

  0x7f0cb10a9000 <--- original value of req->elem.in_sg[0].iov_base
  0x7f0c24008000 <--- corrupted value
        ^^^^^^^^ <--- 4 low bytes overwritten by SCSI data

Laszlo



reply via email to

[Prev in Thread] Current Thread [Next in Thread]