]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 4 Dec 2021 10:47:43 +0000 (11:47 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 4 Dec 2021 10:47:43 +0000 (11:47 +0100)
added patches:
ipmi-move-remove_work-to-dedicated-workqueue.patch
kprobes-limit-max-data_size-of-the-kretprobe-instances.patch
sata_fsl-fix-uaf-in-sata_fsl_port_stop-when-rmmod-sata_fsl.patch
sata_fsl-fix-warning-in-remove_proc_entry-when-rmmod-sata_fsl.patch
vrf-reset-ipcb-ip6cb-when-processing-outbound-pkts-in-vrf-dev-xmit.patch

queue-4.19/ipmi-move-remove_work-to-dedicated-workqueue.patch [new file with mode: 0644]
queue-4.19/kprobes-limit-max-data_size-of-the-kretprobe-instances.patch [new file with mode: 0644]
queue-4.19/sata_fsl-fix-uaf-in-sata_fsl_port_stop-when-rmmod-sata_fsl.patch [new file with mode: 0644]
queue-4.19/sata_fsl-fix-warning-in-remove_proc_entry-when-rmmod-sata_fsl.patch [new file with mode: 0644]
queue-4.19/series
queue-4.19/vrf-reset-ipcb-ip6cb-when-processing-outbound-pkts-in-vrf-dev-xmit.patch [new file with mode: 0644]

diff --git a/queue-4.19/ipmi-move-remove_work-to-dedicated-workqueue.patch b/queue-4.19/ipmi-move-remove_work-to-dedicated-workqueue.patch
new file mode 100644 (file)
index 0000000..a553383
--- /dev/null
@@ -0,0 +1,80 @@
+From 1d49eb91e86e8c1c1614c72e3e958b6b7e2472a9 Mon Sep 17 00:00:00 2001
+From: Ioanna Alifieraki <ioanna-maria.alifieraki@canonical.com>
+Date: Mon, 15 Nov 2021 15:16:45 +0200
+Subject: ipmi: Move remove_work to dedicated workqueue
+
+From: Ioanna Alifieraki <ioanna-maria.alifieraki@canonical.com>
+
+commit 1d49eb91e86e8c1c1614c72e3e958b6b7e2472a9 upstream.
+
+Currently when removing an ipmi_user the removal is deferred as a work on
+the system's workqueue. Although this guarantees the free operation will
+occur in non atomic context, it can race with the ipmi_msghandler module
+removal (see [1]) . In case a remove_user work is scheduled for removal
+and shortly after ipmi_msghandler module is removed we can end up in a
+situation where the module is removed fist and when the work is executed
+the system crashes with :
+BUG: unable to handle page fault for address: ffffffffc05c3450
+PF: supervisor instruction fetch in kernel mode
+PF: error_code(0x0010) - not-present page
+because the pages of the module are gone. In cleanup_ipmi() there is no
+easy way to detect if there are any pending works to flush them before
+removing the module. This patch creates a separate workqueue and schedules
+the remove_work works on it. When removing the module the workqueue is
+drained when destroyed to avoid the race.
+
+[1] https://bugs.launchpad.net/bugs/1950666
+
+Cc: stable@vger.kernel.org # 5.1
+Fixes: 3b9a907223d7 (ipmi: fix sleep-in-atomic in free_user at cleanup SRCU user->release_barrier)
+Signed-off-by: Ioanna Alifieraki <ioanna-maria.alifieraki@canonical.com>
+Message-Id: <20211115131645.25116-1-ioanna-maria.alifieraki@canonical.com>
+Signed-off-by: Corey Minyard <cminyard@mvista.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/char/ipmi/ipmi_msghandler.c |   13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+--- a/drivers/char/ipmi/ipmi_msghandler.c
++++ b/drivers/char/ipmi/ipmi_msghandler.c
+@@ -219,6 +219,8 @@ struct ipmi_user {
+       struct work_struct remove_work;
+ };
++struct workqueue_struct *remove_work_wq;
++
+ static struct ipmi_user *acquire_ipmi_user(struct ipmi_user *user, int *index)
+       __acquires(user->release_barrier)
+ {
+@@ -1207,7 +1209,7 @@ static void free_user(struct kref *ref)
+       struct ipmi_user *user = container_of(ref, struct ipmi_user, refcount);
+       /* SRCU cleanup must happen in task context. */
+-      schedule_work(&user->remove_work);
++      queue_work(remove_work_wq, &user->remove_work);
+ }
+ static void _ipmi_destroy_user(struct ipmi_user *user)
+@@ -5090,6 +5092,13 @@ static int ipmi_init_msghandler(void)
+       atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
++      remove_work_wq = create_singlethread_workqueue("ipmi-msghandler-remove-wq");
++      if (!remove_work_wq) {
++              pr_err("unable to create ipmi-msghandler-remove-wq workqueue");
++              rv = -ENOMEM;
++              goto out;
++      }
++
+       initialized = true;
+ out:
+@@ -5115,6 +5124,8 @@ static void __exit cleanup_ipmi(void)
+       int count;
+       if (initialized) {
++              destroy_workqueue(remove_work_wq);
++
+               atomic_notifier_chain_unregister(&panic_notifier_list,
+                                                &panic_block);
diff --git a/queue-4.19/kprobes-limit-max-data_size-of-the-kretprobe-instances.patch b/queue-4.19/kprobes-limit-max-data_size-of-the-kretprobe-instances.patch
new file mode 100644 (file)
index 0000000..ca31d53
--- /dev/null
@@ -0,0 +1,55 @@
+From 6bbfa44116689469267f1a6e3d233b52114139d2 Mon Sep 17 00:00:00 2001
+From: Masami Hiramatsu <mhiramat@kernel.org>
+Date: Wed, 1 Dec 2021 23:45:50 +0900
+Subject: kprobes: Limit max data_size of the kretprobe instances
+
+From: Masami Hiramatsu <mhiramat@kernel.org>
+
+commit 6bbfa44116689469267f1a6e3d233b52114139d2 upstream.
+
+The 'kprobe::data_size' is unsigned, thus it can not be negative.  But if
+user sets it enough big number (e.g. (size_t)-8), the result of 'data_size
++ sizeof(struct kretprobe_instance)' becomes smaller than sizeof(struct
+kretprobe_instance) or zero. In result, the kretprobe_instance are
+allocated without enough memory, and kretprobe accesses outside of
+allocated memory.
+
+To avoid this issue, introduce a max limitation of the
+kretprobe::data_size. 4KB per instance should be OK.
+
+Link: https://lkml.kernel.org/r/163836995040.432120.10322772773821182925.stgit@devnote2
+
+Cc: stable@vger.kernel.org
+Fixes: f47cd9b553aa ("kprobes: kretprobe user entry-handler")
+Reported-by: zhangyue <zhangyue1@kylinos.cn>
+Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/kprobes.h |    2 ++
+ kernel/kprobes.c        |    3 +++
+ 2 files changed, 5 insertions(+)
+
+--- a/include/linux/kprobes.h
++++ b/include/linux/kprobes.h
+@@ -168,6 +168,8 @@ struct kretprobe {
+       raw_spinlock_t lock;
+ };
++#define KRETPROBE_MAX_DATA_SIZE       4096
++
+ struct kretprobe_instance {
+       struct hlist_node hlist;
+       struct kretprobe *rp;
+--- a/kernel/kprobes.c
++++ b/kernel/kprobes.c
+@@ -1976,6 +1976,9 @@ int register_kretprobe(struct kretprobe
+               }
+       }
++      if (rp->data_size > KRETPROBE_MAX_DATA_SIZE)
++              return -E2BIG;
++
+       rp->kp.pre_handler = pre_handler_kretprobe;
+       rp->kp.post_handler = NULL;
+       rp->kp.fault_handler = NULL;
diff --git a/queue-4.19/sata_fsl-fix-uaf-in-sata_fsl_port_stop-when-rmmod-sata_fsl.patch b/queue-4.19/sata_fsl-fix-uaf-in-sata_fsl_port_stop-when-rmmod-sata_fsl.patch
new file mode 100644 (file)
index 0000000..b307ced
--- /dev/null
@@ -0,0 +1,98 @@
+From 6c8ad7e8cf29eb55836e7a0215f967746ab2b504 Mon Sep 17 00:00:00 2001
+From: Baokun Li <libaokun1@huawei.com>
+Date: Fri, 26 Nov 2021 10:03:06 +0800
+Subject: sata_fsl: fix UAF in sata_fsl_port_stop when rmmod sata_fsl
+
+From: Baokun Li <libaokun1@huawei.com>
+
+commit 6c8ad7e8cf29eb55836e7a0215f967746ab2b504 upstream.
+
+When the `rmmod sata_fsl.ko` command is executed in the PPC64 GNU/Linux,
+a bug is reported:
+ ==================================================================
+ BUG: Unable to handle kernel data access on read at 0x80000800805b502c
+ Oops: Kernel access of bad area, sig: 11 [#1]
+ NIP [c0000000000388a4] .ioread32+0x4/0x20
+ LR [80000000000c6034] .sata_fsl_port_stop+0x44/0xe0 [sata_fsl]
+ Call Trace:
+  .free_irq+0x1c/0x4e0 (unreliable)
+  .ata_host_stop+0x74/0xd0 [libata]
+  .release_nodes+0x330/0x3f0
+  .device_release_driver_internal+0x178/0x2c0
+  .driver_detach+0x64/0xd0
+  .bus_remove_driver+0x70/0xf0
+  .driver_unregister+0x38/0x80
+  .platform_driver_unregister+0x14/0x30
+  .fsl_sata_driver_exit+0x18/0xa20 [sata_fsl]
+  .__se_sys_delete_module+0x1ec/0x2d0
+  .system_call_exception+0xfc/0x1f0
+  system_call_common+0xf8/0x200
+ ==================================================================
+
+The triggering of the BUG is shown in the following stack:
+
+driver_detach
+  device_release_driver_internal
+    __device_release_driver
+      drv->remove(dev) --> platform_drv_remove/platform_remove
+        drv->remove(dev) --> sata_fsl_remove
+          iounmap(host_priv->hcr_base);                        <---- unmap
+          kfree(host_priv);                             <---- free
+      devres_release_all
+        release_nodes
+          dr->node.release(dev, dr->data) --> ata_host_stop
+            ap->ops->port_stop(ap) --> sata_fsl_port_stop
+                ioread32(hcr_base + HCONTROL)           <---- UAF
+            host->ops->host_stop(host)
+
+The iounmap(host_priv->hcr_base) and kfree(host_priv) functions should
+not be executed in drv->remove. These functions should be executed in
+host_stop after port_stop. Therefore, we move these functions to the
+new function sata_fsl_host_stop and bind the new function to host_stop.
+
+Fixes: faf0b2e5afe7 ("drivers/ata: add support to Freescale 3.0Gbps SATA Controller")
+Cc: stable@vger.kernel.org
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Reviewed-by: Sergei Shtylyov <sergei.shtylyov@gmail.com>
+Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/ata/sata_fsl.c |   12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+--- a/drivers/ata/sata_fsl.c
++++ b/drivers/ata/sata_fsl.c
+@@ -1399,6 +1399,14 @@ static int sata_fsl_init_controller(stru
+       return 0;
+ }
++static void sata_fsl_host_stop(struct ata_host *host)
++{
++        struct sata_fsl_host_priv *host_priv = host->private_data;
++
++        iounmap(host_priv->hcr_base);
++        kfree(host_priv);
++}
++
+ /*
+  * scsi mid-layer and libata interface structures
+  */
+@@ -1431,6 +1439,8 @@ static struct ata_port_operations sata_f
+       .port_start = sata_fsl_port_start,
+       .port_stop = sata_fsl_port_stop,
++      .host_stop      = sata_fsl_host_stop,
++
+       .pmp_attach = sata_fsl_pmp_attach,
+       .pmp_detach = sata_fsl_pmp_detach,
+ };
+@@ -1563,8 +1573,6 @@ static int sata_fsl_remove(struct platfo
+       ata_host_detach(host);
+       irq_dispose_mapping(host_priv->irq);
+-      iounmap(host_priv->hcr_base);
+-      kfree(host_priv);
+       return 0;
+ }
diff --git a/queue-4.19/sata_fsl-fix-warning-in-remove_proc_entry-when-rmmod-sata_fsl.patch b/queue-4.19/sata_fsl-fix-warning-in-remove_proc_entry-when-rmmod-sata_fsl.patch
new file mode 100644 (file)
index 0000000..e4f99ff
--- /dev/null
@@ -0,0 +1,78 @@
+From 6f48394cf1f3e8486591ad98c11cdadb8f1ef2ad Mon Sep 17 00:00:00 2001
+From: Baokun Li <libaokun1@huawei.com>
+Date: Fri, 26 Nov 2021 10:03:07 +0800
+Subject: sata_fsl: fix warning in remove_proc_entry when rmmod sata_fsl
+
+From: Baokun Li <libaokun1@huawei.com>
+
+commit 6f48394cf1f3e8486591ad98c11cdadb8f1ef2ad upstream.
+
+Trying to remove the fsl-sata module in the PPC64 GNU/Linux
+leads to the following warning:
+ ------------[ cut here ]------------
+ remove_proc_entry: removing non-empty directory 'irq/69',
+   leaking at least 'fsl-sata[ff0221000.sata]'
+ WARNING: CPU: 3 PID: 1048 at fs/proc/generic.c:722
+   .remove_proc_entry+0x20c/0x220
+ IRQMASK: 0
+ NIP [c00000000033826c] .remove_proc_entry+0x20c/0x220
+ LR [c000000000338268] .remove_proc_entry+0x208/0x220
+ Call Trace:
+  .remove_proc_entry+0x208/0x220 (unreliable)
+  .unregister_irq_proc+0x104/0x140
+  .free_desc+0x44/0xb0
+  .irq_free_descs+0x9c/0xf0
+  .irq_dispose_mapping+0x64/0xa0
+  .sata_fsl_remove+0x58/0xa0 [sata_fsl]
+  .platform_drv_remove+0x40/0x90
+  .device_release_driver_internal+0x160/0x2c0
+  .driver_detach+0x64/0xd0
+  .bus_remove_driver+0x70/0xf0
+  .driver_unregister+0x38/0x80
+  .platform_driver_unregister+0x14/0x30
+  .fsl_sata_driver_exit+0x18/0xa20 [sata_fsl]
+ ---[ end trace 0ea876d4076908f5 ]---
+
+The driver creates the mapping by calling irq_of_parse_and_map(),
+so it also has to dispose the mapping. But the easy way out is to
+simply use platform_get_irq() instead of irq_of_parse_map(). Also
+we should adapt return value checking and propagate error values.
+
+In this case the mapping is not managed by the device but by
+the of core, so the device has not to dispose the mapping.
+
+Fixes: faf0b2e5afe7 ("drivers/ata: add support to Freescale 3.0Gbps SATA Controller")
+Cc: stable@vger.kernel.org
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Reviewed-by: Sergei Shtylyov <sergei.shtylyov@gmail.com>
+Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/ata/sata_fsl.c |    8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+--- a/drivers/ata/sata_fsl.c
++++ b/drivers/ata/sata_fsl.c
+@@ -1495,9 +1495,9 @@ static int sata_fsl_probe(struct platfor
+       host_priv->ssr_base = ssr_base;
+       host_priv->csr_base = csr_base;
+-      irq = irq_of_parse_and_map(ofdev->dev.of_node, 0);
+-      if (!irq) {
+-              dev_err(&ofdev->dev, "invalid irq from platform\n");
++      irq = platform_get_irq(ofdev, 0);
++      if (irq < 0) {
++              retval = irq;
+               goto error_exit_with_cleanup;
+       }
+       host_priv->irq = irq;
+@@ -1572,8 +1572,6 @@ static int sata_fsl_remove(struct platfo
+       ata_host_detach(host);
+-      irq_dispose_mapping(host_priv->irq);
+-
+       return 0;
+ }
index c741c5f2ff48f57e1df7b45e2076fb31529e2c3b..19dd2d5468e0a75c3a3342fd7f219ab1e7eec386 100644 (file)
@@ -14,3 +14,8 @@ ethernet-hisilicon-hns-hns_dsaf_misc-fix-a-possible-.patch
 net-tulip-de4x5-fix-the-problem-that-the-array-lp-ph.patch
 net-ethernet-dec-tulip-de4x5-fix-possible-array-over.patch
 perf-hist-fix-memory-leak-of-a-perf_hpp_fmt.patch
+vrf-reset-ipcb-ip6cb-when-processing-outbound-pkts-in-vrf-dev-xmit.patch
+kprobes-limit-max-data_size-of-the-kretprobe-instances.patch
+ipmi-move-remove_work-to-dedicated-workqueue.patch
+sata_fsl-fix-uaf-in-sata_fsl_port_stop-when-rmmod-sata_fsl.patch
+sata_fsl-fix-warning-in-remove_proc_entry-when-rmmod-sata_fsl.patch
diff --git a/queue-4.19/vrf-reset-ipcb-ip6cb-when-processing-outbound-pkts-in-vrf-dev-xmit.patch b/queue-4.19/vrf-reset-ipcb-ip6cb-when-processing-outbound-pkts-in-vrf-dev-xmit.patch
new file mode 100644 (file)
index 0000000..78a3356
--- /dev/null
@@ -0,0 +1,51 @@
+From ee201011c1e1563c114a55c86eb164b236f18e84 Mon Sep 17 00:00:00 2001
+From: Stephen Suryaputra <ssuryaextr@gmail.com>
+Date: Tue, 30 Nov 2021 11:26:37 -0500
+Subject: vrf: Reset IPCB/IP6CB when processing outbound pkts in vrf dev xmit
+
+From: Stephen Suryaputra <ssuryaextr@gmail.com>
+
+commit ee201011c1e1563c114a55c86eb164b236f18e84 upstream.
+
+IPCB/IP6CB need to be initialized when processing outbound v4 or v6 pkts
+in the codepath of vrf device xmit function so that leftover garbage
+doesn't cause futher code that uses the CB to incorrectly process the
+pkt.
+
+One occasion of the issue might occur when MPLS route uses the vrf
+device as the outgoing device such as when the route is added using "ip
+-f mpls route add <label> dev <vrf>" command.
+
+The problems seems to exist since day one. Hence I put the day one
+commits on the Fixes tags.
+
+Fixes: 193125dbd8eb ("net: Introduce VRF device driver")
+Fixes: 35402e313663 ("net: Add IPv6 support to VRF device")
+Cc: stable@vger.kernel.org
+Signed-off-by: Stephen Suryaputra <ssuryaextr@gmail.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://lore.kernel.org/r/20211130162637.3249-1-ssuryaextr@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/vrf.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/vrf.c
++++ b/drivers/net/vrf.c
+@@ -210,6 +210,7 @@ static netdev_tx_t vrf_process_v6_outbou
+       /* strip the ethernet header added for pass through VRF device */
+       __skb_pull(skb, skb_network_offset(skb));
++      memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
+       ret = vrf_ip6_local_out(net, skb->sk, skb);
+       if (unlikely(net_xmit_eval(ret)))
+               dev->stats.tx_errors++;
+@@ -291,6 +292,7 @@ static netdev_tx_t vrf_process_v4_outbou
+                                              RT_SCOPE_LINK);
+       }
++      memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
+       ret = vrf_ip_local_out(dev_net(skb_dst(skb)->dev), skb->sk, skb);
+       if (unlikely(net_xmit_eval(ret)))
+               vrf_dev->stats.tx_errors++;