Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuergen Gross <jgross@suse.com>2019-10-07 10:21:11 +0200
committerJuergen Gross <jgross@suse.com>2019-10-07 10:21:11 +0200
commitf1c5e2e4c1121be2e6ae17e9515a44d4c35c3d67 (patch)
treec74092b26e0eb86f52d6630de0707e6852643f75
parent646d7f14d0e09e6cc93c2afdef7c40d3846cf9e5 (diff)
xen-netfront: do not use ~0U as error return value for
xennet_fill_frags() (bsc#1065600).
-rw-r--r--patches.suse/0001-xen-netfront-do-not-use-0U-as-error-return-value-for.patch99
-rw-r--r--series.conf1
2 files changed, 100 insertions, 0 deletions
diff --git a/patches.suse/0001-xen-netfront-do-not-use-0U-as-error-return-value-for.patch b/patches.suse/0001-xen-netfront-do-not-use-0U-as-error-return-value-for.patch
new file mode 100644
index 0000000000..53915468b5
--- /dev/null
+++ b/patches.suse/0001-xen-netfront-do-not-use-0U-as-error-return-value-for.patch
@@ -0,0 +1,99 @@
+Patch-mainline: v5.4-rc2
+Git-commit: a761129e3625688310aecf26e1be9e98e85f8eb5
+References: bsc#1065600
+From: Dongli Zhang <dongli.zhang@oracle.com>
+Date: Tue, 1 Oct 2019 21:56:41 +0800
+Subject: [PATCH] xen-netfront: do not use ~0U as error return value for
+ xennet_fill_frags()
+
+xennet_fill_frags() uses ~0U as return value when the sk_buff is not able
+to cache extra fragments. This is incorrect because the return type of
+xennet_fill_frags() is RING_IDX and 0xffffffff is an expected value for
+ring buffer index.
+
+In the situation when the rsp_cons is approaching 0xffffffff, the return
+value of xennet_fill_frags() may become 0xffffffff which xennet_poll() (the
+caller) would regard as error. As a result, queue->rx.rsp_cons is set
+incorrectly because it is updated only when there is error. If there is no
+error, xennet_poll() would be responsible to update queue->rx.rsp_cons.
+Finally, queue->rx.rsp_cons would point to the rx ring buffer entries whose
+queue->rx_skbs[i] and queue->grant_rx_ref[i] are already cleared to NULL.
+This leads to NULL pointer access in the next iteration to process rx ring
+buffer entries.
+
+The symptom is similar to the one fixed in
+commit 00b368502d18 ("xen-netfront: do not assume sk_buff_head list is
+empty in error handling").
+
+This patch changes the return type of xennet_fill_frags() to indicate
+whether it is successful or failed. The queue->rx.rsp_cons will be
+always updated inside this function.
+
+Fixes: ad4f15dc2c70 ("xen/netfront: don't bug in case of too many frags")
+Signed-off-by: Dongli Zhang <dongli.zhang@oracle.com>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+---
+ drivers/net/xen-netfront.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
+index e14ec75b61d6..482c6c8b0fb7 100644
+--- a/drivers/net/xen-netfront.c
++++ b/drivers/net/xen-netfront.c
+@@ -887,9 +887,9 @@ static int xennet_set_skb_gso(struct sk_buff *skb,
+ return 0;
+ }
+
+-static RING_IDX xennet_fill_frags(struct netfront_queue *queue,
+- struct sk_buff *skb,
+- struct sk_buff_head *list)
++static int xennet_fill_frags(struct netfront_queue *queue,
++ struct sk_buff *skb,
++ struct sk_buff_head *list)
+ {
+ RING_IDX cons = queue->rx.rsp_cons;
+ struct sk_buff *nskb;
+@@ -908,7 +908,7 @@ static RING_IDX xennet_fill_frags(struct netfront_queue *queue,
+ if (unlikely(skb_shinfo(skb)->nr_frags >= MAX_SKB_FRAGS)) {
+ queue->rx.rsp_cons = ++cons + skb_queue_len(list);
+ kfree_skb(nskb);
+- return ~0U;
++ return -ENOENT;
+ }
+
+ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
+@@ -919,7 +919,9 @@ static RING_IDX xennet_fill_frags(struct netfront_queue *queue,
+ kfree_skb(nskb);
+ }
+
+- return cons;
++ queue->rx.rsp_cons = cons;
++
++ return 0;
+ }
+
+ static int checksum_setup(struct net_device *dev, struct sk_buff *skb)
+@@ -1045,8 +1047,7 @@ static int xennet_poll(struct napi_struct *napi, int budget)
+ skb->data_len = rx->status;
+ skb->len += rx->status;
+
+- i = xennet_fill_frags(queue, skb, &tmpq);
+- if (unlikely(i == ~0U))
++ if (unlikely(xennet_fill_frags(queue, skb, &tmpq)))
+ goto err;
+
+ if (rx->flags & XEN_NETRXF_csum_blank)
+@@ -1056,7 +1057,7 @@ static int xennet_poll(struct napi_struct *napi, int budget)
+
+ __skb_queue_tail(&rxq, skb);
+
+- queue->rx.rsp_cons = ++i;
++ i = ++queue->rx.rsp_cons;
+ work_done++;
+ }
+
+--
+2.16.4
+
diff --git a/series.conf b/series.conf
index a5753169c2..607098747a 100644
--- a/series.conf
+++ b/series.conf
@@ -24708,6 +24708,7 @@
patches.suse/0001-btrfs-relocation-fix-use-after-free-on-dead-relocati.patch
patches.suse/0001-btrfs-qgroup-Fix-the-wrong-target-io_tree-when-freei.patch
patches.suse/0002-btrfs-qgroup-Fix-reserved-data-space-leak-if-we-have.patch
+ patches.suse/0001-xen-netfront-do-not-use-0U-as-error-return-value-for.patch
# jejb/scsi for-next
patches.suse/scsi-qla2xxx-Fix-Nport-ID-display-value.patch