From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id DA3213787 for ; Wed, 18 Nov 2015 09:47:10 +0100 (CET) Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga103.fm.intel.com with ESMTP; 18 Nov 2015 00:47:10 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,312,1444719600"; d="scan'208";a="688292642" Received: from yliu-dev.sh.intel.com (HELO yliu-dev) ([10.239.66.49]) by orsmga003.jf.intel.com with ESMTP; 18 Nov 2015 00:47:08 -0800 Date: Wed, 18 Nov 2015 16:48:07 +0800 From: Yuanhan Liu To: "Xie, Huawei" Message-ID: <20151118084807.GD2326@yliu-dev.sh.intel.com> References: <1447315353-42152-1-git-send-email-rlane@bigswitch.com> <20151112092305.GI2326@yliu-dev.sh.intel.com> <20151117132349.GT2326@yliu-dev.sh.intel.com> <20151118025655.GW2326@yliu-dev.sh.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) Cc: "dev@dpdk.org" Subject: Re: [dpdk-dev] [PATCH] vhost: avoid buffer overflow in update_secure_len X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Nov 2015 08:47:11 -0000 On Wed, Nov 18, 2015 at 07:53:24AM +0000, Xie, Huawei wrote: ... > > do { > > + if (vec_id >= BUF_VECTOR_MAX) > > + break; > > + > > next_desc = 0; > > len += vq->desc[idx].len; > > vq->buf_vec[vec_id].buf_addr = vq->desc[idx].addr; > > @@ -519,6 +526,8 @@ virtio_dev_merge_rx(struct virtio_net *dev, uint16_t queue_id, > > goto merge_rx_exit; > > } else { > > update_secure_len(vq, res_cur_idx, &secure_len, &vec_idx); > > + if (secure_len == 0) > > + goto merge_rx_exit; > Why do we exit when secure_len is 0 rather than 1? :). Malicious guest I confess it's not a proper fix. Making it return an error code, as Rich suggested in early email, is better. It's generic enough, as we have to check the vec_buf overflow here. BTW, can we move the vec_buf outside `struct vhost_virtqueue'? It makes the structure huge. > could easily forge the desc len so that secure_len never reach pkt_len > even it is not zero so that host enters into dead loop here. > Generally speaking, we shouldn't fix for a specific issue, Agreed. > and the > security checks should be as few as possible. Idealy, yes. > We need to consider > refactor the code here for the generic fix. What's your thougths? --yliu > > > res_cur_idx++; > > } > > } while (pkt_len > secure_len); > > @@ -631,6 +640,8 @@ rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t queue_id, > > uint8_t alloc_err = 0; > > > > desc = &vq->desc[head[entry_success]]; > > + if (desc->len == 0) > > + break; > > > > /* Discard first buffer as it is the virtio header */ > > if (desc->flags & VRING_DESC_F_NEXT) { > > @@ -638,6 +649,8 @@ rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t queue_id, > > vb_offset = 0; > > vb_avail = desc->len; > > } else { > > + if (desc->len < vq->vhost_hlen) > > + break; > > vb_offset = vq->vhost_hlen; > > vb_avail = desc->len - vb_offset; > > } > > >