]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 5 Jul 2022 11:44:55 +0000 (13:44 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 5 Jul 2022 11:44:55 +0000 (13:44 +0200)
added patches:
net-usb-qmi_wwan-add-telit-0x1070-composition.patch
xen-arm-fix-race-in-rb-tree-based-p2m-accounting.patch
xen-blkfront-fix-leaking-data-in-shared-pages.patch
xen-blkfront-force-data-bouncing-when-backend-is-untrusted.patch
xen-netfront-fix-leaking-data-in-shared-pages.patch
xen-netfront-force-data-bouncing-when-backend-is-untrusted.patch
xen-netfront-restore-__skb_queue_tail-positioning-in-xennet_get_responses.patch

queue-5.15/net-usb-qmi_wwan-add-telit-0x1070-composition.patch [new file with mode: 0644]
queue-5.15/series
queue-5.15/xen-arm-fix-race-in-rb-tree-based-p2m-accounting.patch [new file with mode: 0644]
queue-5.15/xen-blkfront-fix-leaking-data-in-shared-pages.patch [new file with mode: 0644]
queue-5.15/xen-blkfront-force-data-bouncing-when-backend-is-untrusted.patch [new file with mode: 0644]
queue-5.15/xen-netfront-fix-leaking-data-in-shared-pages.patch [new file with mode: 0644]
queue-5.15/xen-netfront-force-data-bouncing-when-backend-is-untrusted.patch [new file with mode: 0644]
queue-5.15/xen-netfront-restore-__skb_queue_tail-positioning-in-xennet_get_responses.patch [new file with mode: 0644]

diff --git a/queue-5.15/net-usb-qmi_wwan-add-telit-0x1070-composition.patch b/queue-5.15/net-usb-qmi_wwan-add-telit-0x1070-composition.patch
new file mode 100644 (file)
index 0000000..5a01bdb
--- /dev/null
@@ -0,0 +1,36 @@
+From 94f2a444f28a649926c410eb9a38afb13a83ebe0 Mon Sep 17 00:00:00 2001
+From: Daniele Palmas <dnlplm@gmail.com>
+Date: Fri, 10 Dec 2021 10:57:22 +0100
+Subject: net: usb: qmi_wwan: add Telit 0x1070 composition
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Daniele Palmas <dnlplm@gmail.com>
+
+commit 94f2a444f28a649926c410eb9a38afb13a83ebe0 upstream.
+
+Add the following Telit FN990 composition:
+
+0x1070: tty, adb, rmnet, tty, tty, tty, tty
+
+Signed-off-by: Daniele Palmas <dnlplm@gmail.com>
+Acked-by: Bjørn Mork <bjorn@mork.no>
+Link: https://lore.kernel.org/r/20211210095722.22269-1-dnlplm@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Cc: Fabio Porcedda <fabio.porcedda@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/qmi_wwan.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -1355,6 +1355,7 @@ static const struct usb_device_id produc
+       {QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)}, /* Telit LE922A */
+       {QMI_QUIRK_SET_DTR(0x1bc7, 0x1050, 2)}, /* Telit FN980 */
+       {QMI_QUIRK_SET_DTR(0x1bc7, 0x1060, 2)}, /* Telit LN920 */
++      {QMI_QUIRK_SET_DTR(0x1bc7, 0x1070, 2)}, /* Telit FN990 */
+       {QMI_FIXED_INTF(0x1bc7, 0x1100, 3)},    /* Telit ME910 */
+       {QMI_FIXED_INTF(0x1bc7, 0x1101, 3)},    /* Telit ME910 dual modem */
+       {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)},    /* Telit LE920 */
index 960caacdbd2a0524838687a638e2d8493e705f53..0f372fe54cd5d8f2c3daf0309cc58f4de6a9c216 100644 (file)
@@ -75,6 +75,13 @@ selftests-rseq-fix-work-around-asm-goto-compiler-bugs.patch
 selftests-rseq-x86-64-use-fs-segment-selector-for-accessing-rseq-thread-area.patch
 selftests-rseq-x86-32-use-gs-segment-selector-for-accessing-rseq-thread-area.patch
 selftests-rseq-change-type-of-rseq_offset-to-ptrdiff_t.patch
+xen-blkfront-fix-leaking-data-in-shared-pages.patch
+xen-netfront-fix-leaking-data-in-shared-pages.patch
+xen-netfront-force-data-bouncing-when-backend-is-untrusted.patch
+xen-blkfront-force-data-bouncing-when-backend-is-untrusted.patch
+xen-netfront-restore-__skb_queue_tail-positioning-in-xennet_get_responses.patch
+xen-arm-fix-race-in-rb-tree-based-p2m-accounting.patch
+net-usb-qmi_wwan-add-telit-0x1070-composition.patch
 net-fix-iff_tx_skb_no_linear-definition.patch
 drm-i915-gem-add-missing-else.patch
 drm-msm-gem-fix-error-return-on-fence-id-alloc-fail.patch
diff --git a/queue-5.15/xen-arm-fix-race-in-rb-tree-based-p2m-accounting.patch b/queue-5.15/xen-arm-fix-race-in-rb-tree-based-p2m-accounting.patch
new file mode 100644 (file)
index 0000000..fa5cfbf
--- /dev/null
@@ -0,0 +1,72 @@
+From foo@baz Tue Jul  5 12:56:39 PM CEST 2022
+From: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
+Date: Fri, 1 Jul 2022 09:57:42 +0200
+Subject: xen/arm: Fix race in RB-tree based P2M accounting
+
+From: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
+
+commit b75cd218274e01d026dc5240e86fdeb44bbed0c8 upstream.
+
+During the PV driver life cycle the mappings are added to
+the RB-tree by set_foreign_p2m_mapping(), which is called from
+gnttab_map_refs() and are removed by clear_foreign_p2m_mapping()
+which is called from gnttab_unmap_refs(). As both functions end
+up calling __set_phys_to_machine_multi() which updates the RB-tree,
+this function can be called concurrently.
+
+There is already a "p2m_lock" to protect against concurrent accesses,
+but the problem is that the first read of "phys_to_mach.rb_node"
+in __set_phys_to_machine_multi() is not covered by it, so this might
+lead to the incorrect mappings update (removing in our case) in RB-tree.
+
+In my environment the related issue happens rarely and only when
+PV net backend is running, the xen_add_phys_to_mach_entry() claims
+that it cannot add new pfn <-> mfn mapping to the tree since it is
+already exists which results in a failure when mapping foreign pages.
+
+But there might be other bad consequences related to the non-protected
+root reads such use-after-free, etc.
+
+While at it, also fix the similar usage in __pfn_to_mfn(), so
+initialize "struct rb_node *n" with the "p2m_lock" held in both
+functions to avoid possible bad consequences.
+
+This is CVE-2022-33744 / XSA-406.
+
+Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
+Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm/xen/p2m.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/arch/arm/xen/p2m.c
++++ b/arch/arm/xen/p2m.c
+@@ -63,11 +63,12 @@ out:
+ unsigned long __pfn_to_mfn(unsigned long pfn)
+ {
+-      struct rb_node *n = phys_to_mach.rb_node;
++      struct rb_node *n;
+       struct xen_p2m_entry *entry;
+       unsigned long irqflags;
+       read_lock_irqsave(&p2m_lock, irqflags);
++      n = phys_to_mach.rb_node;
+       while (n) {
+               entry = rb_entry(n, struct xen_p2m_entry, rbnode_phys);
+               if (entry->pfn <= pfn &&
+@@ -152,10 +153,11 @@ bool __set_phys_to_machine_multi(unsigne
+       int rc;
+       unsigned long irqflags;
+       struct xen_p2m_entry *p2m_entry;
+-      struct rb_node *n = phys_to_mach.rb_node;
++      struct rb_node *n;
+       if (mfn == INVALID_P2M_ENTRY) {
+               write_lock_irqsave(&p2m_lock, irqflags);
++              n = phys_to_mach.rb_node;
+               while (n) {
+                       p2m_entry = rb_entry(n, struct xen_p2m_entry, rbnode_phys);
+                       if (p2m_entry->pfn <= pfn &&
diff --git a/queue-5.15/xen-blkfront-fix-leaking-data-in-shared-pages.patch b/queue-5.15/xen-blkfront-fix-leaking-data-in-shared-pages.patch
new file mode 100644 (file)
index 0000000..db7e18a
--- /dev/null
@@ -0,0 +1,54 @@
+From foo@baz Tue Jul  5 12:56:39 PM CEST 2022
+From: Roger Pau Monne <roger.pau@citrix.com>
+Date: Wed, 30 Mar 2022 09:03:48 +0200
+Subject: xen/blkfront: fix leaking data in shared pages
+
+From: Roger Pau Monne <roger.pau@citrix.com>
+
+commit 2f446ffe9d737e9a844b97887919c4fda18246e7 upstream.
+
+When allocating pages to be used for shared communication with the
+backend always zero them, this avoids leaking unintended data present
+on the pages.
+
+This is CVE-2022-26365, part of XSA-403.
+
+Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
+Reviewed-by: Jan Beulich <jbeulich@suse.com>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/block/xen-blkfront.c |    7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/block/xen-blkfront.c
++++ b/drivers/block/xen-blkfront.c
+@@ -312,7 +312,7 @@ static int fill_grant_buffer(struct blkf
+                       goto out_of_memory;
+               if (info->feature_persistent) {
+-                      granted_page = alloc_page(GFP_NOIO);
++                      granted_page = alloc_page(GFP_NOIO | __GFP_ZERO);
+                       if (!granted_page) {
+                               kfree(gnt_list_entry);
+                               goto out_of_memory;
+@@ -1692,7 +1692,7 @@ static int setup_blkring(struct xenbus_d
+       for (i = 0; i < info->nr_ring_pages; i++)
+               rinfo->ring_ref[i] = GRANT_INVALID_REF;
+-      sring = alloc_pages_exact(ring_size, GFP_NOIO);
++      sring = alloc_pages_exact(ring_size, GFP_NOIO | __GFP_ZERO);
+       if (!sring) {
+               xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring");
+               return -ENOMEM;
+@@ -2209,7 +2209,8 @@ static int blkfront_setup_indirect(struc
+               BUG_ON(!list_empty(&rinfo->indirect_pages));
+               for (i = 0; i < num; i++) {
+-                      struct page *indirect_page = alloc_page(GFP_KERNEL);
++                      struct page *indirect_page = alloc_page(GFP_KERNEL |
++                                                              __GFP_ZERO);
+                       if (!indirect_page)
+                               goto out_of_memory;
+                       list_add(&indirect_page->lru, &rinfo->indirect_pages);
diff --git a/queue-5.15/xen-blkfront-force-data-bouncing-when-backend-is-untrusted.patch b/queue-5.15/xen-blkfront-force-data-bouncing-when-backend-is-untrusted.patch
new file mode 100644 (file)
index 0000000..936e878
--- /dev/null
@@ -0,0 +1,203 @@
+From foo@baz Tue Jul  5 12:56:39 PM CEST 2022
+From: Roger Pau Monne <roger.pau@citrix.com>
+Date: Thu, 7 Apr 2022 13:04:24 +0200
+Subject: xen/blkfront: force data bouncing when backend is untrusted
+
+From: Roger Pau Monne <roger.pau@citrix.com>
+
+commit 2400617da7eebf9167d71a46122828bc479d64c9 upstream.
+
+Split the current bounce buffering logic used with persistent grants
+into it's own option, and allow enabling it independently of
+persistent grants.  This allows to reuse the same code paths to
+perform the bounce buffering required to avoid leaking contiguous data
+in shared pages not part of the request fragments.
+
+Reporting whether the backend is to be trusted can be done using a
+module parameter, or from the xenstore frontend path as set by the
+toolstack when adding the device.
+
+This is CVE-2022-33742, part of XSA-403.
+
+Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/block/xen-blkfront.c |   49 +++++++++++++++++++++++++++++--------------
+ 1 file changed, 34 insertions(+), 15 deletions(-)
+
+--- a/drivers/block/xen-blkfront.c
++++ b/drivers/block/xen-blkfront.c
+@@ -152,6 +152,10 @@ static unsigned int xen_blkif_max_ring_o
+ module_param_named(max_ring_page_order, xen_blkif_max_ring_order, int, 0444);
+ MODULE_PARM_DESC(max_ring_page_order, "Maximum order of pages to be used for the shared ring");
++static bool __read_mostly xen_blkif_trusted = true;
++module_param_named(trusted, xen_blkif_trusted, bool, 0644);
++MODULE_PARM_DESC(trusted, "Is the backend trusted");
++
+ #define BLK_RING_SIZE(info)   \
+       __CONST_RING_SIZE(blkif, XEN_PAGE_SIZE * (info)->nr_ring_pages)
+@@ -209,6 +213,7 @@ struct blkfront_info
+       unsigned int feature_discard:1;
+       unsigned int feature_secdiscard:1;
+       unsigned int feature_persistent:1;
++      unsigned int bounce:1;
+       unsigned int discard_granularity;
+       unsigned int discard_alignment;
+       /* Number of 4KB segments handled */
+@@ -311,7 +316,7 @@ static int fill_grant_buffer(struct blkf
+               if (!gnt_list_entry)
+                       goto out_of_memory;
+-              if (info->feature_persistent) {
++              if (info->bounce) {
+                       granted_page = alloc_page(GFP_NOIO | __GFP_ZERO);
+                       if (!granted_page) {
+                               kfree(gnt_list_entry);
+@@ -331,7 +336,7 @@ out_of_memory:
+       list_for_each_entry_safe(gnt_list_entry, n,
+                                &rinfo->grants, node) {
+               list_del(&gnt_list_entry->node);
+-              if (info->feature_persistent)
++              if (info->bounce)
+                       __free_page(gnt_list_entry->page);
+               kfree(gnt_list_entry);
+               i--;
+@@ -377,7 +382,7 @@ static struct grant *get_grant(grant_ref
+       /* Assign a gref to this page */
+       gnt_list_entry->gref = gnttab_claim_grant_reference(gref_head);
+       BUG_ON(gnt_list_entry->gref == -ENOSPC);
+-      if (info->feature_persistent)
++      if (info->bounce)
+               grant_foreign_access(gnt_list_entry, info);
+       else {
+               /* Grant access to the GFN passed by the caller */
+@@ -401,7 +406,7 @@ static struct grant *get_indirect_grant(
+       /* Assign a gref to this page */
+       gnt_list_entry->gref = gnttab_claim_grant_reference(gref_head);
+       BUG_ON(gnt_list_entry->gref == -ENOSPC);
+-      if (!info->feature_persistent) {
++      if (!info->bounce) {
+               struct page *indirect_page;
+               /* Fetch a pre-allocated page to use for indirect grefs */
+@@ -703,7 +708,7 @@ static int blkif_queue_rw_req(struct req
+               .grant_idx = 0,
+               .segments = NULL,
+               .rinfo = rinfo,
+-              .need_copy = rq_data_dir(req) && info->feature_persistent,
++              .need_copy = rq_data_dir(req) && info->bounce,
+       };
+       /*
+@@ -981,11 +986,12 @@ static void xlvbd_flush(struct blkfront_
+ {
+       blk_queue_write_cache(info->rq, info->feature_flush ? true : false,
+                             info->feature_fua ? true : false);
+-      pr_info("blkfront: %s: %s %s %s %s %s\n",
++      pr_info("blkfront: %s: %s %s %s %s %s %s %s\n",
+               info->gd->disk_name, flush_info(info),
+               "persistent grants:", info->feature_persistent ?
+               "enabled;" : "disabled;", "indirect descriptors:",
+-              info->max_indirect_segments ? "enabled;" : "disabled;");
++              info->max_indirect_segments ? "enabled;" : "disabled;",
++              "bounce buffer:", info->bounce ? "enabled" : "disabled;");
+ }
+ static int xen_translate_vdev(int vdevice, int *minor, unsigned int *offset)
+@@ -1212,7 +1218,7 @@ static void blkif_free_ring(struct blkfr
+       if (!list_empty(&rinfo->indirect_pages)) {
+               struct page *indirect_page, *n;
+-              BUG_ON(info->feature_persistent);
++              BUG_ON(info->bounce);
+               list_for_each_entry_safe(indirect_page, n, &rinfo->indirect_pages, lru) {
+                       list_del(&indirect_page->lru);
+                       __free_page(indirect_page);
+@@ -1229,7 +1235,7 @@ static void blkif_free_ring(struct blkfr
+                                                         0, 0UL);
+                               rinfo->persistent_gnts_c--;
+                       }
+-                      if (info->feature_persistent)
++                      if (info->bounce)
+                               __free_page(persistent_gnt->page);
+                       kfree(persistent_gnt);
+               }
+@@ -1250,7 +1256,7 @@ static void blkif_free_ring(struct blkfr
+               for (j = 0; j < segs; j++) {
+                       persistent_gnt = rinfo->shadow[i].grants_used[j];
+                       gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL);
+-                      if (info->feature_persistent)
++                      if (info->bounce)
+                               __free_page(persistent_gnt->page);
+                       kfree(persistent_gnt);
+               }
+@@ -1440,7 +1446,7 @@ static int blkif_completion(unsigned lon
+       data.s = s;
+       num_sg = s->num_sg;
+-      if (bret->operation == BLKIF_OP_READ && info->feature_persistent) {
++      if (bret->operation == BLKIF_OP_READ && info->bounce) {
+               for_each_sg(s->sg, sg, num_sg, i) {
+                       BUG_ON(sg->offset + sg->length > PAGE_SIZE);
+@@ -1499,7 +1505,7 @@ static int blkif_completion(unsigned lon
+                                * Add the used indirect page back to the list of
+                                * available pages for indirect grefs.
+                                */
+-                              if (!info->feature_persistent) {
++                              if (!info->bounce) {
+                                       indirect_page = s->indirect_grants[i]->page;
+                                       list_add(&indirect_page->lru, &rinfo->indirect_pages);
+                               }
+@@ -1790,6 +1796,10 @@ static int talk_to_blkback(struct xenbus
+       if (!info)
+               return -ENODEV;
++      /* Check if backend is trusted. */
++      info->bounce = !xen_blkif_trusted ||
++                     !xenbus_read_unsigned(dev->nodename, "trusted", 1);
++
+       max_page_order = xenbus_read_unsigned(info->xbdev->otherend,
+                                             "max-ring-page-order", 0);
+       ring_page_order = min(xen_blkif_max_ring_order, max_page_order);
+@@ -2199,10 +2209,10 @@ static int blkfront_setup_indirect(struc
+       if (err)
+               goto out_of_memory;
+-      if (!info->feature_persistent && info->max_indirect_segments) {
++      if (!info->bounce && info->max_indirect_segments) {
+               /*
+-               * We are using indirect descriptors but not persistent
+-               * grants, we need to allocate a set of pages that can be
++               * We are using indirect descriptors but don't have a bounce
++               * buffer, we need to allocate a set of pages that can be
+                * used for mapping indirect grefs
+                */
+               int num = INDIRECT_GREFS(grants) * BLK_RING_SIZE(info);
+@@ -2303,6 +2313,8 @@ static void blkfront_gather_backend_feat
+               info->feature_persistent =
+                       !!xenbus_read_unsigned(info->xbdev->otherend,
+                                              "feature-persistent", 0);
++      if (info->feature_persistent)
++              info->bounce = true;
+       indirect_segments = xenbus_read_unsigned(info->xbdev->otherend,
+                                       "feature-max-indirect-segments", 0);
+@@ -2566,6 +2578,13 @@ static void blkfront_delay_work(struct w
+       struct blkfront_info *info;
+       bool need_schedule_work = false;
++      /*
++       * Note that when using bounce buffers but not persistent grants
++       * there's no need to run blkfront_delay_work because grants are
++       * revoked in blkif_completion or else an error is reported and the
++       * connection is closed.
++       */
++
+       mutex_lock(&blkfront_mutex);
+       list_for_each_entry(info, &info_list, info_list) {
diff --git a/queue-5.15/xen-netfront-fix-leaking-data-in-shared-pages.patch b/queue-5.15/xen-netfront-fix-leaking-data-in-shared-pages.patch
new file mode 100644 (file)
index 0000000..1136dac
--- /dev/null
@@ -0,0 +1,36 @@
+From foo@baz Tue Jul  5 12:56:39 PM CEST 2022
+From: Roger Pau Monne <roger.pau@citrix.com>
+Date: Wed, 6 Apr 2022 17:38:04 +0200
+Subject: xen/netfront: fix leaking data in shared pages
+
+From: Roger Pau Monne <roger.pau@citrix.com>
+
+commit 307c8de2b02344805ebead3440d8feed28f2f010 upstream.
+
+When allocating pages to be used for shared communication with the
+backend always zero them, this avoids leaking unintended data present
+on the pages.
+
+This is CVE-2022-33740, part of XSA-403.
+
+Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
+Reviewed-by: Jan Beulich <jbeulich@suse.com>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/xen-netfront.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/xen-netfront.c
++++ b/drivers/net/xen-netfront.c
+@@ -273,7 +273,8 @@ static struct sk_buff *xennet_alloc_one_
+       if (unlikely(!skb))
+               return NULL;
+-      page = page_pool_dev_alloc_pages(queue->page_pool);
++      page = page_pool_alloc_pages(queue->page_pool,
++                                   GFP_ATOMIC | __GFP_NOWARN | __GFP_ZERO);
+       if (unlikely(!page)) {
+               kfree_skb(skb);
+               return NULL;
diff --git a/queue-5.15/xen-netfront-force-data-bouncing-when-backend-is-untrusted.patch b/queue-5.15/xen-netfront-force-data-bouncing-when-backend-is-untrusted.patch
new file mode 100644 (file)
index 0000000..8d3e832
--- /dev/null
@@ -0,0 +1,124 @@
+From foo@baz Tue Jul  5 12:56:39 PM CEST 2022
+From: Roger Pau Monne <roger.pau@citrix.com>
+Date: Thu, 7 Apr 2022 12:20:06 +0200
+Subject: xen/netfront: force data bouncing when backend is untrusted
+
+From: Roger Pau Monne <roger.pau@citrix.com>
+
+commit 4491001c2e0fa69efbb748c96ec96b100a5cdb7e upstream.
+
+Bounce all data on the skbs to be transmitted into zeroed pages if the
+backend is untrusted. This avoids leaking data present in the pages
+shared with the backend but not part of the skb fragments.  This
+requires introducing a new helper in order to allocate skbs with a
+size multiple of XEN_PAGE_SIZE so we don't leak contiguous data on the
+granted pages.
+
+Reporting whether the backend is to be trusted can be done using a
+module parameter, or from the xenstore frontend path as set by the
+toolstack when adding the device.
+
+This is CVE-2022-33741, part of XSA-403.
+
+Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/xen-netfront.c |   49 +++++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 47 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/xen-netfront.c
++++ b/drivers/net/xen-netfront.c
+@@ -66,6 +66,10 @@ module_param_named(max_queues, xennet_ma
+ MODULE_PARM_DESC(max_queues,
+                "Maximum number of queues per virtual interface");
++static bool __read_mostly xennet_trusted = true;
++module_param_named(trusted, xennet_trusted, bool, 0644);
++MODULE_PARM_DESC(trusted, "Is the backend trusted");
++
+ #define XENNET_TIMEOUT  (5 * HZ)
+ static const struct ethtool_ops xennet_ethtool_ops;
+@@ -175,6 +179,9 @@ struct netfront_info {
+       /* Is device behaving sane? */
+       bool broken;
++      /* Should skbs be bounced into a zeroed buffer? */
++      bool bounce;
++
+       atomic_t rx_gso_checksum_fixup;
+ };
+@@ -668,6 +675,33 @@ static int xennet_xdp_xmit(struct net_de
+       return nxmit;
+ }
++struct sk_buff *bounce_skb(const struct sk_buff *skb)
++{
++      unsigned int headerlen = skb_headroom(skb);
++      /* Align size to allocate full pages and avoid contiguous data leaks */
++      unsigned int size = ALIGN(skb_end_offset(skb) + skb->data_len,
++                                XEN_PAGE_SIZE);
++      struct sk_buff *n = alloc_skb(size, GFP_ATOMIC | __GFP_ZERO);
++
++      if (!n)
++              return NULL;
++
++      if (!IS_ALIGNED((uintptr_t)n->head, XEN_PAGE_SIZE)) {
++              WARN_ONCE(1, "misaligned skb allocated\n");
++              kfree_skb(n);
++              return NULL;
++      }
++
++      /* Set the data pointer */
++      skb_reserve(n, headerlen);
++      /* Set the tail pointer and length */
++      skb_put(n, skb->len);
++
++      BUG_ON(skb_copy_bits(skb, -headerlen, n->head, headerlen + skb->len));
++
++      skb_copy_header(n, skb);
++      return n;
++}
+ #define MAX_XEN_SKB_FRAGS (65536 / XEN_PAGE_SIZE + 1)
+@@ -721,9 +755,13 @@ static netdev_tx_t xennet_start_xmit(str
+       /* The first req should be at least ETH_HLEN size or the packet will be
+        * dropped by netback.
++       *
++       * If the backend is not trusted bounce all data to zeroed pages to
++       * avoid exposing contiguous data on the granted page not belonging to
++       * the skb.
+        */
+-      if (unlikely(PAGE_SIZE - offset < ETH_HLEN)) {
+-              nskb = skb_copy(skb, GFP_ATOMIC);
++      if (np->bounce || unlikely(PAGE_SIZE - offset < ETH_HLEN)) {
++              nskb = bounce_skb(skb);
+               if (!nskb)
+                       goto drop;
+               dev_consume_skb_any(skb);
+@@ -2247,6 +2285,10 @@ static int talk_to_netback(struct xenbus
+       info->netdev->irq = 0;
++      /* Check if backend is trusted. */
++      info->bounce = !xennet_trusted ||
++                     !xenbus_read_unsigned(dev->nodename, "trusted", 1);
++
+       /* Check if backend supports multiple queues */
+       max_queues = xenbus_read_unsigned(info->xbdev->otherend,
+                                         "multi-queue-max-queues", 1);
+@@ -2413,6 +2455,9 @@ static int xennet_connect(struct net_dev
+               return err;
+       if (np->netback_has_xdp_headroom)
+               pr_info("backend supports XDP headroom\n");
++      if (np->bounce)
++              dev_info(&np->xbdev->dev,
++                       "bouncing transmitted data to zeroed pages\n");
+       /* talk_to_netback() sets the correct number of queues */
+       num_queues = dev->real_num_tx_queues;
diff --git a/queue-5.15/xen-netfront-restore-__skb_queue_tail-positioning-in-xennet_get_responses.patch b/queue-5.15/xen-netfront-restore-__skb_queue_tail-positioning-in-xennet_get_responses.patch
new file mode 100644 (file)
index 0000000..465280b
--- /dev/null
@@ -0,0 +1,40 @@
+From foo@baz Tue Jul  5 12:56:39 PM CEST 2022
+From: Jan Beulich <jbeulich@suse.com>
+Date: Fri, 1 Jul 2022 09:57:19 +0200
+Subject: xen-netfront: restore __skb_queue_tail() positioning in xennet_get_responses()
+
+From: Jan Beulich <jbeulich@suse.com>
+
+commit f63c2c2032c2e3caad9add3b82cc6e91c376fd26 upstream.
+
+The commit referenced below moved the invocation past the "next" label,
+without any explanation. In fact this allows misbehaving backends undue
+control over the domain the frontend runs in, as earlier detected errors
+require the skb to not be freed (it may be retained for later processing
+via xennet_move_rx_slot(), or it may simply be unsafe to have it freed).
+
+This is CVE-2022-33743 / XSA-405.
+
+Fixes: 6c5aa6fc4def ("xen networking: add basic XDP support for xen-netfront")
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/xen-netfront.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/xen-netfront.c
++++ b/drivers/net/xen-netfront.c
+@@ -1094,8 +1094,10 @@ static int xennet_get_responses(struct n
+                       }
+               }
+               rcu_read_unlock();
+-next:
++
+               __skb_queue_tail(list, skb);
++
++next:
+               if (!(rx->flags & XEN_NETRXF_more_data))
+                       break;