From: Greg Kroah-Hartman Date: Tue, 15 Sep 2020 07:37:14 +0000 (+0200) Subject: 4.9-stable patches X-Git-Tag: v4.19.146~35 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ecc107c4501e077a80d7c94f0713f32297dcc1da;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: btrfs-fix-wrong-address-when-faulting-in-pages-in-the-search-ioctl.patch regulator-push-allocation-in-set_consumer_device_supply-out-of-lock.patch scsi-target-iscsi-fix-data-digest-calculation.patch scsi-target-iscsi-fix-hang-in-iscsit_access_np-when-getting-tpg-np_login_sem.patch --- diff --git a/queue-4.9/btrfs-fix-wrong-address-when-faulting-in-pages-in-the-search-ioctl.patch b/queue-4.9/btrfs-fix-wrong-address-when-faulting-in-pages-in-the-search-ioctl.patch new file mode 100644 index 00000000000..846f0d8c511 --- /dev/null +++ b/queue-4.9/btrfs-fix-wrong-address-when-faulting-in-pages-in-the-search-ioctl.patch @@ -0,0 +1,51 @@ +From 1c78544eaa4660096aeb6a57ec82b42cdb3bfe5a Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Mon, 14 Sep 2020 09:01:04 +0100 +Subject: btrfs: fix wrong address when faulting in pages in the search ioctl + +From: Filipe Manana + +commit 1c78544eaa4660096aeb6a57ec82b42cdb3bfe5a upstream. + +When faulting in the pages for the user supplied buffer for the search +ioctl, we are passing only the base address of the buffer to the function +fault_in_pages_writeable(). This means that after the first iteration of +the while loop that searches for leaves, when we have a non-zero offset, +stored in 'sk_offset', we try to fault in a wrong page range. + +So fix this by adding the offset in 'sk_offset' to the base address of the +user supplied buffer when calling fault_in_pages_writeable(). + +Several users have reported that the applications compsize and bees have +started to operate incorrectly since commit a48b73eca4ceb9 ("btrfs: fix +potential deadlock in the search ioctl") was added to stable trees, and +these applications make heavy use of the search ioctls. This fixes their +issues. + +Link: https://lore.kernel.org/linux-btrfs/632b888d-a3c3-b085-cdf5-f9bb61017d92@lechevalier.se/ +Link: https://github.com/kilobyte/compsize/issues/34 +Fixes: a48b73eca4ceb9 ("btrfs: fix potential deadlock in the search ioctl") +CC: stable@vger.kernel.org # 4.4+ +Tested-by: A L +Reviewed-by: Josef Bacik +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/ioctl.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -2151,7 +2151,8 @@ static noinline int search_ioctl(struct + key.offset = sk->min_offset; + + while (1) { +- ret = fault_in_pages_writeable(ubuf, *buf_size - sk_offset); ++ ret = fault_in_pages_writeable(ubuf + sk_offset, ++ *buf_size - sk_offset); + if (ret) + break; + diff --git a/queue-4.9/regulator-push-allocation-in-set_consumer_device_supply-out-of-lock.patch b/queue-4.9/regulator-push-allocation-in-set_consumer_device_supply-out-of-lock.patch new file mode 100644 index 00000000000..3a0fe82fb8c --- /dev/null +++ b/queue-4.9/regulator-push-allocation-in-set_consumer_device_supply-out-of-lock.patch @@ -0,0 +1,116 @@ +From 5c06540165d443c6455123eb48e7f1a9b618ab34 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= +Date: Wed, 12 Aug 2020 03:31:36 +0200 +Subject: regulator: push allocation in set_consumer_device_supply() out of lock +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michał Mirosław + +commit 5c06540165d443c6455123eb48e7f1a9b618ab34 upstream. + +Pull regulator_list_mutex into set_consumer_device_supply() and keep +allocations outside of it. Fourth of the fs_reclaim deadlock case. + +Fixes: 45389c47526d ("regulator: core: Add early supply resolution for regulators") +Signed-off-by: Michał Mirosław +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/f0380bdb3d60aeefa9693c4e234d2dcda7e56747.1597195321.git.mirq-linux@rere.qmqm.pl +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/regulator/core.c | 46 ++++++++++++++++++++++++++-------------------- + 1 file changed, 26 insertions(+), 20 deletions(-) + +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -1191,7 +1191,7 @@ static int set_consumer_device_supply(st + const char *consumer_dev_name, + const char *supply) + { +- struct regulator_map *node; ++ struct regulator_map *node, *new_node; + int has_dev; + + if (supply == NULL) +@@ -1202,6 +1202,22 @@ static int set_consumer_device_supply(st + else + has_dev = 0; + ++ new_node = kzalloc(sizeof(struct regulator_map), GFP_KERNEL); ++ if (new_node == NULL) ++ return -ENOMEM; ++ ++ new_node->regulator = rdev; ++ new_node->supply = supply; ++ ++ if (has_dev) { ++ new_node->dev_name = kstrdup(consumer_dev_name, GFP_KERNEL); ++ if (new_node->dev_name == NULL) { ++ kfree(new_node); ++ return -ENOMEM; ++ } ++ } ++ ++ mutex_lock(®ulator_list_mutex); + list_for_each_entry(node, ®ulator_map_list, list) { + if (node->dev_name && consumer_dev_name) { + if (strcmp(node->dev_name, consumer_dev_name) != 0) +@@ -1219,26 +1235,19 @@ static int set_consumer_device_supply(st + node->regulator->desc->name, + supply, + dev_name(&rdev->dev), rdev_get_name(rdev)); +- return -EBUSY; ++ goto fail; + } + +- node = kzalloc(sizeof(struct regulator_map), GFP_KERNEL); +- if (node == NULL) +- return -ENOMEM; +- +- node->regulator = rdev; +- node->supply = supply; +- +- if (has_dev) { +- node->dev_name = kstrdup(consumer_dev_name, GFP_KERNEL); +- if (node->dev_name == NULL) { +- kfree(node); +- return -ENOMEM; +- } +- } ++ list_add(&new_node->list, ®ulator_map_list); ++ mutex_unlock(®ulator_list_mutex); + +- list_add(&node->list, ®ulator_map_list); + return 0; ++ ++fail: ++ mutex_unlock(®ulator_list_mutex); ++ kfree(new_node->dev_name); ++ kfree(new_node); ++ return -EBUSY; + } + + static void unset_regulator_supplies(struct regulator_dev *rdev) +@@ -4034,19 +4043,16 @@ regulator_register(const struct regulato + + /* add consumers devices */ + if (init_data) { +- mutex_lock(®ulator_list_mutex); + for (i = 0; i < init_data->num_consumer_supplies; i++) { + ret = set_consumer_device_supply(rdev, + init_data->consumer_supplies[i].dev_name, + init_data->consumer_supplies[i].supply); + if (ret < 0) { +- mutex_unlock(®ulator_list_mutex); + dev_err(dev, "Failed to set supply %s\n", + init_data->consumer_supplies[i].supply); + goto unset_supplies; + } + } +- mutex_unlock(®ulator_list_mutex); + } + + if (!rdev->desc->ops->get_voltage && diff --git a/queue-4.9/scsi-target-iscsi-fix-data-digest-calculation.patch b/queue-4.9/scsi-target-iscsi-fix-data-digest-calculation.patch new file mode 100644 index 00000000000..35adcefa7f5 --- /dev/null +++ b/queue-4.9/scsi-target-iscsi-fix-data-digest-calculation.patch @@ -0,0 +1,57 @@ +From 5528d03183fe5243416c706f64b1faa518b05130 Mon Sep 17 00:00:00 2001 +From: Varun Prakash +Date: Tue, 25 Aug 2020 18:05:10 +0530 +Subject: scsi: target: iscsi: Fix data digest calculation + +From: Varun Prakash + +commit 5528d03183fe5243416c706f64b1faa518b05130 upstream. + +Current code does not consider 'page_off' in data digest calculation. To +fix this, add a local variable 'first_sg' and set first_sg.offset to +sg->offset + page_off. + +Link: https://lore.kernel.org/r/1598358910-3052-1-git-send-email-varun@chelsio.com +Fixes: e48354ce078c ("iscsi-target: Add iSCSI fabric support for target v4.1") +Cc: +Reviewed-by: Mike Christie +Signed-off-by: Varun Prakash +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/iscsi/iscsi_target.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +--- a/drivers/target/iscsi/iscsi_target.c ++++ b/drivers/target/iscsi/iscsi_target.c +@@ -1396,14 +1396,27 @@ static u32 iscsit_do_crypto_hash_sg( + sg = cmd->first_data_sg; + page_off = cmd->first_data_sg_off; + ++ if (data_length && page_off) { ++ struct scatterlist first_sg; ++ u32 len = min_t(u32, data_length, sg->length - page_off); ++ ++ sg_init_table(&first_sg, 1); ++ sg_set_page(&first_sg, sg_page(sg), len, sg->offset + page_off); ++ ++ ahash_request_set_crypt(hash, &first_sg, NULL, len); ++ crypto_ahash_update(hash); ++ ++ data_length -= len; ++ sg = sg_next(sg); ++ } ++ + while (data_length) { +- u32 cur_len = min_t(u32, data_length, (sg->length - page_off)); ++ u32 cur_len = min_t(u32, data_length, sg->length); + + ahash_request_set_crypt(hash, sg, NULL, cur_len); + crypto_ahash_update(hash); + + data_length -= cur_len; +- page_off = 0; + /* iscsit_map_iovec has already checked for invalid sg pointers */ + sg = sg_next(sg); + } diff --git a/queue-4.9/scsi-target-iscsi-fix-hang-in-iscsit_access_np-when-getting-tpg-np_login_sem.patch b/queue-4.9/scsi-target-iscsi-fix-hang-in-iscsit_access_np-when-getting-tpg-np_login_sem.patch new file mode 100644 index 00000000000..5de896e6c89 --- /dev/null +++ b/queue-4.9/scsi-target-iscsi-fix-hang-in-iscsit_access_np-when-getting-tpg-np_login_sem.patch @@ -0,0 +1,117 @@ +From ed43ffea78dcc97db3f561da834f1a49c8961e33 Mon Sep 17 00:00:00 2001 +From: Hou Pu +Date: Wed, 29 Jul 2020 09:03:43 -0400 +Subject: scsi: target: iscsi: Fix hang in iscsit_access_np() when getting tpg->np_login_sem + +From: Hou Pu + +commit ed43ffea78dcc97db3f561da834f1a49c8961e33 upstream. + +The iSCSI target login thread might get stuck with the following stack: + +cat /proc/`pidof iscsi_np`/stack +[<0>] down_interruptible+0x42/0x50 +[<0>] iscsit_access_np+0xe3/0x167 +[<0>] iscsi_target_locate_portal+0x695/0x8ac +[<0>] __iscsi_target_login_thread+0x855/0xb82 +[<0>] iscsi_target_login_thread+0x2f/0x5a +[<0>] kthread+0xfa/0x130 +[<0>] ret_from_fork+0x1f/0x30 + +This can be reproduced via the following steps: + +1. Initiator A tries to log in to iqn1-tpg1 on port 3260. After finishing + PDU exchange in the login thread and before the negotiation is finished + the the network link goes down. At this point A has not finished login + and tpg->np_login_sem is held. + +2. Initiator B tries to log in to iqn2-tpg1 on port 3260. After finishing + PDU exchange in the login thread the target expects to process remaining + login PDUs in workqueue context. + +3. Initiator A' tries to log in to iqn1-tpg1 on port 3260 from a new + socket. A' will wait for tpg->np_login_sem with np->np_login_timer + loaded to wait for at most 15 seconds. The lock is held by A so A' + eventually times out. + +4. Before A' got timeout initiator B gets negotiation failed and calls + iscsi_target_login_drop()->iscsi_target_login_sess_out(). The + np->np_login_timer is canceled and initiator A' will hang forever. + Because A' is now in the login thread, no new login requests can be + serviced. + +Fix this by moving iscsi_stop_login_thread_timer() out of +iscsi_target_login_sess_out(). Also remove iscsi_np parameter from +iscsi_target_login_sess_out(). + +Link: https://lore.kernel.org/r/20200729130343.24976-1-houpu@bytedance.com +Cc: stable@vger.kernel.org +Reviewed-by: Mike Christie +Signed-off-by: Hou Pu +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/iscsi/iscsi_target_login.c | 6 +++--- + drivers/target/iscsi/iscsi_target_login.h | 3 +-- + drivers/target/iscsi/iscsi_target_nego.c | 3 +-- + 3 files changed, 5 insertions(+), 7 deletions(-) + +--- a/drivers/target/iscsi/iscsi_target_login.c ++++ b/drivers/target/iscsi/iscsi_target_login.c +@@ -1150,7 +1150,7 @@ iscsit_conn_set_transport(struct iscsi_c + } + + void iscsi_target_login_sess_out(struct iscsi_conn *conn, +- struct iscsi_np *np, bool zero_tsih, bool new_sess) ++ bool zero_tsih, bool new_sess) + { + if (!new_sess) + goto old_sess_out; +@@ -1172,7 +1172,6 @@ void iscsi_target_login_sess_out(struct + conn->sess = NULL; + + old_sess_out: +- iscsi_stop_login_thread_timer(np); + /* + * If login negotiation fails check if the Time2Retain timer + * needs to be restarted. +@@ -1432,8 +1431,9 @@ static int __iscsi_target_login_thread(s + new_sess_out: + new_sess = true; + old_sess_out: ++ iscsi_stop_login_thread_timer(np); + tpg_np = conn->tpg_np; +- iscsi_target_login_sess_out(conn, np, zero_tsih, new_sess); ++ iscsi_target_login_sess_out(conn, zero_tsih, new_sess); + new_sess = false; + + if (tpg) { +--- a/drivers/target/iscsi/iscsi_target_login.h ++++ b/drivers/target/iscsi/iscsi_target_login.h +@@ -14,8 +14,7 @@ extern int iscsit_put_login_tx(struct is + extern void iscsit_free_conn(struct iscsi_np *, struct iscsi_conn *); + extern int iscsit_start_kthreads(struct iscsi_conn *); + extern void iscsi_post_login_handler(struct iscsi_np *, struct iscsi_conn *, u8); +-extern void iscsi_target_login_sess_out(struct iscsi_conn *, struct iscsi_np *, +- bool, bool); ++extern void iscsi_target_login_sess_out(struct iscsi_conn *, bool, bool); + extern int iscsi_target_login_thread(void *); + + #endif /*** ISCSI_TARGET_LOGIN_H ***/ +--- a/drivers/target/iscsi/iscsi_target_nego.c ++++ b/drivers/target/iscsi/iscsi_target_nego.c +@@ -548,12 +548,11 @@ static bool iscsi_target_sk_check_and_cl + + static void iscsi_target_login_drop(struct iscsi_conn *conn, struct iscsi_login *login) + { +- struct iscsi_np *np = login->np; + bool zero_tsih = login->zero_tsih; + + iscsi_remove_failed_auth_entry(conn); + iscsi_target_nego_release(conn); +- iscsi_target_login_sess_out(conn, np, zero_tsih, true); ++ iscsi_target_login_sess_out(conn, zero_tsih, true); + } + + static void iscsi_target_login_timeout(unsigned long data) diff --git a/queue-4.9/series b/queue-4.9/series index 7547020d6cf..303b372c792 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -27,3 +27,7 @@ iio-accel-mma7455-fix-timestamp-alignment-and-prevent-data-leak.patch iio-accel-mma8452-fix-timestamp-alignment-and-prevent-data-leak.patch usb-core-add-helpers-to-retrieve-endpoints.patch staging-wlan-ng-fix-out-of-bounds-read-in-prism2sta_probe_usb.patch +btrfs-fix-wrong-address-when-faulting-in-pages-in-the-search-ioctl.patch +regulator-push-allocation-in-set_consumer_device_supply-out-of-lock.patch +scsi-target-iscsi-fix-data-digest-calculation.patch +scsi-target-iscsi-fix-hang-in-iscsit_access_np-when-getting-tpg-np_login_sem.patch