From e261003ac48dbca8bc280f4a2bdccf509a2547b2 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 10 Mar 2020 13:18:19 +0100 Subject: [PATCH] 4.14-stable patches added patches: crypto-algif_skcipher-use-zero_or_null_ptr-in-skcipher_recvmsg_async.patch dm-integrity-fix-a-deadlock-due-to-offloading-to-an-incorrect-workqueue.patch xhci-handle-port-status-events-for-removed-usb3-hcd.patch --- ...r_null_ptr-in-skcipher_recvmsg_async.patch | 63 ++++++++++++ ...offloading-to-an-incorrect-workqueue.patch | 95 +++++++++++++++++++ queue-4.14/series | 3 + ...t-status-events-for-removed-usb3-hcd.patch | 42 ++++++++ 4 files changed, 203 insertions(+) create mode 100644 queue-4.14/crypto-algif_skcipher-use-zero_or_null_ptr-in-skcipher_recvmsg_async.patch create mode 100644 queue-4.14/dm-integrity-fix-a-deadlock-due-to-offloading-to-an-incorrect-workqueue.patch create mode 100644 queue-4.14/xhci-handle-port-status-events-for-removed-usb3-hcd.patch diff --git a/queue-4.14/crypto-algif_skcipher-use-zero_or_null_ptr-in-skcipher_recvmsg_async.patch b/queue-4.14/crypto-algif_skcipher-use-zero_or_null_ptr-in-skcipher_recvmsg_async.patch new file mode 100644 index 00000000000..2a03a80220a --- /dev/null +++ b/queue-4.14/crypto-algif_skcipher-use-zero_or_null_ptr-in-skcipher_recvmsg_async.patch @@ -0,0 +1,63 @@ +From yangerkun@huawei.com Tue Mar 10 13:13:31 2020 +From: yangerkun +Date: Thu, 5 Mar 2020 16:57:55 +0800 +Subject: crypto: algif_skcipher - use ZERO_OR_NULL_PTR in skcipher_recvmsg_async +To: , +Cc: , , +Message-ID: <20200305085755.22730-1-yangerkun@huawei.com> + +From: yangerkun + +Nowdays, we trigger a oops: +... +kasan: GPF could be caused by NULL-ptr deref or user memory accessgeneral protection fault: 0000 [#1] SMP KASAN +... +Call Trace: + [] skcipher_recvmsg_async+0x3f1/0x1400 x86/../crypto/algif_skcipher.c:543 + [] skcipher_recvmsg+0x93/0x7f0 x86/../crypto/algif_skcipher.c:723 + [] sock_recvmsg_nosec x86/../net/socket.c:702 [inline] + [] sock_recvmsg x86/../net/socket.c:710 [inline] + [] sock_recvmsg+0x94/0xc0 x86/../net/socket.c:705 + [] sock_read_iter+0x27b/0x3a0 x86/../net/socket.c:787 + [] aio_run_iocb+0x21b/0x7a0 x86/../fs/aio.c:1520 + [] io_submit_one x86/../fs/aio.c:1630 [inline] + [] do_io_submit+0x6b9/0x10b0 x86/../fs/aio.c:1688 + [] SYSC_io_submit x86/../fs/aio.c:1713 [inline] + [] SyS_io_submit+0x2d/0x40 x86/../fs/aio.c:1710 + [] tracesys_phase2+0x90/0x95 + +In skcipher_recvmsg_async, we use '!sreq->tsg' to determine does we +calloc fail. However, kcalloc may return ZERO_SIZE_PTR, and with this, +the latter sg_init_table will trigger the bug. Fix it be use ZERO_OF_NULL_PTR. + +This function was introduced with ' commit a596999b7ddf ("crypto: +algif - change algif_skcipher to be asynchronous")', and has been removed +with 'commit e870456d8e7c ("crypto: algif_skcipher - overhaul memory +management")'. + +Reported-by: Hulk Robot +Signed-off-by: yangerkun +Signed-off-by: Greg Kroah-Hartman +--- + crypto/algif_skcipher.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +v1->v2: +update the commit message + +diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c +index d12782dc9683..9bd4691cc5c5 100644 +--- a/crypto/algif_skcipher.c ++++ b/crypto/algif_skcipher.c +@@ -538,7 +538,7 @@ static int skcipher_recvmsg_async(struct socket *sock, struct msghdr *msg, + lock_sock(sk); + tx_nents = skcipher_all_sg_nents(ctx); + sreq->tsg = kcalloc(tx_nents, sizeof(*sg), GFP_KERNEL); +- if (unlikely(!sreq->tsg)) ++ if (unlikely(ZERO_OR_NULL_PTR(sreq->tsg))) + goto unlock; + sg_init_table(sreq->tsg, tx_nents); + memcpy(iv, ctx->iv, ivsize); +-- +2.17.2 + diff --git a/queue-4.14/dm-integrity-fix-a-deadlock-due-to-offloading-to-an-incorrect-workqueue.patch b/queue-4.14/dm-integrity-fix-a-deadlock-due-to-offloading-to-an-incorrect-workqueue.patch new file mode 100644 index 00000000000..658e00f8a4e --- /dev/null +++ b/queue-4.14/dm-integrity-fix-a-deadlock-due-to-offloading-to-an-incorrect-workqueue.patch @@ -0,0 +1,95 @@ +From 53770f0ec5fd417429775ba006bc4abe14002335 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Mon, 17 Feb 2020 07:43:03 -0500 +Subject: dm integrity: fix a deadlock due to offloading to an incorrect workqueue + +From: Mikulas Patocka + +commit 53770f0ec5fd417429775ba006bc4abe14002335 upstream. + +If we need to perform synchronous I/O in dm_integrity_map_continue(), +we must make sure that we are not in the map function - in order to +avoid the deadlock due to bio queuing in generic_make_request. To +avoid the deadlock, we offload the request to metadata_wq. + +However, metadata_wq also processes metadata updates for write requests. +If there are too many requests that get offloaded to metadata_wq at the +beginning of dm_integrity_map_continue, the workqueue metadata_wq +becomes clogged and the system is incapable of processing any metadata +updates. + +This causes a deadlock because all the requests that need to do metadata +updates wait for metadata_wq to proceed and metadata_wq waits inside +wait_and_add_new_range until some existing request releases its range +lock (which doesn't happen because the range lock is released after +metadata update). + +In order to fix the deadlock, we create a new workqueue offload_wq and +offload requests to it - so that processing of offload_wq is independent +from processing of metadata_wq. + +Fixes: 7eada909bfd7 ("dm: add integrity target") +Cc: stable@vger.kernel.org # v4.12+ +Reported-by: Heinz Mauelshagen +Tested-by: Heinz Mauelshagen +Signed-off-by: Heinz Mauelshagen +Signed-off-by: Mikulas Patocka +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-integrity.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +--- a/drivers/md/dm-integrity.c ++++ b/drivers/md/dm-integrity.c +@@ -187,6 +187,7 @@ struct dm_integrity_c { + struct rb_root in_progress; + wait_queue_head_t endio_wait; + struct workqueue_struct *wait_wq; ++ struct workqueue_struct *offload_wq; + + unsigned char commit_seq; + commit_id_t commit_ids[N_COMMIT_IDS]; +@@ -1157,7 +1158,7 @@ static void dec_in_flight(struct dm_inte + dio->range.logical_sector += dio->range.n_sectors; + bio_advance(bio, dio->range.n_sectors << SECTOR_SHIFT); + INIT_WORK(&dio->work, integrity_bio_wait); +- queue_work(ic->wait_wq, &dio->work); ++ queue_work(ic->offload_wq, &dio->work); + return; + } + do_endio_flush(ic, dio); +@@ -1577,7 +1578,7 @@ static void dm_integrity_map_continue(st + + if (need_sync_io && from_map) { + INIT_WORK(&dio->work, integrity_bio_wait); +- queue_work(ic->metadata_wq, &dio->work); ++ queue_work(ic->offload_wq, &dio->work); + return; + } + +@@ -3005,6 +3006,14 @@ static int dm_integrity_ctr(struct dm_ta + goto bad; + } + ++ ic->offload_wq = alloc_workqueue("dm-integrity-offload", WQ_MEM_RECLAIM, ++ METADATA_WORKQUEUE_MAX_ACTIVE); ++ if (!ic->offload_wq) { ++ ti->error = "Cannot allocate workqueue"; ++ r = -ENOMEM; ++ goto bad; ++ } ++ + ic->commit_wq = alloc_workqueue("dm-integrity-commit", WQ_MEM_RECLAIM, 1); + if (!ic->commit_wq) { + ti->error = "Cannot allocate workqueue"; +@@ -3189,6 +3198,8 @@ static void dm_integrity_dtr(struct dm_t + destroy_workqueue(ic->metadata_wq); + if (ic->wait_wq) + destroy_workqueue(ic->wait_wq); ++ if (ic->offload_wq) ++ destroy_workqueue(ic->offload_wq); + if (ic->commit_wq) + destroy_workqueue(ic->commit_wq); + if (ic->writer_wq) diff --git a/queue-4.14/series b/queue-4.14/series index e05c5b5aaee..abd69ac04ea 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -122,3 +122,6 @@ arm-dts-imx6dl-colibri-eval-v3-fix-sram-compatible-properties.patch hwmon-adt7462-fix-an-error-return-in-adt7462_reg_volt.patch dmaengine-coh901318-fix-a-double-lock-bug-in-dma_tc_handle.patch powerpc-fix-hardware-pmu-exception-bug-on-powervm-compatibility-mode-systems.patch +dm-integrity-fix-a-deadlock-due-to-offloading-to-an-incorrect-workqueue.patch +xhci-handle-port-status-events-for-removed-usb3-hcd.patch +crypto-algif_skcipher-use-zero_or_null_ptr-in-skcipher_recvmsg_async.patch diff --git a/queue-4.14/xhci-handle-port-status-events-for-removed-usb3-hcd.patch b/queue-4.14/xhci-handle-port-status-events-for-removed-usb3-hcd.patch new file mode 100644 index 00000000000..fdc9a8bf35d --- /dev/null +++ b/queue-4.14/xhci-handle-port-status-events-for-removed-usb3-hcd.patch @@ -0,0 +1,42 @@ +From 1245374e9b8340fc255fd51b2015173a83050d03 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Fri, 9 Nov 2018 17:21:18 +0200 +Subject: xhci: handle port status events for removed USB3 hcd + +From: Mathias Nyman + +commit 1245374e9b8340fc255fd51b2015173a83050d03 upstream. + +At xhci removal the USB3 hcd (shared_hcd) is removed before the primary +USB2 hcd. Interrupts for port status changes may still occur for USB3 +ports after the shared_hcd is freed, causing NULL pointer dereference. + +Check if xhci->shared_hcd is still valid before handing USB3 port events + +Cc: +Reported-by: Peter Chen +Tested-by: Jack Pham +Signed-off-by: Mathias Nyman +Cc: Macpaul Lin +[redone for 4.14.y based on Mathias's comments] +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-ring.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -1640,6 +1640,12 @@ static void handle_port_status(struct xh + if ((major_revision == 0x03) != (hcd->speed >= HCD_USB3)) + hcd = xhci->shared_hcd; + ++ if (!hcd) { ++ xhci_dbg(xhci, "No hcd found for port %u event\n", port_id); ++ bogus_port_status = true; ++ goto cleanup; ++ } ++ + if (major_revision == 0) { + xhci_warn(xhci, "Event for port %u not in " + "Extended Capabilities, ignoring.\n", -- 2.47.3