]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.20-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 24 Jan 2019 19:05:25 +0000 (20:05 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 24 Jan 2019 19:05:25 +0000 (20:05 +0100)
added patches:
ipmi-don-t-initialize-anything-in-the-core-until-something-uses-it.patch
ipmi-fix-use-after-free-of-user-release_barrier.rda.patch
ipmi-msghandler-fix-potential-spectre-v1-vulnerabilities.patch
ipmi-prevent-use-after-free-in-deliver_response.patch
ipmi-ssif-fix-handling-of-multi-part-return-messages.patch

queue-4.20/ipmi-don-t-initialize-anything-in-the-core-until-something-uses-it.patch [new file with mode: 0644]
queue-4.20/ipmi-fix-use-after-free-of-user-release_barrier.rda.patch [new file with mode: 0644]
queue-4.20/ipmi-msghandler-fix-potential-spectre-v1-vulnerabilities.patch [new file with mode: 0644]
queue-4.20/ipmi-prevent-use-after-free-in-deliver_response.patch [new file with mode: 0644]
queue-4.20/ipmi-ssif-fix-handling-of-multi-part-return-messages.patch [new file with mode: 0644]
queue-4.20/series

diff --git a/queue-4.20/ipmi-don-t-initialize-anything-in-the-core-until-something-uses-it.patch b/queue-4.20/ipmi-don-t-initialize-anything-in-the-core-until-something-uses-it.patch
new file mode 100644 (file)
index 0000000..ea13ca7
--- /dev/null
@@ -0,0 +1,252 @@
+From 913a89f009d98c85a902d718cd54bb32ab11d167 Mon Sep 17 00:00:00 2001
+From: Corey Minyard <cminyard@mvista.com>
+Date: Thu, 20 Dec 2018 16:50:23 -0600
+Subject: ipmi: Don't initialize anything in the core until something uses it
+
+From: Corey Minyard <cminyard@mvista.com>
+
+commit 913a89f009d98c85a902d718cd54bb32ab11d167 upstream.
+
+The IPMI driver was recently modified to use SRCU, but it turns out
+this uses a chunk of percpu memory, even if IPMI is never used.
+
+So modify thing to on initialize on the first use.  There was already
+code to sort of handle this for handling init races, so piggy back
+on top of that, and simplify it in the process.
+
+Signed-off-by: Corey Minyard <cminyard@mvista.com>
+Reported-by: Tejun Heo <tj@kernel.org>
+Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+Reviewed-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+Cc: stable@vger.kernel.org # 4.18
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/ipmi/ipmi_msghandler.c |  143 ++++++++++++++++++++----------------
+ 1 file changed, 80 insertions(+), 63 deletions(-)
+
+--- a/drivers/char/ipmi/ipmi_msghandler.c
++++ b/drivers/char/ipmi/ipmi_msghandler.c
+@@ -62,7 +62,8 @@ static void ipmi_debug_msg(const char *t
+ { }
+ #endif
+-static int initialized;
++static bool initialized;
++static bool drvregistered;
+ enum ipmi_panic_event_op {
+       IPMI_SEND_PANIC_EVENT_NONE,
+@@ -612,7 +613,7 @@ static DEFINE_MUTEX(ipmidriver_mutex);
+ static LIST_HEAD(ipmi_interfaces);
+ static DEFINE_MUTEX(ipmi_interfaces_mutex);
+-DEFINE_STATIC_SRCU(ipmi_interfaces_srcu);
++struct srcu_struct ipmi_interfaces_srcu;
+ /*
+  * List of watchers that want to know when smi's are added and deleted.
+@@ -720,7 +721,15 @@ struct watcher_entry {
+ int ipmi_smi_watcher_register(struct ipmi_smi_watcher *watcher)
+ {
+       struct ipmi_smi *intf;
+-      int index;
++      int index, rv;
++
++      /*
++       * Make sure the driver is actually initialized, this handles
++       * problems with initialization order.
++       */
++      rv = ipmi_init_msghandler();
++      if (rv)
++              return rv;
+       mutex_lock(&smi_watchers_mutex);
+@@ -1076,7 +1085,7 @@ int ipmi_create_user(unsigned int
+ {
+       unsigned long flags;
+       struct ipmi_user *new_user;
+-      int           rv = 0, index;
++      int           rv, index;
+       struct ipmi_smi *intf;
+       /*
+@@ -1094,18 +1103,9 @@ int ipmi_create_user(unsigned int
+        * Make sure the driver is actually initialized, this handles
+        * problems with initialization order.
+        */
+-      if (!initialized) {
+-              rv = ipmi_init_msghandler();
+-              if (rv)
+-                      return rv;
+-
+-              /*
+-               * The init code doesn't return an error if it was turned
+-               * off, but it won't initialize.  Check that.
+-               */
+-              if (!initialized)
+-                      return -ENODEV;
+-      }
++      rv = ipmi_init_msghandler();
++      if (rv)
++              return rv;
+       new_user = kmalloc(sizeof(*new_user), GFP_KERNEL);
+       if (!new_user)
+@@ -3291,17 +3291,9 @@ int ipmi_register_smi(const struct ipmi_
+        * Make sure the driver is actually initialized, this handles
+        * problems with initialization order.
+        */
+-      if (!initialized) {
+-              rv = ipmi_init_msghandler();
+-              if (rv)
+-                      return rv;
+-              /*
+-               * The init code doesn't return an error if it was turned
+-               * off, but it won't initialize.  Check that.
+-               */
+-              if (!initialized)
+-                      return -ENODEV;
+-      }
++      rv = ipmi_init_msghandler();
++      if (rv)
++              return rv;
+       intf = kzalloc(sizeof(*intf), GFP_KERNEL);
+       if (!intf)
+@@ -5017,6 +5009,22 @@ static int panic_event(struct notifier_b
+       return NOTIFY_DONE;
+ }
++/* Must be called with ipmi_interfaces_mutex held. */
++static int ipmi_register_driver(void)
++{
++      int rv;
++
++      if (drvregistered)
++              return 0;
++
++      rv = driver_register(&ipmidriver.driver);
++      if (rv)
++              pr_err("Could not register IPMI driver\n");
++      else
++              drvregistered = true;
++      return rv;
++}
++
+ static struct notifier_block panic_block = {
+       .notifier_call  = panic_event,
+       .next           = NULL,
+@@ -5027,66 +5035,75 @@ static int ipmi_init_msghandler(void)
+ {
+       int rv;
++      mutex_lock(&ipmi_interfaces_mutex);
++      rv = ipmi_register_driver();
++      if (rv)
++              goto out;
+       if (initialized)
+-              return 0;
++              goto out;
+-      rv = driver_register(&ipmidriver.driver);
+-      if (rv) {
+-              pr_err("Could not register IPMI driver\n");
+-              return rv;
+-      }
+-
+-      pr_info("version " IPMI_DRIVER_VERSION "\n");
++      init_srcu_struct(&ipmi_interfaces_srcu);
+       timer_setup(&ipmi_timer, ipmi_timeout, 0);
+       mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
+       atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
+-      initialized = 1;
++      initialized = true;
+-      return 0;
++out:
++      mutex_unlock(&ipmi_interfaces_mutex);
++      return rv;
+ }
+ static int __init ipmi_init_msghandler_mod(void)
+ {
+-      ipmi_init_msghandler();
+-      return 0;
++      int rv;
++
++      pr_info("version " IPMI_DRIVER_VERSION "\n");
++
++      mutex_lock(&ipmi_interfaces_mutex);
++      rv = ipmi_register_driver();
++      mutex_unlock(&ipmi_interfaces_mutex);
++
++      return rv;
+ }
+ static void __exit cleanup_ipmi(void)
+ {
+       int count;
+-      if (!initialized)
+-              return;
+-
+-      atomic_notifier_chain_unregister(&panic_notifier_list, &panic_block);
++      if (initialized) {
++              atomic_notifier_chain_unregister(&panic_notifier_list,
++                                               &panic_block);
+-      /*
+-       * This can't be called if any interfaces exist, so no worry
+-       * about shutting down the interfaces.
+-       */
++              /*
++               * This can't be called if any interfaces exist, so no worry
++               * about shutting down the interfaces.
++               */
+-      /*
+-       * Tell the timer to stop, then wait for it to stop.  This
+-       * avoids problems with race conditions removing the timer
+-       * here.
+-       */
+-      atomic_inc(&stop_operation);
+-      del_timer_sync(&ipmi_timer);
++              /*
++               * Tell the timer to stop, then wait for it to stop.  This
++               * avoids problems with race conditions removing the timer
++               * here.
++               */
++              atomic_inc(&stop_operation);
++              del_timer_sync(&ipmi_timer);
+-      driver_unregister(&ipmidriver.driver);
++              initialized = false;
+-      initialized = 0;
++              /* Check for buffer leaks. */
++              count = atomic_read(&smi_msg_inuse_count);
++              if (count != 0)
++                      pr_warn("SMI message count %d at exit\n", count);
++              count = atomic_read(&recv_msg_inuse_count);
++              if (count != 0)
++                      pr_warn("recv message count %d at exit\n", count);
+-      /* Check for buffer leaks. */
+-      count = atomic_read(&smi_msg_inuse_count);
+-      if (count != 0)
+-              pr_warn("SMI message count %d at exit\n", count);
+-      count = atomic_read(&recv_msg_inuse_count);
+-      if (count != 0)
+-              pr_warn("recv message count %d at exit\n", count);
++              cleanup_srcu_struct(&ipmi_interfaces_srcu);
++      }
++      if (drvregistered)
++              driver_unregister(&ipmidriver.driver);
+ }
+ module_exit(cleanup_ipmi);
diff --git a/queue-4.20/ipmi-fix-use-after-free-of-user-release_barrier.rda.patch b/queue-4.20/ipmi-fix-use-after-free-of-user-release_barrier.rda.patch
new file mode 100644 (file)
index 0000000..d7ec732
--- /dev/null
@@ -0,0 +1,113 @@
+From 77f8269606bf95fcb232ee86f6da80886f1dfae8 Mon Sep 17 00:00:00 2001
+From: Yang Yingliang <yangyingliang@huawei.com>
+Date: Wed, 16 Jan 2019 13:33:22 +0800
+Subject: ipmi: fix use-after-free of user->release_barrier.rda
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+commit 77f8269606bf95fcb232ee86f6da80886f1dfae8 upstream.
+
+When we do the following test, we got oops in ipmi_msghandler driver
+while((1))
+do
+       service ipmievd restart & service ipmievd restart
+done
+
+---------------------------------------------------------------
+[  294.230186] Unable to handle kernel paging request at virtual address 0000803fea6ea008
+[  294.230188] Mem abort info:
+[  294.230190]   ESR = 0x96000004
+[  294.230191]   Exception class = DABT (current EL), IL = 32 bits
+[  294.230193]   SET = 0, FnV = 0
+[  294.230194]   EA = 0, S1PTW = 0
+[  294.230195] Data abort info:
+[  294.230196]   ISV = 0, ISS = 0x00000004
+[  294.230197]   CM = 0, WnR = 0
+[  294.230199] user pgtable: 4k pages, 48-bit VAs, pgdp = 00000000a1c1b75a
+[  294.230201] [0000803fea6ea008] pgd=0000000000000000
+[  294.230204] Internal error: Oops: 96000004 [#1] SMP
+[  294.235211] Modules linked in: nls_utf8 isofs rpcrdma ib_iser ib_srpt target_core_mod ib_srp scsi_transport_srp ib_ipoib rdma_ucm ib_umad rdma_cm ib_cm iw_cm dm_mirror dm_region_hash dm_log dm_mod aes_ce_blk crypto_simd cryptd aes_ce_cipher ghash_ce sha2_ce ses sha256_arm64 sha1_ce hibmc_drm hisi_sas_v2_hw enclosure sg hisi_sas_main sbsa_gwdt ip_tables mlx5_ib ib_uverbs marvell ib_core mlx5_core ixgbe ipmi_si mdio hns_dsaf ipmi_devintf ipmi_msghandler hns_enet_drv hns_mdio
+[  294.277745] CPU: 3 PID: 0 Comm: swapper/3 Kdump: loaded Not tainted 5.0.0-rc2+ #113
+[  294.285511] Hardware name: Huawei TaiShan 2280 /BC11SPCD, BIOS 1.37 11/21/2017
+[  294.292835] pstate: 80000005 (Nzcv daif -PAN -UAO)
+[  294.297695] pc : __srcu_read_lock+0x38/0x58
+[  294.301940] lr : acquire_ipmi_user+0x2c/0x70 [ipmi_msghandler]
+[  294.307853] sp : ffff00001001bc80
+[  294.311208] x29: ffff00001001bc80 x28: ffff0000117e5000
+[  294.316594] x27: 0000000000000000 x26: dead000000000100
+[  294.321980] x25: dead000000000200 x24: ffff803f6bd06800
+[  294.327366] x23: 0000000000000000 x22: 0000000000000000
+[  294.332752] x21: ffff00001001bd04 x20: ffff80df33d19018
+[  294.338137] x19: ffff80df33d19018 x18: 0000000000000000
+[  294.343523] x17: 0000000000000000 x16: 0000000000000000
+[  294.348908] x15: 0000000000000000 x14: 0000000000000002
+[  294.354293] x13: 0000000000000000 x12: 0000000000000000
+[  294.359679] x11: 0000000000000000 x10: 0000000000100000
+[  294.365065] x9 : 0000000000000000 x8 : 0000000000000004
+[  294.370451] x7 : 0000000000000000 x6 : ffff80df34558678
+[  294.375836] x5 : 000000000000000c x4 : 0000000000000000
+[  294.381221] x3 : 0000000000000001 x2 : 0000803fea6ea000
+[  294.386607] x1 : 0000803fea6ea008 x0 : 0000000000000001
+[  294.391994] Process swapper/3 (pid: 0, stack limit = 0x0000000083087293)
+[  294.398791] Call trace:
+[  294.401266]  __srcu_read_lock+0x38/0x58
+[  294.405154]  acquire_ipmi_user+0x2c/0x70 [ipmi_msghandler]
+[  294.410716]  deliver_response+0x80/0xf8 [ipmi_msghandler]
+[  294.416189]  deliver_local_response+0x28/0x68 [ipmi_msghandler]
+[  294.422193]  handle_one_recv_msg+0x158/0xcf8 [ipmi_msghandler]
+[  294.432050]  handle_new_recv_msgs+0xc0/0x210 [ipmi_msghandler]
+[  294.441984]  smi_recv_tasklet+0x8c/0x158 [ipmi_msghandler]
+[  294.451618]  tasklet_action_common.isra.5+0x88/0x138
+[  294.460661]  tasklet_action+0x2c/0x38
+[  294.468191]  __do_softirq+0x120/0x2f8
+[  294.475561]  irq_exit+0x134/0x140
+[  294.482445]  __handle_domain_irq+0x6c/0xc0
+[  294.489954]  gic_handle_irq+0xb8/0x178
+[  294.497037]  el1_irq+0xb0/0x140
+[  294.503381]  arch_cpu_idle+0x34/0x1a8
+[  294.510096]  do_idle+0x1d4/0x290
+[  294.516322]  cpu_startup_entry+0x28/0x30
+[  294.523230]  secondary_start_kernel+0x184/0x1d0
+[  294.530657] Code: d538d082 d2800023 8b010c81 8b020021 (c85f7c25)
+[  294.539746] ---[ end trace 8a7a880dee570b29 ]---
+[  294.547341] Kernel panic - not syncing: Fatal exception in interrupt
+[  294.556837] SMP: stopping secondary CPUs
+[  294.563996] Kernel Offset: disabled
+[  294.570515] CPU features: 0x002,21006008
+[  294.577638] Memory Limit: none
+[  294.587178] Starting crashdump kernel...
+[  294.594314] Bye!
+
+Because the user->release_barrier.rda is freed in ipmi_destroy_user(), but
+the refcount is not zero, when acquire_ipmi_user() uses user->release_barrier.rda
+in __srcu_read_lock(), it causes oops.
+Fix this by calling cleanup_srcu_struct() when the refcount is zero.
+
+Fixes: e86ee2d44b44 ("ipmi: Rework locking and shutdown for hot remove")
+Cc: stable@vger.kernel.org # 4.18
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Corey Minyard <cminyard@mvista.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/ipmi/ipmi_msghandler.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/char/ipmi/ipmi_msghandler.c
++++ b/drivers/char/ipmi/ipmi_msghandler.c
+@@ -1183,6 +1183,7 @@ EXPORT_SYMBOL(ipmi_get_smi_info);
+ static void free_user(struct kref *ref)
+ {
+       struct ipmi_user *user = container_of(ref, struct ipmi_user, refcount);
++      cleanup_srcu_struct(&user->release_barrier);
+       kfree(user);
+ }
+@@ -1259,7 +1260,6 @@ int ipmi_destroy_user(struct ipmi_user *
+ {
+       _ipmi_destroy_user(user);
+-      cleanup_srcu_struct(&user->release_barrier);
+       kref_put(&user->refcount, free_user);
+       return 0;
diff --git a/queue-4.20/ipmi-msghandler-fix-potential-spectre-v1-vulnerabilities.patch b/queue-4.20/ipmi-msghandler-fix-potential-spectre-v1-vulnerabilities.patch
new file mode 100644 (file)
index 0000000..782df95
--- /dev/null
@@ -0,0 +1,117 @@
+From a7102c7461794a5bb31af24b08e9e0f50038897a Mon Sep 17 00:00:00 2001
+From: "Gustavo A. R. Silva" <gustavo@embeddedor.com>
+Date: Wed, 9 Jan 2019 17:39:06 -0600
+Subject: ipmi: msghandler: Fix potential Spectre v1 vulnerabilities
+
+From: Gustavo A. R. Silva <gustavo@embeddedor.com>
+
+commit a7102c7461794a5bb31af24b08e9e0f50038897a upstream.
+
+channel and addr->channel are indirectly controlled by user-space,
+hence leading to a potential exploitation of the Spectre variant 1
+vulnerability.
+
+These issues were detected with the help of Smatch:
+
+drivers/char/ipmi/ipmi_msghandler.c:1381 ipmi_set_my_address() warn: potential spectre issue 'user->intf->addrinfo' [w] (local cap)
+drivers/char/ipmi/ipmi_msghandler.c:1401 ipmi_get_my_address() warn: potential spectre issue 'user->intf->addrinfo' [r] (local cap)
+drivers/char/ipmi/ipmi_msghandler.c:1421 ipmi_set_my_LUN() warn: potential spectre issue 'user->intf->addrinfo' [w] (local cap)
+drivers/char/ipmi/ipmi_msghandler.c:1441 ipmi_get_my_LUN() warn: potential spectre issue 'user->intf->addrinfo' [r] (local cap)
+drivers/char/ipmi/ipmi_msghandler.c:2260 check_addr() warn: potential spectre issue 'intf->addrinfo' [r] (local cap)
+
+Fix this by sanitizing channel and addr->channel before using them to
+index user->intf->addrinfo and intf->addrinfo, correspondingly.
+
+Notice that given that speculation windows are large, the policy is
+to kill the speculation on the first load and not worry if it can be
+completed with a dependent load/store [1].
+
+[1] https://lore.kernel.org/lkml/20180423164740.GY17484@dhcp22.suse.cz/
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
+Signed-off-by: Corey Minyard <cminyard@mvista.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/ipmi/ipmi_msghandler.c |   26 ++++++++++++++++++--------
+ 1 file changed, 18 insertions(+), 8 deletions(-)
+
+--- a/drivers/char/ipmi/ipmi_msghandler.c
++++ b/drivers/char/ipmi/ipmi_msghandler.c
+@@ -32,6 +32,7 @@
+ #include <linux/moduleparam.h>
+ #include <linux/workqueue.h>
+ #include <linux/uuid.h>
++#include <linux/nospec.h>
+ #define IPMI_DRIVER_VERSION "39.2"
+@@ -1298,10 +1299,12 @@ int ipmi_set_my_address(struct ipmi_user
+       if (!user)
+               return -ENODEV;
+-      if (channel >= IPMI_MAX_CHANNELS)
++      if (channel >= IPMI_MAX_CHANNELS) {
+               rv = -EINVAL;
+-      else
++      } else {
++              channel = array_index_nospec(channel, IPMI_MAX_CHANNELS);
+               user->intf->addrinfo[channel].address = address;
++      }
+       release_ipmi_user(user, index);
+       return rv;
+@@ -1318,10 +1321,12 @@ int ipmi_get_my_address(struct ipmi_user
+       if (!user)
+               return -ENODEV;
+-      if (channel >= IPMI_MAX_CHANNELS)
++      if (channel >= IPMI_MAX_CHANNELS) {
+               rv = -EINVAL;
+-      else
++      } else {
++              channel = array_index_nospec(channel, IPMI_MAX_CHANNELS);
+               *address = user->intf->addrinfo[channel].address;
++      }
+       release_ipmi_user(user, index);
+       return rv;
+@@ -1338,10 +1343,12 @@ int ipmi_set_my_LUN(struct ipmi_user *us
+       if (!user)
+               return -ENODEV;
+-      if (channel >= IPMI_MAX_CHANNELS)
++      if (channel >= IPMI_MAX_CHANNELS) {
+               rv = -EINVAL;
+-      else
++      } else {
++              channel = array_index_nospec(channel, IPMI_MAX_CHANNELS);
+               user->intf->addrinfo[channel].lun = LUN & 0x3;
++      }
+       release_ipmi_user(user, index);
+       return rv;
+@@ -1358,10 +1365,12 @@ int ipmi_get_my_LUN(struct ipmi_user *us
+       if (!user)
+               return -ENODEV;
+-      if (channel >= IPMI_MAX_CHANNELS)
++      if (channel >= IPMI_MAX_CHANNELS) {
+               rv = -EINVAL;
+-      else
++      } else {
++              channel = array_index_nospec(channel, IPMI_MAX_CHANNELS);
+               *address = user->intf->addrinfo[channel].lun;
++      }
+       release_ipmi_user(user, index);
+       return rv;
+@@ -2184,6 +2193,7 @@ static int check_addr(struct ipmi_smi  *
+ {
+       if (addr->channel >= IPMI_MAX_CHANNELS)
+               return -EINVAL;
++      addr->channel = array_index_nospec(addr->channel, IPMI_MAX_CHANNELS);
+       *lun = intf->addrinfo[addr->channel].lun;
+       *saddr = intf->addrinfo[addr->channel].address;
+       return 0;
diff --git a/queue-4.20/ipmi-prevent-use-after-free-in-deliver_response.patch b/queue-4.20/ipmi-prevent-use-after-free-in-deliver_response.patch
new file mode 100644 (file)
index 0000000..e07f4fb
--- /dev/null
@@ -0,0 +1,70 @@
+From 479d6b39b9e0d2de648ebf146f23a1e40962068f Mon Sep 17 00:00:00 2001
+From: Fred Klassen <fklassen@appneta.com>
+Date: Sat, 19 Jan 2019 14:28:18 -0800
+Subject: ipmi: Prevent use-after-free in deliver_response
+
+From: Fred Klassen <fklassen@appneta.com>
+
+commit 479d6b39b9e0d2de648ebf146f23a1e40962068f upstream.
+
+Some IPMI modules (e.g. ibmpex_msg_handler()) will have ipmi_usr_hdlr
+handlers that call ipmi_free_recv_msg() directly. This will essentially
+kfree(msg), leading to use-after-free.
+
+This does not happen in the ipmi_devintf module, which will queue the
+message and run ipmi_free_recv_msg() later.
+
+BUG: KASAN: use-after-free in deliver_response+0x12f/0x1b0
+Read of size 8 at addr ffff888a7bf20018 by task ksoftirqd/3/27
+CPU: 3 PID: 27 Comm: ksoftirqd/3 Tainted: G           O      4.19.11-amd64-ani99-debug #12.0.1.601133+pv
+Hardware name: AppNeta r1000/X11SPW-TF, BIOS 2.1a-AP 09/17/2018
+Call Trace:
+dump_stack+0x92/0xeb
+print_address_description+0x73/0x290
+kasan_report+0x258/0x380
+deliver_response+0x12f/0x1b0
+? ipmi_free_recv_msg+0x50/0x50
+deliver_local_response+0xe/0x50
+handle_one_recv_msg+0x37a/0x21d0
+handle_new_recv_msgs+0x1ce/0x440
+...
+
+Allocated by task 9885:
+kasan_kmalloc+0xa0/0xd0
+kmem_cache_alloc_trace+0x116/0x290
+ipmi_alloc_recv_msg+0x28/0x70
+i_ipmi_request+0xb4a/0x1640
+ipmi_request_settime+0x1b8/0x1e0
+...
+
+Freed by task 27:
+__kasan_slab_free+0x12e/0x180
+kfree+0xe9/0x280
+deliver_response+0x122/0x1b0
+deliver_local_response+0xe/0x50
+handle_one_recv_msg+0x37a/0x21d0
+handle_new_recv_msgs+0x1ce/0x440
+tasklet_action_common.isra.19+0xc4/0x250
+__do_softirq+0x11f/0x51f
+
+Fixes: e86ee2d44b44 ("ipmi: Rework locking and shutdown for hot remove")
+Cc: stable@vger.kernel.org # 4.18
+Signed-off-by: Fred Klassen <fklassen@appneta.com>
+Signed-off-by: Corey Minyard <cminyard@mvista.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/ipmi/ipmi_msghandler.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/char/ipmi/ipmi_msghandler.c
++++ b/drivers/char/ipmi/ipmi_msghandler.c
+@@ -894,7 +894,7 @@ static int deliver_response(struct ipmi_
+               if (user) {
+                       user->handler->ipmi_recv_hndl(msg, user->handler_data);
+-                      release_ipmi_user(msg->user, index);
++                      release_ipmi_user(user, index);
+               } else {
+                       /* User went away, give up. */
+                       ipmi_free_recv_msg(msg);
diff --git a/queue-4.20/ipmi-ssif-fix-handling-of-multi-part-return-messages.patch b/queue-4.20/ipmi-ssif-fix-handling-of-multi-part-return-messages.patch
new file mode 100644 (file)
index 0000000..7f53315
--- /dev/null
@@ -0,0 +1,95 @@
+From 7d6380cd40f7993f75c4bde5b36f6019237e8719 Mon Sep 17 00:00:00 2001
+From: Corey Minyard <cminyard@mvista.com>
+Date: Fri, 16 Nov 2018 09:59:21 -0600
+Subject: ipmi:ssif: Fix handling of multi-part return messages
+
+From: Corey Minyard <cminyard@mvista.com>
+
+commit 7d6380cd40f7993f75c4bde5b36f6019237e8719 upstream.
+
+The block number was not being compared right, it was off by one
+when checking the response.
+
+Some statistics wouldn't be incremented properly in some cases.
+
+Check to see if that middle-part messages always have 31 bytes of
+data.
+
+Signed-off-by: Corey Minyard <cminyard@mvista.com>
+Cc: stable@vger.kernel.org # 4.4
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/ipmi/ipmi_ssif.c |   25 +++++++++++++++++--------
+ 1 file changed, 17 insertions(+), 8 deletions(-)
+
+--- a/drivers/char/ipmi/ipmi_ssif.c
++++ b/drivers/char/ipmi/ipmi_ssif.c
+@@ -632,8 +632,9 @@ static void msg_done_handler(struct ssif
+               /* Remove the multi-part read marker. */
+               len -= 2;
++              data += 2;
+               for (i = 0; i < len; i++)
+-                      ssif_info->data[i] = data[i+2];
++                      ssif_info->data[i] = data[i];
+               ssif_info->multi_len = len;
+               ssif_info->multi_pos = 1;
+@@ -661,8 +662,19 @@ static void msg_done_handler(struct ssif
+               }
+               blocknum = data[0];
++              len--;
++              data++;
++
++              if (blocknum != 0xff && len != 31) {
++                  /* All blocks but the last must have 31 data bytes. */
++                      result = -EIO;
++                      if (ssif_info->ssif_debug & SSIF_DEBUG_MSG)
++                              pr_info("Received middle message <31\n");
+-              if (ssif_info->multi_len + len - 1 > IPMI_MAX_MSG_LENGTH) {
++                      goto continue_op;
++              }
++
++              if (ssif_info->multi_len + len > IPMI_MAX_MSG_LENGTH) {
+                       /* Received message too big, abort the operation. */
+                       result = -E2BIG;
+                       if (ssif_info->ssif_debug & SSIF_DEBUG_MSG)
+@@ -671,16 +683,14 @@ static void msg_done_handler(struct ssif
+                       goto continue_op;
+               }
+-              /* Remove the blocknum from the data. */
+-              len--;
+               for (i = 0; i < len; i++)
+-                      ssif_info->data[i + ssif_info->multi_len] = data[i + 1];
++                      ssif_info->data[i + ssif_info->multi_len] = data[i];
+               ssif_info->multi_len += len;
+               if (blocknum == 0xff) {
+                       /* End of read */
+                       len = ssif_info->multi_len;
+                       data = ssif_info->data;
+-              } else if (blocknum + 1 != ssif_info->multi_pos) {
++              } else if (blocknum != ssif_info->multi_pos) {
+                       /*
+                        * Out of sequence block, just abort.  Block
+                        * numbers start at zero for the second block,
+@@ -707,6 +717,7 @@ static void msg_done_handler(struct ssif
+               }
+       }
++ continue_op:
+       if (result < 0) {
+               ssif_inc_stat(ssif_info, receive_errors);
+       } else {
+@@ -714,8 +725,6 @@ static void msg_done_handler(struct ssif
+               ssif_inc_stat(ssif_info, received_message_parts);
+       }
+-
+- continue_op:
+       if (ssif_info->ssif_debug & SSIF_DEBUG_STATE)
+               pr_info("DONE 1: state = %d, result=%d\n",
+                       ssif_info->ssif_state, result);
index c14cf66872e382452b939306f53952e0f9ab4a03..f702d90e9503305817ca2fea72605709272328e6 100644 (file)
@@ -120,3 +120,8 @@ mm-proc-be-more-verbose-about-unstable-vma-flags-in-.patch
 mm-memblock.c-skip-kmemleak-for-kasan_init.patch
 drm-amd-display-fix-disabled-cursor-on-top-screen-edge.patch
 bluetooth-fix-unnecessary-error-message-for-hci-request-completion.patch
+ipmi-fix-use-after-free-of-user-release_barrier.rda.patch
+ipmi-don-t-initialize-anything-in-the-core-until-something-uses-it.patch
+ipmi-msghandler-fix-potential-spectre-v1-vulnerabilities.patch
+ipmi-prevent-use-after-free-in-deliver_response.patch
+ipmi-ssif-fix-handling-of-multi-part-return-messages.patch