From: Dinghao Liu dinghao.liu@zju.edu.cn
[ Upstream commit f31559af97a0eabd467e4719253675b7dccb8a46 ]
When fw_core_add_address_handler() fails, we need to destroy the port by tty_port_destroy(). Also we need to unregister the address handler by fw_core_remove_address_handler() on failure.
Signed-off-by: Dinghao Liu dinghao.liu@zju.edu.cn Link: https://lore.kernel.org/r/20201221122437.10274-1-dinghao.liu@zju.edu.cn Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/fwserial/fwserial.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c index 41a49c8194e50..b19c46bd2557c 100644 --- a/drivers/staging/fwserial/fwserial.c +++ b/drivers/staging/fwserial/fwserial.c @@ -2249,6 +2249,7 @@ static int fwserial_create(struct fw_unit *unit) err = fw_core_add_address_handler(&port->rx_handler, &fw_high_memory_region); if (err) { + tty_port_destroy(&port->port); kfree(port); goto free_ports; } @@ -2331,6 +2332,7 @@ static int fwserial_create(struct fw_unit *unit)
free_ports: for (--i; i >= 0; --i) { + fw_core_remove_address_handler(&serial->ports[i]->rx_handler); tty_port_destroy(&serial->ports[i]->port); kfree(serial->ports[i]); }
From: Heiner Kallweit hkallweit1@gmail.com
[ Upstream commit 4b2d8ca9208be636b30e924b1cbcb267b0740c93 ]
On this system the M.2 PCIe WiFi card isn't detected after reboot, only after cold boot. reboot=pci fixes this behavior. In [0] the same issue is described, although on another system and with another Intel WiFi card. In case it's relevant, both systems have Celeron CPUs.
Add a PCI reboot quirk on affected systems until a more generic fix is available.
[0] https://bugzilla.kernel.org/show_bug.cgi?id=202399
[ bp: Massage commit message. ]
Signed-off-by: Heiner Kallweit hkallweit1@gmail.com Signed-off-by: Borislav Petkov bp@suse.de Link: https://lkml.kernel.org/r/1524eafd-f89c-cfa4-ed70-0bde9e45eec9@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/reboot.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index b7663a1f89ee5..77e4a41eed989 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -477,6 +477,15 @@ static const struct dmi_system_id reboot_dmi_table[] __initconst = { }, },
+ { /* PCIe Wifi card isn't detected after reboot otherwise */ + .callback = set_pci_reboot, + .ident = "Zotac ZBOX CI327 nano", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "NA"), + DMI_MATCH(DMI_PRODUCT_NAME, "ZBOX-CI327NANO-GS-01"), + }, + }, + /* Sony */ { /* Handle problems with rebooting on Sony VGN-Z540N */ .callback = set_bios_reboot,
From: Jiri Slaby jslaby@suse.cz
[ Upstream commit 9777f8e60e718f7b022a94f2524f967d8def1931 ]
The constant 20 makes the font sum computation signed which can lead to sign extensions and signed wraps. It's not much of a problem as we build with -fno-strict-overflow. But if we ever decide not to, be ready, so switch the constant to unsigned.
Signed-off-by: Jiri Slaby jslaby@suse.cz Link: https://lore.kernel.org/r/20210105120239.28031-7-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/vt/consolemap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/tty/vt/consolemap.c b/drivers/tty/vt/consolemap.c index a5f88cf0f61d5..a2c1a02f04078 100644 --- a/drivers/tty/vt/consolemap.c +++ b/drivers/tty/vt/consolemap.c @@ -493,7 +493,7 @@ con_insert_unipair(struct uni_pagedir *p, u_short unicode, u_short fontpos)
p2[unicode & 0x3f] = fontpos; - p->sum += (fontpos << 20) + unicode; + p->sum += (fontpos << 20U) + unicode;
return 0; }
From: Tony Lindgren tony@atomide.com
[ Upstream commit cb88d01b67383a095e3f7caeb4cdade5a6cf0417 ]
We can currently get a "command execute failure 19" error on beacon loss if the signal is weak:
wlcore: Beacon loss detected. roles:0xff wlcore: Connection loss work (role_id: 0). ... wlcore: ERROR command execute failure 19 ... WARNING: CPU: 0 PID: 1552 at drivers/net/wireless/ti/wlcore/main.c:803 ... (wl12xx_queue_recovery_work.part.0 [wlcore]) (wl12xx_cmd_role_start_sta [wlcore]) (wl1271_op_bss_info_changed [wlcore]) (ieee80211_prep_connection [mac80211])
Error 19 is defined as CMD_STATUS_WRONG_NESTING from the wlcore firmware, and seems to mean that the firmware no longer wants to see the quirk handling for WLCORE_QUIRK_START_STA_FAILS done.
This quirk got added with commit 18eab430700d ("wlcore: workaround start_sta problem in wl12xx fw"), and it seems that this already got fixed in the firmware long time ago back in 2012 as wl18xx never had this quirk in place to start with.
As we no longer even support firmware that early, to me it seems that it's safe to just drop WLCORE_QUIRK_START_STA_FAILS to fix the error. Looks like earlier firmware got disabled back in 2013 with commit 0e284c074ef9 ("wl12xx: increase minimum singlerole firmware version required").
If it turns out we still need WLCORE_QUIRK_START_STA_FAILS with any firmware that the driver works with, we can simply revert this patch and add extra checks for firmware version used.
With this fix wlcore reconnects properly after a beacon loss.
Cc: Raz Bouganim r-bouganim@ti.com Signed-off-by: Tony Lindgren tony@atomide.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210115065613.7731-1-tony@atomide.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ti/wl12xx/main.c | 3 --- drivers/net/wireless/ti/wlcore/main.c | 15 +-------------- drivers/net/wireless/ti/wlcore/wlcore.h | 3 --- 3 files changed, 1 insertion(+), 20 deletions(-)
diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 22009e14a8fc1..9bd635ec7827b 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -648,7 +648,6 @@ static int wl12xx_identify_chip(struct wl1271 *wl) wl->quirks |= WLCORE_QUIRK_LEGACY_NVS | WLCORE_QUIRK_DUAL_PROBE_TMPL | WLCORE_QUIRK_TKIP_HEADER_SPACE | - WLCORE_QUIRK_START_STA_FAILS | WLCORE_QUIRK_AP_ZERO_SESSION_ID; wl->sr_fw_name = WL127X_FW_NAME_SINGLE; wl->mr_fw_name = WL127X_FW_NAME_MULTI; @@ -672,7 +671,6 @@ static int wl12xx_identify_chip(struct wl1271 *wl) wl->quirks |= WLCORE_QUIRK_LEGACY_NVS | WLCORE_QUIRK_DUAL_PROBE_TMPL | WLCORE_QUIRK_TKIP_HEADER_SPACE | - WLCORE_QUIRK_START_STA_FAILS | WLCORE_QUIRK_AP_ZERO_SESSION_ID; wl->plt_fw_name = WL127X_PLT_FW_NAME; wl->sr_fw_name = WL127X_FW_NAME_SINGLE; @@ -701,7 +699,6 @@ static int wl12xx_identify_chip(struct wl1271 *wl) wl->quirks |= WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN | WLCORE_QUIRK_DUAL_PROBE_TMPL | WLCORE_QUIRK_TKIP_HEADER_SPACE | - WLCORE_QUIRK_START_STA_FAILS | WLCORE_QUIRK_AP_ZERO_SESSION_ID;
wlcore_set_min_fw_ver(wl, WL128X_CHIP_VER, diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index eb3a7971c1d34..9f568034deb35 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -2832,21 +2832,8 @@ static int wlcore_join(struct wl1271 *wl, struct wl12xx_vif *wlvif)
if (is_ibss) ret = wl12xx_cmd_role_start_ibss(wl, wlvif); - else { - if (wl->quirks & WLCORE_QUIRK_START_STA_FAILS) { - /* - * TODO: this is an ugly workaround for wl12xx fw - * bug - we are not able to tx/rx after the first - * start_sta, so make dummy start+stop calls, - * and then call start_sta again. - * this should be fixed in the fw. - */ - wl12xx_cmd_role_start_sta(wl, wlvif); - wl12xx_cmd_role_stop_sta(wl, wlvif); - } - + else ret = wl12xx_cmd_role_start_sta(wl, wlvif); - }
return ret; } diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index 95fbedc8ea342..a75b43f5a6c2a 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -560,9 +560,6 @@ wlcore_set_min_fw_ver(struct wl1271 *wl, unsigned int chip, /* Each RX/TX transaction requires an end-of-transaction transfer */ #define WLCORE_QUIRK_END_OF_TRANSACTION BIT(0)
-/* the first start_role(sta) sometimes doesn't work on wl12xx */ -#define WLCORE_QUIRK_START_STA_FAILS BIT(1) - /* wl127x and SPI don't support SDIO block size alignment */ #define WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN BIT(2)
From: Di Zhu zhudi21@huawei.com
[ Upstream commit 275b1e88cabb34dbcbe99756b67e9939d34a99b6 ]
pktgen create threads for all online cpus and bond these threads to relevant cpu repecivtily. when this thread firstly be woken up, it will compare cpu currently running with the cpu specified at the time of creation and if the two cpus are not equal, BUG_ON() will take effect causing panic on the system. Notice that these threads could be migrated to other cpus before start running because of the cpu hotplug after these threads have created. so the BUG_ON() used here seems unreasonable and we can replace it with WARN_ON() to just printf a warning other than panic the system.
Signed-off-by: Di Zhu zhudi21@huawei.com Link: https://lore.kernel.org/r/20210125124229.19334-1-zhudi21@huawei.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/pktgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 884afb8e9fc4e..b3132f11afeb9 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -3555,7 +3555,7 @@ static int pktgen_thread_worker(void *arg) struct pktgen_dev *pkt_dev = NULL; int cpu = t->cpu;
- BUG_ON(smp_processor_id() != cpu); + WARN_ON(smp_processor_id() != cpu);
init_waitqueue_head(&t->queue); complete(&t->start_done);
From: Miaoqing Pan miaoqing@codeaurora.org
[ Upstream commit b55379e343a3472c35f4a1245906db5158cab453 ]
Failed to transmit wmi management frames:
[84977.840894] ath10k_snoc a000000.wifi: wmi mgmt tx queue is full [84977.840913] ath10k_snoc a000000.wifi: failed to transmit packet, dropping: -28 [84977.840924] ath10k_snoc a000000.wifi: failed to submit frame: -28 [84977.840932] ath10k_snoc a000000.wifi: failed to transmit frame: -28
This issue is caused by race condition between skb_dequeue and __skb_queue_tail. The queue of ‘wmi_mgmt_tx_queue’ is protected by a different lock: ar->data_lock vs list->lock, the result is no protection. So when ath10k_mgmt_over_wmi_tx_work() and ath10k_mac_tx_wmi_mgmt() running concurrently on different CPUs, there appear to be a rare corner cases when the queue length is 1,
CPUx (skb_deuque) CPUy (__skb_queue_tail) next=list prev=list struct sk_buff *skb = skb_peek(list); WRITE_ONCE(newsk->next, next); WRITE_ONCE(list->qlen, list->qlen - 1);WRITE_ONCE(newsk->prev, prev); next = skb->next; WRITE_ONCE(next->prev, newsk); prev = skb->prev; WRITE_ONCE(prev->next, newsk); skb->next = skb->prev = NULL; list->qlen++; WRITE_ONCE(next->prev, prev); WRITE_ONCE(prev->next, next);
If the instruction ‘next = skb->next’ is executed before ‘WRITE_ONCE(prev->next, newsk)’, newsk will be lost, as CPUx get the old ‘next’ pointer, but the length is still added by one. The final result is the length of the queue will reach the maximum value but the queue is empty.
So remove ar->data_lock, and use 'skb_queue_tail' instead of '__skb_queue_tail' to prevent the potential race condition. Also switch to use skb_queue_len_lockless, in case we queue a few SKBs simultaneously.
Tested-on: WCN3990 hw1.0 SNOC WLAN.HL.3.1.c2-00033-QCAHLSWMTPLZ-1
Signed-off-by: Miaoqing Pan miaoqing@codeaurora.org Reviewed-by: Brian Norris briannorris@chromium.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/1608618887-8857-1-git-send-email-miaoqing@codeauro... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath10k/mac.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index be4420ff52b8a..aa5bec5a36761 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -3545,23 +3545,16 @@ bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar) static int ath10k_mac_tx_wmi_mgmt(struct ath10k *ar, struct sk_buff *skb) { struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue; - int ret = 0; - - spin_lock_bh(&ar->data_lock);
- if (skb_queue_len(q) == ATH10K_MAX_NUM_MGMT_PENDING) { + if (skb_queue_len_lockless(q) >= ATH10K_MAX_NUM_MGMT_PENDING) { ath10k_warn(ar, "wmi mgmt tx queue is full\n"); - ret = -ENOSPC; - goto unlock; + return -ENOSPC; }
- __skb_queue_tail(q, skb); + skb_queue_tail(q, skb); ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work);
-unlock: - spin_unlock_bh(&ar->data_lock); - - return ret; + return 0; }
static enum ath10k_mac_tx_path
From: Fangrui Song maskray@google.com
[ Upstream commit bb73d07148c405c293e576b40af37737faf23a6a ]
This is similar to commit
b21ebf2fb4cd ("x86: Treat R_X86_64_PLT32 as R_X86_64_PC32")
but for i386. As far as the kernel is concerned, R_386_PLT32 can be treated the same as R_386_PC32.
R_386_PLT32/R_X86_64_PLT32 are PC-relative relocation types which can only be used by branches. If the referenced symbol is defined externally, a PLT will be used.
R_386_PC32/R_X86_64_PC32 are PC-relative relocation types which can be used by address taking operations and branches. If the referenced symbol is defined externally, a copy relocation/canonical PLT entry will be created in the executable.
On x86-64, there is no PIC vs non-PIC PLT distinction and an R_X86_64_PLT32 relocation is produced for both `call/jmp foo` and `call/jmp foo@PLT` with newer (2018) GNU as/LLVM integrated assembler. This avoids canonical PLT entries (st_shndx=0, st_value!=0).
On i386, there are 2 types of PLTs, PIC and non-PIC. Currently, the GCC/GNU as convention is to use R_386_PC32 for non-PIC PLT and R_386_PLT32 for PIC PLT. Copy relocations/canonical PLT entries are possible ABI issues but GCC/GNU as will likely keep the status quo because (1) the ABI is legacy (2) the change will drop a GNU ld diagnostic for non-default visibility ifunc in shared objects.
clang-12 -fno-pic (since [1]) can emit R_386_PLT32 for compiler generated function declarations, because preventing canonical PLT entries is weighed over the rare ifunc diagnostic.
Further info for the more interested:
https://github.com/ClangBuiltLinux/linux/issues/1210 https://sourceware.org/bugzilla/show_bug.cgi?id=27169 https://github.com/llvm/llvm-project/commit/a084c0388e2a59b9556f2de008333323... [1]
[ bp: Massage commit message. ]
Reported-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Fangrui Song maskray@google.com Signed-off-by: Borislav Petkov bp@suse.de Reviewed-by: Nick Desaulniers ndesaulniers@google.com Reviewed-by: Nathan Chancellor natechancellor@gmail.com Tested-by: Nick Desaulniers ndesaulniers@google.com Tested-by: Nathan Chancellor natechancellor@gmail.com Tested-by: Sedat Dilek sedat.dilek@gmail.com Link: https://lkml.kernel.org/r/20210127205600.1227437-1-maskray@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/module.c | 1 + arch/x86/tools/relocs.c | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c index f58336af095c9..1ccfe6bb9122e 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c @@ -126,6 +126,7 @@ int apply_relocate(Elf32_Shdr *sechdrs, *location += sym->st_value; break; case R_386_PC32: + case R_386_PLT32: /* Add the value, subtract its position */ *location += sym->st_value - (uint32_t)location; break; diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c index 220e97841e494..c58b631781233 100644 --- a/arch/x86/tools/relocs.c +++ b/arch/x86/tools/relocs.c @@ -840,9 +840,11 @@ static int do_reloc32(struct section *sec, Elf_Rel *rel, Elf_Sym *sym, case R_386_PC32: case R_386_PC16: case R_386_PC8: + case R_386_PLT32: /* - * NONE can be ignored and PC relative relocations don't - * need to be adjusted. + * NONE can be ignored and PC relative relocations don't need + * to be adjusted. Because sym must be defined, R_386_PLT32 can + * be treated the same way as R_386_PC32. */ break;
@@ -883,9 +885,11 @@ static int do_reloc_real(struct section *sec, Elf_Rel *rel, Elf_Sym *sym, case R_386_PC32: case R_386_PC16: case R_386_PC8: + case R_386_PLT32: /* - * NONE can be ignored and PC relative relocations don't - * need to be adjusted. + * NONE can be ignored and PC relative relocations don't need + * to be adjusted. Because sym must be defined, R_386_PLT32 can + * be treated the same way as R_386_PC32. */ break;
From: Gopal Tiwari gtiwari@redhat.com
[ Upstream commit e8bd76ede155fd54d8c41d045dda43cd3174d506 ]
kernel panic trace looks like:
#5 [ffffb9e08698fc80] do_page_fault at ffffffffb666e0d7 #6 [ffffb9e08698fcb0] page_fault at ffffffffb70010fe [exception RIP: amp_read_loc_assoc_final_data+63] RIP: ffffffffc06ab54f RSP: ffffb9e08698fd68 RFLAGS: 00010246 RAX: 0000000000000000 RBX: ffff8c8845a5a000 RCX: 0000000000000004 RDX: 0000000000000000 RSI: ffff8c8b9153d000 RDI: ffff8c8845a5a000 RBP: ffffb9e08698fe40 R8: 00000000000330e0 R9: ffffffffc0675c94 R10: ffffb9e08698fe58 R11: 0000000000000001 R12: ffff8c8b9cbf6200 R13: 0000000000000000 R14: 0000000000000000 R15: ffff8c8b2026da0b ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 #7 [ffffb9e08698fda8] hci_event_packet at ffffffffc0676904 [bluetooth] #8 [ffffb9e08698fe50] hci_rx_work at ffffffffc06629ac [bluetooth] #9 [ffffb9e08698fe98] process_one_work at ffffffffb66f95e7
hcon->amp_mgr seems NULL triggered kernel panic in following line inside function amp_read_loc_assoc_final_data
set_bit(READ_LOC_AMP_ASSOC_FINAL, &mgr->state);
Fixed by checking NULL for mgr.
Signed-off-by: Gopal Tiwari gtiwari@redhat.com Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/bluetooth/amp.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c index ebcab5bbadd7e..9f645a1d0202d 100644 --- a/net/bluetooth/amp.c +++ b/net/bluetooth/amp.c @@ -305,6 +305,9 @@ void amp_read_loc_assoc_final_data(struct hci_dev *hdev, struct hci_request req; int err;
+ if (!mgr) + return; + cp.phy_handle = hcon->handle; cp.len_so_far = cpu_to_le16(0); cp.max_len = cpu_to_le16(hdev->amp_assoc_size);
From: Christian Gromm christian.gromm@microchip.com
[ Upstream commit 45b754ae5b82949dca2b6e74fa680313cefdc813 ]
This patch checks the function parameter 'bytes' before doing the subtraction to prevent memory corruption.
Signed-off-by: Christian Gromm christian.gromm@microchip.com Reported-by: Dan Carpenter dan.carpenter@oracle.com Link: https://lore.kernel.org/r/1612282865-21846-1-git-send-email-christian.gromm@... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/most/aim-sound/sound.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/staging/most/aim-sound/sound.c b/drivers/staging/most/aim-sound/sound.c index ea1366a440083..e259bf4956ab6 100644 --- a/drivers/staging/most/aim-sound/sound.c +++ b/drivers/staging/most/aim-sound/sound.c @@ -92,6 +92,8 @@ static void swap_copy24(u8 *dest, const u8 *source, unsigned int bytes) { unsigned int i = 0;
+ if (bytes < 2) + return; while (i < bytes - 2) { dest[i] = source[i + 2]; dest[i + 1] = source[i + 1];
From: Sean Young sean@mess.org
[ Upstream commit 9dec0f48a75e0dadca498002d25ef4e143e60194 ]
prescaler larger than 8 would mean the carrier is at most 152Hz, which does not make sense for IR carriers.
Reported-by: syzbot+6d31bf169a8265204b8d@syzkaller.appspotmail.com Signed-off-by: Sean Young sean@mess.org Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/rc/mceusb.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index bf7aaff3aa375..bbbbfd697f9c4 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -630,11 +630,18 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, u8 *buf, int buf_len, data[0], data[1]); break; case MCE_RSP_EQIRCFS: + if (!data[0] && !data[1]) { + dev_dbg(dev, "%s: no carrier", inout); + break; + } + // prescaler should make sense + if (data[0] > 8) + break; period = DIV_ROUND_CLOSEST((1U << data[0] * 2) * (data[1] + 1), 10); if (!period) break; - carrier = (1000 * 1000) / period; + carrier = USEC_PER_SEC / period; dev_dbg(dev, "%s carrier of %u Hz (period %uus)", inout, carrier, period); break;
From: Ricardo Ribalda ribalda@chromium.org
[ Upstream commit 7532dad6634031d083df7af606fac655b8d08b5c ]
Avoid an underflow while calculating the number of inputs for entities with zero pads.
Signed-off-by: Ricardo Ribalda ribalda@chromium.org Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/uvc/uvc_driver.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 5899593dabaf6..aaaee039fb30c 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -904,7 +904,10 @@ static struct uvc_entity *uvc_alloc_entity(u16 type, u8 id, unsigned int i;
extra_size = roundup(extra_size, sizeof(*entity->pads)); - num_inputs = (type & UVC_TERM_OUTPUT) ? num_pads : num_pads - 1; + if (num_pads) + num_inputs = type & UVC_TERM_OUTPUT ? num_pads : num_pads - 1; + else + num_inputs = 0; size = sizeof(*entity) + extra_size + sizeof(*entity->pads) * num_pads + num_inputs; entity = kzalloc(size, GFP_KERNEL); @@ -920,7 +923,7 @@ static struct uvc_entity *uvc_alloc_entity(u16 type, u8 id,
for (i = 0; i < num_inputs; ++i) entity->pads[i].flags = MEDIA_PAD_FL_SINK; - if (!UVC_ENTITY_IS_OTERM(entity)) + if (!UVC_ENTITY_IS_OTERM(entity) && num_pads) entity->pads[num_pads-1].flags = MEDIA_PAD_FL_SOURCE;
entity->bNrInPins = num_inputs;
From: Jaegeuk Kim jaegeuk@kernel.org
[ Upstream commit 632faca72938f9f63049e48a8c438913828ac7a9 ]
If we have large section/zone, unallocated segment makes them corrupted.
E.g.,
- Pinned file: -1 119304647 119304647 - ATGC data: -1 119304647 119304647
Reviewed-by: Chao Yu yuchao0@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/segment.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index 0d46e936d54ed..00c415131b069 100644 --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h @@ -91,11 +91,11 @@ #define BLKS_PER_SEC(sbi) \ ((sbi)->segs_per_sec * (sbi)->blocks_per_seg) #define GET_SEC_FROM_SEG(sbi, segno) \ - ((segno) / (sbi)->segs_per_sec) + (((segno) == -1) ? -1: (segno) / (sbi)->segs_per_sec) #define GET_SEG_FROM_SEC(sbi, secno) \ ((secno) * (sbi)->segs_per_sec) #define GET_ZONE_FROM_SEC(sbi, secno) \ - ((secno) / (sbi)->secs_per_zone) + (((secno) == -1) ? -1: (secno) / (sbi)->secs_per_zone) #define GET_ZONE_FROM_SEG(sbi, segno) \ GET_ZONE_FROM_SEC(sbi, GET_SEC_FROM_SEG(sbi, segno))
From: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp
[ Upstream commit 5797e861e402fff2bedce4ec8b7c89f4248b6073 ]
syzbot is reporting that tomoyo's quota check is racy [1]. But this check is tolerant of some degree of inaccuracy. Thus, teach KCSAN to ignore this data race.
[1] https://syzkaller.appspot.com/bug?id=999533deec7ba6337f8aa25d8bd1a4d5f7e5047...
Reported-by: syzbot syzbot+0789a72b46fd91431bd8@syzkaller.appspotmail.com Signed-off-by: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp Signed-off-by: Sasha Levin sashal@kernel.org --- security/tomoyo/file.c | 16 ++++++++-------- security/tomoyo/network.c | 8 ++++---- security/tomoyo/util.c | 24 ++++++++++++------------ 3 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c index 2a374b4da8f5c..cbe0dc87bb919 100644 --- a/security/tomoyo/file.c +++ b/security/tomoyo/file.c @@ -356,13 +356,13 @@ static bool tomoyo_merge_path_acl(struct tomoyo_acl_info *a, { u16 * const a_perm = &container_of(a, struct tomoyo_path_acl, head) ->perm; - u16 perm = *a_perm; + u16 perm = READ_ONCE(*a_perm); const u16 b_perm = container_of(b, struct tomoyo_path_acl, head)->perm; if (is_delete) perm &= ~b_perm; else perm |= b_perm; - *a_perm = perm; + WRITE_ONCE(*a_perm, perm); return !perm; }
@@ -428,14 +428,14 @@ static bool tomoyo_merge_mkdev_acl(struct tomoyo_acl_info *a, { u8 *const a_perm = &container_of(a, struct tomoyo_mkdev_acl, head)->perm; - u8 perm = *a_perm; + u8 perm = READ_ONCE(*a_perm); const u8 b_perm = container_of(b, struct tomoyo_mkdev_acl, head) ->perm; if (is_delete) perm &= ~b_perm; else perm |= b_perm; - *a_perm = perm; + WRITE_ONCE(*a_perm, perm); return !perm; }
@@ -505,13 +505,13 @@ static bool tomoyo_merge_path2_acl(struct tomoyo_acl_info *a, { u8 * const a_perm = &container_of(a, struct tomoyo_path2_acl, head) ->perm; - u8 perm = *a_perm; + u8 perm = READ_ONCE(*a_perm); const u8 b_perm = container_of(b, struct tomoyo_path2_acl, head)->perm; if (is_delete) perm &= ~b_perm; else perm |= b_perm; - *a_perm = perm; + WRITE_ONCE(*a_perm, perm); return !perm; }
@@ -640,14 +640,14 @@ static bool tomoyo_merge_path_number_acl(struct tomoyo_acl_info *a, { u8 * const a_perm = &container_of(a, struct tomoyo_path_number_acl, head)->perm; - u8 perm = *a_perm; + u8 perm = READ_ONCE(*a_perm); const u8 b_perm = container_of(b, struct tomoyo_path_number_acl, head) ->perm; if (is_delete) perm &= ~b_perm; else perm |= b_perm; - *a_perm = perm; + WRITE_ONCE(*a_perm, perm); return !perm; }
diff --git a/security/tomoyo/network.c b/security/tomoyo/network.c index cd6932e5225c4..828645fc97c09 100644 --- a/security/tomoyo/network.c +++ b/security/tomoyo/network.c @@ -233,14 +233,14 @@ static bool tomoyo_merge_inet_acl(struct tomoyo_acl_info *a, { u8 * const a_perm = &container_of(a, struct tomoyo_inet_acl, head)->perm; - u8 perm = *a_perm; + u8 perm = READ_ONCE(*a_perm); const u8 b_perm = container_of(b, struct tomoyo_inet_acl, head)->perm;
if (is_delete) perm &= ~b_perm; else perm |= b_perm; - *a_perm = perm; + WRITE_ONCE(*a_perm, perm); return !perm; }
@@ -259,14 +259,14 @@ static bool tomoyo_merge_unix_acl(struct tomoyo_acl_info *a, { u8 * const a_perm = &container_of(a, struct tomoyo_unix_acl, head)->perm; - u8 perm = *a_perm; + u8 perm = READ_ONCE(*a_perm); const u8 b_perm = container_of(b, struct tomoyo_unix_acl, head)->perm;
if (is_delete) perm &= ~b_perm; else perm |= b_perm; - *a_perm = perm; + WRITE_ONCE(*a_perm, perm); return !perm; }
diff --git a/security/tomoyo/util.c b/security/tomoyo/util.c index 580b318910f14..f512123c7753d 100644 --- a/security/tomoyo/util.c +++ b/security/tomoyo/util.c @@ -1041,30 +1041,30 @@ bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r) u8 i; if (ptr->is_deleted) continue; + /* + * Reading perm bitmap might race with tomoyo_merge_*() because + * caller does not hold tomoyo_policy_lock mutex. But exceeding + * max_learning_entry parameter by a few entries does not harm. + */ switch (ptr->type) { case TOMOYO_TYPE_PATH_ACL: - perm = container_of(ptr, struct tomoyo_path_acl, head) - ->perm; + data_race(perm = container_of(ptr, struct tomoyo_path_acl, head)->perm); break; case TOMOYO_TYPE_PATH2_ACL: - perm = container_of(ptr, struct tomoyo_path2_acl, head) - ->perm; + data_race(perm = container_of(ptr, struct tomoyo_path2_acl, head)->perm); break; case TOMOYO_TYPE_PATH_NUMBER_ACL: - perm = container_of(ptr, struct tomoyo_path_number_acl, - head)->perm; + data_race(perm = container_of(ptr, struct tomoyo_path_number_acl, head) + ->perm); break; case TOMOYO_TYPE_MKDEV_ACL: - perm = container_of(ptr, struct tomoyo_mkdev_acl, - head)->perm; + data_race(perm = container_of(ptr, struct tomoyo_mkdev_acl, head)->perm); break; case TOMOYO_TYPE_INET_ACL: - perm = container_of(ptr, struct tomoyo_inet_acl, - head)->perm; + data_race(perm = container_of(ptr, struct tomoyo_inet_acl, head)->perm); break; case TOMOYO_TYPE_UNIX_ACL: - perm = container_of(ptr, struct tomoyo_unix_acl, - head)->perm; + data_race(perm = container_of(ptr, struct tomoyo_unix_acl, head)->perm); break; case TOMOYO_TYPE_MANUAL_TASK_ACL: perm = 0;
From: Sabyrzhan Tasbolatov snovitoll@gmail.com
[ Upstream commit 7ef4c19d245f3dc233fd4be5acea436edd1d83d8 ]
syzbot found WARNINGs in several smackfs write operations where bytes count is passed to memdup_user_nul which exceeds GFP MAX_ORDER. Check count size if bigger than PAGE_SIZE.
Per smackfs doc, smk_write_net4addr accepts any label or -CIPSO, smk_write_net6addr accepts any label or -DELETE. I couldn't find any general rule for other label lengths except SMK_LABELLEN, SMK_LONGLABEL, SMK_CIPSOMAX which are documented.
Let's constrain, in general, smackfs label lengths for PAGE_SIZE. Although fuzzer crashes write to smackfs/netlabel on 0x400000 length.
Here is a quick way to reproduce the WARNING: python -c "print('A' * 0x400000)" > /sys/fs/smackfs/netlabel
Reported-by: syzbot+a71a442385a0b2815497@syzkaller.appspotmail.com Signed-off-by: Sabyrzhan Tasbolatov snovitoll@gmail.com Signed-off-by: Casey Schaufler casey@schaufler-ca.com Signed-off-by: Sasha Levin sashal@kernel.org --- security/smack/smackfs.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index accd3846f1e3e..4f8c1a272df07 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -1191,7 +1191,7 @@ static ssize_t smk_write_net4addr(struct file *file, const char __user *buf, return -EPERM; if (*ppos != 0) return -EINVAL; - if (count < SMK_NETLBLADDRMIN) + if (count < SMK_NETLBLADDRMIN || count > PAGE_SIZE - 1) return -EINVAL;
data = memdup_user_nul(buf, count); @@ -1451,7 +1451,7 @@ static ssize_t smk_write_net6addr(struct file *file, const char __user *buf, return -EPERM; if (*ppos != 0) return -EINVAL; - if (count < SMK_NETLBLADDRMIN) + if (count < SMK_NETLBLADDRMIN || count > PAGE_SIZE - 1) return -EINVAL;
data = memdup_user_nul(buf, count); @@ -1858,6 +1858,10 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf, if (!smack_privileged(CAP_MAC_ADMIN)) return -EPERM;
+ /* Enough data must be present */ + if (count == 0 || count > PAGE_SIZE) + return -EINVAL; + data = memdup_user_nul(buf, count); if (IS_ERR(data)) return PTR_ERR(data); @@ -2029,6 +2033,9 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, if (!smack_privileged(CAP_MAC_ADMIN)) return -EPERM;
+ if (count > PAGE_SIZE) + return -EINVAL; + data = memdup_user_nul(buf, count); if (IS_ERR(data)) return PTR_ERR(data); @@ -2116,6 +2123,9 @@ static ssize_t smk_write_unconfined(struct file *file, const char __user *buf, if (!smack_privileged(CAP_MAC_ADMIN)) return -EPERM;
+ if (count > PAGE_SIZE) + return -EINVAL; + data = memdup_user_nul(buf, count); if (IS_ERR(data)) return PTR_ERR(data); @@ -2669,6 +2679,10 @@ static ssize_t smk_write_syslog(struct file *file, const char __user *buf, if (!smack_privileged(CAP_MAC_ADMIN)) return -EPERM;
+ /* Enough data must be present */ + if (count == 0 || count > PAGE_SIZE) + return -EINVAL; + data = memdup_user_nul(buf, count); if (IS_ERR(data)) return PTR_ERR(data); @@ -2761,10 +2775,13 @@ static ssize_t smk_write_relabel_self(struct file *file, const char __user *buf, return -EPERM;
/* + * No partial write. * Enough data must be present. */ if (*ppos != 0) return -EINVAL; + if (count == 0 || count > PAGE_SIZE) + return -EINVAL;
data = memdup_user_nul(buf, count); if (IS_ERR(data))
From: "Andrea Parri (Microsoft)" parri.andrea@gmail.com
[ Upstream commit e4d221b42354b2e2ddb9187a806afb651eee2cda ]
An erroneous or malicious host could send multiple rescind messages for a same channel. In vmbus_onoffer_rescind(), the guest maps the channel ID to obtain a pointer to the channel object and it eventually releases such object and associated data. The host could time rescind messages and lead to an use-after-free. Add a new flag to the channel structure to make sure that only one instance of vmbus_onoffer_rescind() can get the reference to the channel object.
Reported-by: Juan Vazquez juvazq@microsoft.com Signed-off-by: Andrea Parri (Microsoft) parri.andrea@gmail.com Reviewed-by: Michael Kelley mikelley@microsoft.com Link: https://lore.kernel.org/r/20201209070827.29335-6-parri.andrea@gmail.com Signed-off-by: Wei Liu wei.liu@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hv/channel_mgmt.c | 12 ++++++++++++ include/linux/hyperv.h | 1 + 2 files changed, 13 insertions(+)
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 5bf633c15cd4b..6ddda97030628 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -942,6 +942,18 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
mutex_lock(&vmbus_connection.channel_mutex); channel = relid2channel(rescind->child_relid); + if (channel != NULL) { + /* + * Guarantee that no other instance of vmbus_onoffer_rescind() + * has got a reference to the channel object. Synchronize on + * &vmbus_connection.channel_mutex. + */ + if (channel->rescind_ref) { + mutex_unlock(&vmbus_connection.channel_mutex); + return; + } + channel->rescind_ref = true; + } mutex_unlock(&vmbus_connection.channel_mutex);
if (channel == NULL) { diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 63cd81e5610d1..22e2c2d75361e 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -710,6 +710,7 @@ struct vmbus_channel { u8 monitor_bit;
bool rescind; /* got rescind msg */ + bool rescind_ref; /* got rescind msg, got channel reference */ struct completion rescind_event;
u32 ringbuffer_gpadlhandle;
On Wed, Feb 24, 2021 at 07:55:12AM -0500, Sasha Levin wrote:
From: "Andrea Parri (Microsoft)" parri.andrea@gmail.com
[ Upstream commit e4d221b42354b2e2ddb9187a806afb651eee2cda ]
An erroneous or malicious host could send multiple rescind messages for a same channel. In vmbus_onoffer_rescind(), the guest maps the channel ID to obtain a pointer to the channel object and it eventually releases such object and associated data. The host could time rescind messages and lead to an use-after-free. Add a new flag to the channel structure to make sure that only one instance of vmbus_onoffer_rescind() can get the reference to the channel object.
Reported-by: Juan Vazquez juvazq@microsoft.com Signed-off-by: Andrea Parri (Microsoft) parri.andrea@gmail.com Reviewed-by: Michael Kelley mikelley@microsoft.com Link: https://lore.kernel.org/r/20201209070827.29335-6-parri.andrea@gmail.com Signed-off-by: Wei Liu wei.liu@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org
Same here.
Andrea
drivers/hv/channel_mgmt.c | 12 ++++++++++++ include/linux/hyperv.h | 1 + 2 files changed, 13 insertions(+)
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 5bf633c15cd4b..6ddda97030628 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -942,6 +942,18 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) mutex_lock(&vmbus_connection.channel_mutex); channel = relid2channel(rescind->child_relid);
- if (channel != NULL) {
/*
* Guarantee that no other instance of vmbus_onoffer_rescind()
* has got a reference to the channel object. Synchronize on
* &vmbus_connection.channel_mutex.
*/
if (channel->rescind_ref) {
mutex_unlock(&vmbus_connection.channel_mutex);
return;
}
channel->rescind_ref = true;
- } mutex_unlock(&vmbus_connection.channel_mutex);
if (channel == NULL) { diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 63cd81e5610d1..22e2c2d75361e 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -710,6 +710,7 @@ struct vmbus_channel { u8 monitor_bit; bool rescind; /* got rescind msg */
- bool rescind_ref; /* got rescind msg, got channel reference */ struct completion rescind_event;
u32 ringbuffer_gpadlhandle; -- 2.27.0
From: John David Anglin dave.anglin@bell.net
[ Upstream commit 31680c1d1595a59e17c14ec036b192a95f8e5f4a ]
Bump 64-bit IRQ stack size to 64 KB.
I had a kernel IRQ stack overflow on the mx3210 debian buildd machine. This patch increases the 64-bit IRQ stack size to 64 KB. The 64-bit stack size needs to be larger than the 32-bit stack size since registers are twice as big.
Signed-off-by: John David Anglin dave.anglin@bell.net Signed-off-by: Helge Deller deller@gmx.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/parisc/kernel/irq.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index 0ca254085a662..c152c30c2d06d 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -380,7 +380,11 @@ static inline int eirr_to_irq(unsigned long eirr) /* * IRQ STACK - used for irq handler */ +#ifdef CONFIG_64BIT +#define IRQ_STACK_SIZE (4096 << 4) /* 64k irq stack size */ +#else #define IRQ_STACK_SIZE (4096 << 3) /* 32k irq stack size */ +#endif
union irq_stack_union { unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)];
linux-stable-mirror@lists.linaro.org