All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dmitry Fleytman <dmitry@daynix.com>
To: P J P <ppandit@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	Qemu Developers <qemu-devel@nongnu.org>,
	Li Qiang <liqiang6-s@360.cn>
Subject: Re: [Qemu-devel] [PATCH v3] scsi: pvscsi: avoid infinite loop while building SG list
Date: Tue, 13 Sep 2016 11:54:02 +0300	[thread overview]
Message-ID: <7D125827-164E-43FF-A80F-8B8908D9B2EE@daynix.com> (raw)
In-Reply-To: <alpine.LFD.2.20.1609131231080.27819@wniryva>

Hello Prasad,

See my comments inline.

> On 13 Sep 2016, at 10:01 AM, P J P <ppandit@redhat.com> wrote:
> 
> +-- On Tue, 6 Sep 2016, P J P wrote --+
> | From: Prasad J Pandit <pjp@fedoraproject.org>
> | 
> | In PVSCSI paravirtual SCSI bus, pvscsi_convert_sglist can take a very
> | long time or go into an infinite loop due to two different bugs:
> | 
> | 1) the request descriptor data length is defined to be 64 bit. While
> | building SG list from a request descriptor, it gets truncated to 32bit
> | in routine 'pvscsi_convert_sglist'. This could lead to an infinite loop
> | situation for large 'dataLen' values, when data_length is cast to uint32_t
> | and chunk_size becomes always zero.  Fix this by removing the incorrect
> | cast.
> | 
> | 2) pvscsi_get_next_sg_elem can be called arbitrarily many times if the
> | element has a zero length.  Get out of the loop early when this happens,
> | by introducing an upper limit on the number of SG list elements.
> | 
> | Reported-by: Li Qiang <liqiang6-s@360.cn>
> | Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
> | ---
> |  hw/scsi/vmw_pvscsi.c | 11 ++++++-----
> |  1 file changed, 6 insertions(+), 5 deletions(-)
> | 
> | Update as per:
> |   -> https://lists.gnu.org/archive/html/qemu-devel/2016-09/msg01172.html
> | 
> | diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
> | index 4245c15..babac5a 100644
> | --- a/hw/scsi/vmw_pvscsi.c
> | +++ b/hw/scsi/vmw_pvscsi.c
> | @@ -40,6 +40,8 @@
> |  #define PVSCSI_MAX_DEVS                   (64)
> |  #define PVSCSI_MSIX_NUM_VECTORS           (1)
> |  
> | +#define PVSCSI_MAX_SG_ELEM                2048
> | +
> |  #define PVSCSI_MAX_CMD_DATA_WORDS \
> |      (sizeof(PVSCSICmdDescSetupRings)/sizeof(uint32_t))
> |  
> | @@ -628,17 +630,16 @@ pvscsi_queue_pending_descriptor(PVSCSIState *s, SCSIDevice **d,
> |  static void
> |  pvscsi_convert_sglist(PVSCSIRequest *r)
> |  {
> | -    int chunk_size;
> | +    uint32_t chunk_size, elmcnt = 0;
> |      uint64_t data_length = r->req.dataLen;
> |      PVSCSISGState sg = r->sg;
> | -    while (data_length) {
> | -        while (!sg.resid) {
> | +    while (data_length && elmcnt < PVSCSI_MAX_SG_ELEM) {
> | +        while (!sg.resid && elmcnt++ < PVSCSI_MAX_SG_ELEM) {


Better put here:

if(elemcnt++ >= PVSCSI_MAX_SG_ELEM) {
    return;
}

And ditch additional conditions from while clauses.
This way you’ll have less compare operations and avoid
adding the same element twice when leaving because of too long SG list.

Also this is not a good idea to send truncated requests
when SG list becomes too long. I’d prefer to return error
code from pvscsi_convert_sglist() and handle it as appropriate.


Regards,
Dmitry

> |              pvscsi_get_next_sg_elem(&sg);
> |              trace_pvscsi_convert_sglist(r->req.context, r->sg.dataAddr,
> |                                          r->sg.resid);
> |          }
> | -        assert(data_length > 0);
> | -        chunk_size = MIN((unsigned) data_length, sg.resid);
> | +        chunk_size = MIN(data_length, sg.resid);
> |          if (chunk_size) {
> |              qemu_sglist_add(&r->sgl, sg.dataAddr, chunk_size);
> |          }
> 
> 
> Ping...!
> --
> Prasad J Pandit / Red Hat Product Security Team
> 47AF CE69 3A90 54AA 9045 1053 DD13 3D32 FE5B 041F

  reply	other threads:[~2016-09-13  8:55 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-06 17:53 [Qemu-devel] [PATCH v3] scsi: pvscsi: avoid infinite loop while building SG list P J P
2016-09-13  7:01 ` P J P
2016-09-13  8:54   ` Dmitry Fleytman [this message]
2016-09-13 11:20     ` P J P
2016-09-13 12:00       ` Dmitry Fleytman
2016-09-13 12:53         ` P J P
2016-09-13 13:05           ` Dmitry Fleytman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7D125827-164E-43FF-A80F-8B8908D9B2EE@daynix.com \
    --to=dmitry@daynix.com \
    --cc=liqiang6-s@360.cn \
    --cc=pbonzini@redhat.com \
    --cc=ppandit@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.