From: Greg Kroah-Hartman Date: Thu, 13 Jan 2022 18:54:16 +0000 (+0100) Subject: 5.10-stable patches X-Git-Tag: v5.16.1~16 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ef225700dedc56c8e3e25cb04ab35443059802af;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: can-gs_usb-fix-use-of-uninitialized-variable-detach-device-on-reception-of-invalid-usb-data.patch can-gs_usb-gs_can_start_xmit-zero-initialize-hf-flags-reserved.patch can-isotp-convert-struct-tpcon-idx-len-to-unsigned-int.patch random-fix-crash-on-multiple-early-calls-to-add_bootloader_randomness.patch random-fix-data-race-on-crng-init-time.patch random-fix-data-race-on-crng_node_pool.patch --- diff --git a/queue-5.10/can-gs_usb-fix-use-of-uninitialized-variable-detach-device-on-reception-of-invalid-usb-data.patch b/queue-5.10/can-gs_usb-fix-use-of-uninitialized-variable-detach-device-on-reception-of-invalid-usb-data.patch new file mode 100644 index 00000000000..19495bd1382 --- /dev/null +++ b/queue-5.10/can-gs_usb-fix-use-of-uninitialized-variable-detach-device-on-reception-of-invalid-usb-data.patch @@ -0,0 +1,51 @@ +From 4a8737ff068724f509d583fef404d349adba80d6 Mon Sep 17 00:00:00 2001 +From: Marc Kleine-Budde +Date: Fri, 10 Dec 2021 10:03:09 +0100 +Subject: can: gs_usb: fix use of uninitialized variable, detach device on reception of invalid USB data + +From: Marc Kleine-Budde + +commit 4a8737ff068724f509d583fef404d349adba80d6 upstream. + +The received data contains the channel the received data is associated +with. If the channel number is bigger than the actual number of +channels assume broken or malicious USB device and shut it down. + +This fixes the error found by clang: + +| drivers/net/can/usb/gs_usb.c:386:6: error: variable 'dev' is used +| uninitialized whenever 'if' condition is true +| if (hf->channel >= GS_MAX_INTF) +| ^~~~~~~~~~~~~~~~~~~~~~~~~~ +| drivers/net/can/usb/gs_usb.c:474:10: note: uninitialized use occurs here +| hf, dev->gs_hf_size, gs_usb_receive_bulk_callback, +| ^~~ + +Link: https://lore.kernel.org/all/20211210091158.408326-1-mkl@pengutronix.de +Fixes: d08e973a77d1 ("can: gs_usb: Added support for the GS_USB CAN devices") +Cc: stable@vger.kernel.org +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/can/usb/gs_usb.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/can/usb/gs_usb.c ++++ b/drivers/net/can/usb/gs_usb.c +@@ -320,7 +320,7 @@ static void gs_usb_receive_bulk_callback + + /* device reports out of range channel id */ + if (hf->channel >= GS_MAX_INTF) +- goto resubmit_urb; ++ goto device_detach; + + dev = usbcan->canch[hf->channel]; + +@@ -405,6 +405,7 @@ static void gs_usb_receive_bulk_callback + + /* USB failure take down all interfaces */ + if (rc == -ENODEV) { ++ device_detach: + for (rc = 0; rc < GS_MAX_INTF; rc++) { + if (usbcan->canch[rc]) + netif_device_detach(usbcan->canch[rc]->netdev); diff --git a/queue-5.10/can-gs_usb-gs_can_start_xmit-zero-initialize-hf-flags-reserved.patch b/queue-5.10/can-gs_usb-gs_can_start_xmit-zero-initialize-hf-flags-reserved.patch new file mode 100644 index 00000000000..c3b5b46856b --- /dev/null +++ b/queue-5.10/can-gs_usb-gs_can_start_xmit-zero-initialize-hf-flags-reserved.patch @@ -0,0 +1,39 @@ +From 89d58aebe14a365c25ba6645414afdbf4e41cea4 Mon Sep 17 00:00:00 2001 +From: Brian Silverman +Date: Wed, 5 Jan 2022 16:29:50 -0800 +Subject: can: gs_usb: gs_can_start_xmit(): zero-initialize hf->{flags,reserved} + +From: Brian Silverman + +commit 89d58aebe14a365c25ba6645414afdbf4e41cea4 upstream. + +No information is deliberately sent in hf->flags in host -> device +communications, but the open-source candleLight firmware echoes it +back, which can result in the GS_CAN_FLAG_OVERFLOW flag being set and +generating spurious ERRORFRAMEs. + +While there also initialize the reserved member with 0. + +Fixes: d08e973a77d1 ("can: gs_usb: Added support for the GS_USB CAN devices") +Link: https://lore.kernel.org/all/20220106002952.25883-1-brian.silverman@bluerivertech.com +Link: https://github.com/candle-usb/candleLight_fw/issues/87 +Cc: stable@vger.kernel.org +Signed-off-by: Brian Silverman +[mkl: initialize the reserved member, too] +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/can/usb/gs_usb.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/can/usb/gs_usb.c ++++ b/drivers/net/can/usb/gs_usb.c +@@ -507,6 +507,8 @@ static netdev_tx_t gs_can_start_xmit(str + + hf->echo_id = idx; + hf->channel = dev->channel; ++ hf->flags = 0; ++ hf->reserved = 0; + + cf = (struct can_frame *)skb->data; + diff --git a/queue-5.10/can-isotp-convert-struct-tpcon-idx-len-to-unsigned-int.patch b/queue-5.10/can-isotp-convert-struct-tpcon-idx-len-to-unsigned-int.patch new file mode 100644 index 00000000000..428331907e8 --- /dev/null +++ b/queue-5.10/can-isotp-convert-struct-tpcon-idx-len-to-unsigned-int.patch @@ -0,0 +1,45 @@ +From 5f33a09e769a9da0482f20a6770a342842443776 Mon Sep 17 00:00:00 2001 +From: Marc Kleine-Budde +Date: Wed, 5 Jan 2022 14:01:12 +0100 +Subject: can: isotp: convert struct tpcon::{idx,len} to unsigned int + +From: Marc Kleine-Budde + +commit 5f33a09e769a9da0482f20a6770a342842443776 upstream. + +In isotp_rcv_ff() 32 bit of data received over the network is assigned +to struct tpcon::len. Later in that function the length is checked for +the maximal supported length against MAX_MSG_LENGTH. + +As struct tpcon::len is an "int" this check does not work, if the +provided length overflows the "int". + +Later on struct tpcon::idx is compared against struct tpcon::len. + +To fix this problem this patch converts both struct tpcon::{idx,len} +to unsigned int. + +Fixes: e057dd3fc20f ("can: add ISO 15765-2:2016 transport protocol") +Link: https://lore.kernel.org/all/20220105132429.1170627-1-mkl@pengutronix.de +Cc: stable@vger.kernel.org +Acked-by: Oliver Hartkopp +Reported-by: syzbot+4c63f36709a642f801c5@syzkaller.appspotmail.com +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + net/can/isotp.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/can/isotp.c ++++ b/net/can/isotp.c +@@ -119,8 +119,8 @@ enum { + }; + + struct tpcon { +- int idx; +- int len; ++ unsigned int idx; ++ unsigned int len; + u32 state; + u8 bs; + u8 sn; diff --git a/queue-5.10/random-fix-crash-on-multiple-early-calls-to-add_bootloader_randomness.patch b/queue-5.10/random-fix-crash-on-multiple-early-calls-to-add_bootloader_randomness.patch new file mode 100644 index 00000000000..695cda25012 --- /dev/null +++ b/queue-5.10/random-fix-crash-on-multiple-early-calls-to-add_bootloader_randomness.patch @@ -0,0 +1,136 @@ +From f7e67b8e803185d0aabe7f29d25a35c8be724a78 Mon Sep 17 00:00:00 2001 +From: Dominik Brodowski +Date: Wed, 29 Dec 2021 22:10:03 +0100 +Subject: random: fix crash on multiple early calls to add_bootloader_randomness() + +From: Dominik Brodowski + +commit f7e67b8e803185d0aabe7f29d25a35c8be724a78 upstream. + +Currently, if CONFIG_RANDOM_TRUST_BOOTLOADER is enabled, multiple calls +to add_bootloader_randomness() are broken and can cause a NULL pointer +dereference, as noted by Ivan T. Ivanov. This is not only a hypothetical +problem, as qemu on arm64 may provide bootloader entropy via EFI and via +devicetree. + +On the first call to add_hwgenerator_randomness(), crng_fast_load() is +executed, and if the seed is long enough, crng_init will be set to 1. +On subsequent calls to add_bootloader_randomness() and then to +add_hwgenerator_randomness(), crng_fast_load() will be skipped. Instead, +wait_event_interruptible() and then credit_entropy_bits() will be called. +If the entropy count for that second seed is large enough, that proceeds +to crng_reseed(). + +However, both wait_event_interruptible() and crng_reseed() depends +(at least in numa_crng_init()) on workqueues. Therefore, test whether +system_wq is already initialized, which is a sufficient indicator that +workqueue_init_early() has progressed far enough. + +If we wind up hitting the !system_wq case, we later want to do what +would have been done there when wqs are up, so set a flag, and do that +work later from the rand_initialize() call. + +Reported-by: Ivan T. Ivanov +Fixes: 18b915ac6b0a ("efi/random: Treat EFI_RNG_PROTOCOL output as bootloader randomness") +Cc: stable@vger.kernel.org +Signed-off-by: Dominik Brodowski +[Jason: added crng_need_done state and related logic.] +Signed-off-by: Jason A. Donenfeld +Signed-off-by: Greg Kroah-Hartman +--- + drivers/char/random.c | 56 ++++++++++++++++++++++++++++++++------------------ + 1 file changed, 36 insertions(+), 20 deletions(-) + +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -461,6 +461,7 @@ static struct crng_state primary_crng = + * its value (from 0->1->2). + */ + static int crng_init = 0; ++static bool crng_need_final_init = false; + #define crng_ready() (likely(crng_init > 1)) + static int crng_init_cnt = 0; + static unsigned long crng_global_init_time = 0; +@@ -838,6 +839,36 @@ static void __init crng_initialize_prima + crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1; + } + ++static void crng_finalize_init(struct crng_state *crng) ++{ ++ if (crng != &primary_crng || crng_init >= 2) ++ return; ++ if (!system_wq) { ++ /* We can't call numa_crng_init until we have workqueues, ++ * so mark this for processing later. */ ++ crng_need_final_init = true; ++ return; ++ } ++ ++ invalidate_batched_entropy(); ++ numa_crng_init(); ++ crng_init = 2; ++ process_random_ready_list(); ++ wake_up_interruptible(&crng_init_wait); ++ kill_fasync(&fasync, SIGIO, POLL_IN); ++ pr_notice("crng init done\n"); ++ if (unseeded_warning.missed) { ++ pr_notice("%d get_random_xx warning(s) missed due to ratelimiting\n", ++ unseeded_warning.missed); ++ unseeded_warning.missed = 0; ++ } ++ if (urandom_warning.missed) { ++ pr_notice("%d urandom warning(s) missed due to ratelimiting\n", ++ urandom_warning.missed); ++ urandom_warning.missed = 0; ++ } ++} ++ + #ifdef CONFIG_NUMA + static void do_numa_crng_init(struct work_struct *work) + { +@@ -992,25 +1023,7 @@ static void crng_reseed(struct crng_stat + memzero_explicit(&buf, sizeof(buf)); + WRITE_ONCE(crng->init_time, jiffies); + spin_unlock_irqrestore(&crng->lock, flags); +- if (crng == &primary_crng && crng_init < 2) { +- invalidate_batched_entropy(); +- numa_crng_init(); +- crng_init = 2; +- process_random_ready_list(); +- wake_up_interruptible(&crng_init_wait); +- kill_fasync(&fasync, SIGIO, POLL_IN); +- pr_notice("crng init done\n"); +- if (unseeded_warning.missed) { +- pr_notice("%d get_random_xx warning(s) missed due to ratelimiting\n", +- unseeded_warning.missed); +- unseeded_warning.missed = 0; +- } +- if (urandom_warning.missed) { +- pr_notice("%d urandom warning(s) missed due to ratelimiting\n", +- urandom_warning.missed); +- urandom_warning.missed = 0; +- } +- } ++ crng_finalize_init(crng); + } + + static void _extract_crng(struct crng_state *crng, +@@ -1804,6 +1817,8 @@ static void __init init_std_data(struct + int __init rand_initialize(void) + { + init_std_data(&input_pool); ++ if (crng_need_final_init) ++ crng_finalize_init(&primary_crng); + crng_initialize_primary(&primary_crng); + crng_global_init_time = jiffies; + if (ratelimit_disable) { +@@ -2312,7 +2327,8 @@ void add_hwgenerator_randomness(const ch + * We'll be woken up again once below random_write_wakeup_thresh, + * or when the calling thread is about to terminate. + */ +- wait_event_interruptible(random_write_wait, kthread_should_stop() || ++ wait_event_interruptible(random_write_wait, ++ !system_wq || kthread_should_stop() || + ENTROPY_BITS(&input_pool) <= random_write_wakeup_bits); + mix_pool_bytes(poolp, buffer, count); + credit_entropy_bits(poolp, entropy); diff --git a/queue-5.10/random-fix-data-race-on-crng-init-time.patch b/queue-5.10/random-fix-data-race-on-crng-init-time.patch new file mode 100644 index 00000000000..eaefc83f5ee --- /dev/null +++ b/queue-5.10/random-fix-data-race-on-crng-init-time.patch @@ -0,0 +1,71 @@ +From 009ba8568be497c640cab7571f7bfd18345d7b24 Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Mon, 20 Dec 2021 16:41:57 -0600 +Subject: random: fix data race on crng init time + +From: Eric Biggers + +commit 009ba8568be497c640cab7571f7bfd18345d7b24 upstream. + +_extract_crng() does plain loads of crng->init_time and +crng_global_init_time, which causes undefined behavior if +crng_reseed() and RNDRESEEDCRNG modify these corrently. + +Use READ_ONCE() and WRITE_ONCE() to make the behavior defined. + +Don't fix the race on crng->init_time by protecting it with crng->lock, +since it's not a problem for duplicate reseedings to occur. I.e., the +lockless access with READ_ONCE() is fine. + +Fixes: d848e5f8e1eb ("random: add new ioctl RNDRESEEDCRNG") +Fixes: e192be9d9a30 ("random: replace non-blocking pool with a Chacha20-based CRNG") +Cc: stable@vger.kernel.org +Signed-off-by: Eric Biggers +Acked-by: Paul E. McKenney +Signed-off-by: Jason A. Donenfeld +Signed-off-by: Greg Kroah-Hartman +--- + drivers/char/random.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -990,7 +990,7 @@ static void crng_reseed(struct crng_stat + crng->state[i+4] ^= buf.key[i] ^ rv; + } + memzero_explicit(&buf, sizeof(buf)); +- crng->init_time = jiffies; ++ WRITE_ONCE(crng->init_time, jiffies); + spin_unlock_irqrestore(&crng->lock, flags); + if (crng == &primary_crng && crng_init < 2) { + invalidate_batched_entropy(); +@@ -1016,12 +1016,15 @@ static void crng_reseed(struct crng_stat + static void _extract_crng(struct crng_state *crng, + __u8 out[CHACHA_BLOCK_SIZE]) + { +- unsigned long v, flags; ++ unsigned long v, flags, init_time; + +- if (crng_ready() && +- (time_after(crng_global_init_time, crng->init_time) || +- time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL))) +- crng_reseed(crng, crng == &primary_crng ? &input_pool : NULL); ++ if (crng_ready()) { ++ init_time = READ_ONCE(crng->init_time); ++ if (time_after(READ_ONCE(crng_global_init_time), init_time) || ++ time_after(jiffies, init_time + CRNG_RESEED_INTERVAL)) ++ crng_reseed(crng, crng == &primary_crng ? ++ &input_pool : NULL); ++ } + spin_lock_irqsave(&crng->lock, flags); + if (arch_get_random_long(&v)) + crng->state[14] ^= v; +@@ -1975,7 +1978,7 @@ static long random_ioctl(struct file *f, + if (crng_init < 2) + return -ENODATA; + crng_reseed(&primary_crng, &input_pool); +- crng_global_init_time = jiffies - 1; ++ WRITE_ONCE(crng_global_init_time, jiffies - 1); + return 0; + default: + return -EINVAL; diff --git a/queue-5.10/random-fix-data-race-on-crng_node_pool.patch b/queue-5.10/random-fix-data-race-on-crng_node_pool.patch new file mode 100644 index 00000000000..2d321035fe7 --- /dev/null +++ b/queue-5.10/random-fix-data-race-on-crng_node_pool.patch @@ -0,0 +1,106 @@ +From 5d73d1e320c3fd94ea15ba5f79301da9a8bcc7de Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Mon, 20 Dec 2021 16:41:56 -0600 +Subject: random: fix data race on crng_node_pool + +From: Eric Biggers + +commit 5d73d1e320c3fd94ea15ba5f79301da9a8bcc7de upstream. + +extract_crng() and crng_backtrack_protect() load crng_node_pool with a +plain load, which causes undefined behavior if do_numa_crng_init() +modifies it concurrently. + +Fix this by using READ_ONCE(). Note: as per the previous discussion +https://lore.kernel.org/lkml/20211219025139.31085-1-ebiggers@kernel.org/T/#u, +READ_ONCE() is believed to be sufficient here, and it was requested that +it be used here instead of smp_load_acquire(). + +Also change do_numa_crng_init() to set crng_node_pool using +cmpxchg_release() instead of mb() + cmpxchg(), as the former is +sufficient here but is more lightweight. + +Fixes: 1e7f583af67b ("random: make /dev/urandom scalable for silly userspace programs") +Cc: stable@vger.kernel.org +Signed-off-by: Eric Biggers +Acked-by: Paul E. McKenney +Signed-off-by: Jason A. Donenfeld +Signed-off-by: Greg Kroah-Hartman +--- + drivers/char/random.c | 42 ++++++++++++++++++++++-------------------- + 1 file changed, 22 insertions(+), 20 deletions(-) + +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -853,8 +853,8 @@ static void do_numa_crng_init(struct wor + crng_initialize_secondary(crng); + pool[i] = crng; + } +- mb(); +- if (cmpxchg(&crng_node_pool, NULL, pool)) { ++ /* pairs with READ_ONCE() in select_crng() */ ++ if (cmpxchg_release(&crng_node_pool, NULL, pool) != NULL) { + for_each_node(i) + kfree(pool[i]); + kfree(pool); +@@ -867,8 +867,26 @@ static void numa_crng_init(void) + { + schedule_work(&numa_crng_init_work); + } ++ ++static struct crng_state *select_crng(void) ++{ ++ struct crng_state **pool; ++ int nid = numa_node_id(); ++ ++ /* pairs with cmpxchg_release() in do_numa_crng_init() */ ++ pool = READ_ONCE(crng_node_pool); ++ if (pool && pool[nid]) ++ return pool[nid]; ++ ++ return &primary_crng; ++} + #else + static void numa_crng_init(void) {} ++ ++static struct crng_state *select_crng(void) ++{ ++ return &primary_crng; ++} + #endif + + /* +@@ -1015,15 +1033,7 @@ static void _extract_crng(struct crng_st + + static void extract_crng(__u8 out[CHACHA_BLOCK_SIZE]) + { +- struct crng_state *crng = NULL; +- +-#ifdef CONFIG_NUMA +- if (crng_node_pool) +- crng = crng_node_pool[numa_node_id()]; +- if (crng == NULL) +-#endif +- crng = &primary_crng; +- _extract_crng(crng, out); ++ _extract_crng(select_crng(), out); + } + + /* +@@ -1052,15 +1062,7 @@ static void _crng_backtrack_protect(stru + + static void crng_backtrack_protect(__u8 tmp[CHACHA_BLOCK_SIZE], int used) + { +- struct crng_state *crng = NULL; +- +-#ifdef CONFIG_NUMA +- if (crng_node_pool) +- crng = crng_node_pool[numa_node_id()]; +- if (crng == NULL) +-#endif +- crng = &primary_crng; +- _crng_backtrack_protect(crng, tmp, used); ++ _crng_backtrack_protect(select_crng(), tmp, used); + } + + static ssize_t extract_crng_user(void __user *buf, size_t nbytes) diff --git a/queue-5.10/series b/queue-5.10/series index 339ee2770a5..7346a899df3 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -13,3 +13,9 @@ ath11k-fix-buffer-overflow-when-scanning-with-extraie.patch mmc-sdhci-pci-add-pci-id-for-intel-adl.patch veth-do-not-record-rx-queue-hint-in-veth_xmit.patch mfd-intel-lpss-fix-too-early-pm-enablement-in-the-acpi-probe.patch +can-gs_usb-fix-use-of-uninitialized-variable-detach-device-on-reception-of-invalid-usb-data.patch +can-isotp-convert-struct-tpcon-idx-len-to-unsigned-int.patch +can-gs_usb-gs_can_start_xmit-zero-initialize-hf-flags-reserved.patch +random-fix-data-race-on-crng_node_pool.patch +random-fix-data-race-on-crng-init-time.patch +random-fix-crash-on-multiple-early-calls-to-add_bootloader_randomness.patch