From: Greg Kroah-Hartman Date: Thu, 24 Jan 2019 19:05:25 +0000 (+0100) Subject: 4.20-stable patches X-Git-Tag: v4.20.5~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=05a16fecf252a4b71055c1dfb23bb9495b3f43dd;p=thirdparty%2Fkernel%2Fstable-queue.git 4.20-stable patches 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 --- 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 index 00000000000..ea13ca75aed --- /dev/null +++ b/queue-4.20/ipmi-don-t-initialize-anything-in-the-core-until-something-uses-it.patch @@ -0,0 +1,252 @@ +From 913a89f009d98c85a902d718cd54bb32ab11d167 Mon Sep 17 00:00:00 2001 +From: Corey Minyard +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 + +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 +Reported-by: Tejun Heo +Cc: Paul E. McKenney +Reviewed-by: Paul E. McKenney +Cc: stable@vger.kernel.org # 4.18 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..d7ec7324d16 --- /dev/null +++ b/queue-4.20/ipmi-fix-use-after-free-of-user-release_barrier.rda.patch @@ -0,0 +1,113 @@ +From 77f8269606bf95fcb232ee86f6da80886f1dfae8 Mon Sep 17 00:00:00 2001 +From: Yang Yingliang +Date: Wed, 16 Jan 2019 13:33:22 +0800 +Subject: ipmi: fix use-after-free of user->release_barrier.rda + +From: Yang Yingliang + +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 +Signed-off-by: Corey Minyard +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..782df955762 --- /dev/null +++ b/queue-4.20/ipmi-msghandler-fix-potential-spectre-v1-vulnerabilities.patch @@ -0,0 +1,117 @@ +From a7102c7461794a5bb31af24b08e9e0f50038897a Mon Sep 17 00:00:00 2001 +From: "Gustavo A. R. Silva" +Date: Wed, 9 Jan 2019 17:39:06 -0600 +Subject: ipmi: msghandler: Fix potential Spectre v1 vulnerabilities + +From: Gustavo A. R. Silva + +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 +Signed-off-by: Corey Minyard +Signed-off-by: Greg Kroah-Hartman + +--- + 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 + #include + #include ++#include + + #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 index 00000000000..e07f4fb15c2 --- /dev/null +++ b/queue-4.20/ipmi-prevent-use-after-free-in-deliver_response.patch @@ -0,0 +1,70 @@ +From 479d6b39b9e0d2de648ebf146f23a1e40962068f Mon Sep 17 00:00:00 2001 +From: Fred Klassen +Date: Sat, 19 Jan 2019 14:28:18 -0800 +Subject: ipmi: Prevent use-after-free in deliver_response + +From: Fred Klassen + +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 +Signed-off-by: Corey Minyard +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..7f5331575cb --- /dev/null +++ b/queue-4.20/ipmi-ssif-fix-handling-of-multi-part-return-messages.patch @@ -0,0 +1,95 @@ +From 7d6380cd40f7993f75c4bde5b36f6019237e8719 Mon Sep 17 00:00:00 2001 +From: Corey Minyard +Date: Fri, 16 Nov 2018 09:59:21 -0600 +Subject: ipmi:ssif: Fix handling of multi-part return messages + +From: Corey Minyard + +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 +Cc: stable@vger.kernel.org # 4.4 +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-4.20/series b/queue-4.20/series index c14cf66872e..f702d90e950 100644 --- a/queue-4.20/series +++ b/queue-4.20/series @@ -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