4.9.285-rc1 review
Greg Kroah-Hartman
maintainercover 4.9.285-rc1 review
This is the start of the stable review cycle for the 4.9.285 release. There are 57 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 06 Oct 2021 12:50:17 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.9.285-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.9.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 4.9.285-rc1
Yanfei Xu <[email protected]>
net: mdiobus: Fix memory leak in __mdiobus_register
Anirudh Rayabharam <[email protected]>
HID: usbhid: free raw_report buffers in usbhid_stop
Jozsef Kadlecsik <[email protected]>
netfilter: ipset: Fix oversized kvmalloc() calls
F.A.Sulaiman <[email protected]>
HID: betop: fix slab-out-of-bounds Write in betop_probe
Suzuki K Poulose <[email protected]>
arm64: Extend workaround for erratum 1024718 to all versions of Cortex-A55
Alex Sverdlin <[email protected]>
ARM: 9098/1: ftrace: MODULE_PLT: Fix build problem without DYNAMIC_FTRACE
Alex Sverdlin <[email protected]>
ARM: 9079/1: ftrace: Add MODULE_PLTS support
Alex Sverdlin <[email protected]>
ARM: 9078/1: Add warn suppress parameter to arm_gen_branch_link()
Alex Sverdlin <[email protected]>
ARM: 9077/1: PLT: Move struct plt_entries definition to header
Sai Krishna Potthuri <[email protected]>
EDAC/synopsys: Fix wrong value type assignment for edac_mode
Eric Dumazet <[email protected]>
net: udp: annotate data race around udp_sk(sk)->corkflag
yangerkun <[email protected]>
ext4: fix potential infinite loop in ext4_dx_readdir()
Johan Hovold <[email protected]>
ipack: ipoctal: fix module reference leak
Johan Hovold <[email protected]>
ipack: ipoctal: fix missing allocation-failure check
Johan Hovold <[email protected]>
ipack: ipoctal: fix tty-registration error handling
Johan Hovold <[email protected]>
ipack: ipoctal: fix tty registration race
Johan Hovold <[email protected]>
ipack: ipoctal: fix stack information leak
Jacob Keller <[email protected]>
e100: fix buffer overrun in e100_get_regs
Jacob Keller <[email protected]>
e100: fix length calculation in e100_get_regs_len
Paul Fertser <[email protected]>
hwmon: (tmp421) fix rounding for negative values
Lorenzo Bianconi <[email protected]>
mac80211: limit injected vht mcs/nss in ieee80211_parse_tx_radiotap
Andrea Claudi <[email protected]>
ipvs: check that ip_vs_conn_tab_bits is between 8 and 20
Johannes Berg <[email protected]>
mac80211: fix use-after-free in CCMP/GCMP RX
James Morse <[email protected]>
cpufreq: schedutil: Destroy mutex before kobject_put() frees the memory
Kevin Hao <[email protected]>
cpufreq: schedutil: Use kobject release() method to free sugov_tunables
Igor Matheus Andrade Torrente <[email protected]>
tty: Fix out-of-bound vmalloc access in imageblit
Linus Torvalds <[email protected]>
qnx4: work around gcc false positive warning bug
Pali Rohár <[email protected]>
arm64: dts: marvell: armada-37xx: Extend PCIe MEM space
Linus Torvalds <[email protected]>
spi: Fix tegra20 build with CONFIG_PM=n
Guenter Roeck <[email protected]>
net: 6pack: Fix tx timeout and slot time
Guenter Roeck <[email protected]>
alpha: Declare virt_to_phys and virt_to_bus parameter as pointer to volatile
Dan Li <[email protected]>
arm64: Mark __stack_chk_guard as __ro_after_init
Helge Deller <[email protected]>
parisc: Use absolute_pointer() to define PAGE0
Linus Torvalds <[email protected]>
qnx4: avoid stringop-overread errors
Linus Torvalds <[email protected]>
sparc: avoid stringop-overread errors
Guenter Roeck <[email protected]>
net: i825xx: Use absolute_pointer for memcpy from fixed memory location
Guenter Roeck <[email protected]>
compiler.h: Introduce absolute_pointer macro
Guenter Roeck <[email protected]>
m68k: Double cast io functions to unsigned long
Jesper Nilsson <[email protected]>
net: stmmac: allow CSR clock of 300MHz
Zhihao Cheng <[email protected]>
blktrace: Fix uaf in blk_trace access after removing by sysfs
Baokun Li <[email protected]>
scsi: iscsi: Adjust iface sysfs attr detection
Aya Levin <[email protected]>
net/mlx4_en: Don't allow aRFS for encapsulated packets
Johan Hovold <[email protected]>
net: hso: fix muxed tty registration
Pali Rohár <[email protected]>
serial: mvebu-uart: fix driver's tx_empty callback
Dan Carpenter <[email protected]>
mcb: fix error handling in mcb_alloc_bus()
Slark Xiao <[email protected]>
USB: serial: option: add device id for Foxconn T99W265
Krzysztof Kozlowski <[email protected]>
USB: serial: option: remove duplicate USB device ID
Carlo Lobrano <[email protected]>
USB: serial: option: add Telit LN920 compositions
Krzysztof Kozlowski <[email protected]>
USB: serial: mos7840: remove duplicated 0xac24 device ID
Johan Hovold <[email protected]>
staging: greybus: uart: fix tty use after free
Uwe Brandt <[email protected]>
USB: serial: cp210x: add ID for GW Instek GDM-834x Digital Multimeter
Ondrej Zary <[email protected]>
usb-storage: Add quirk for ScanLogic SL11R-IDE older than 2.6c
Jan Beulich <[email protected]>
xen/x86: fix PV trap handling on secondary processors
Steve French <[email protected]>
cifs: fix incorrect check for null pointer in header_assemble
Dan Carpenter <[email protected]>
usb: musb: tusb6010: uninitialized data in tusb_fifo_write_unaligned()
Dan Carpenter <[email protected]>
usb: gadget: r8a66597: fix a loop in set_feature()
Wengang Wang <[email protected]>
ocfs2: drop acl cache for directories too
-------------
Diffstat:
Makefile | 4 +- arch/alpha/include/asm/io.h | 6 +- arch/arm/include/asm/ftrace.h | 3 + arch/arm/include/asm/insn.h | 8 +-- arch/arm/include/asm/module.h | 10 ++++ arch/arm/kernel/ftrace.c | 45 ++++++++++++--- arch/arm/kernel/insn.c | 19 ++++--- arch/arm/kernel/module-plts.c | 49 ++++++++++++---- arch/arm64/Kconfig | 2 +- arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 11 +++- arch/arm64/kernel/process.c | 2 +- arch/arm64/mm/proc.S | 4 +- arch/m68k/include/asm/raw_io.h | 20 +++---- arch/parisc/include/asm/page.h | 2 +- arch/sparc/kernel/mdesc.c | 3 +- arch/x86/xen/enlighten.c | 15 +++-- drivers/cpufreq/cpufreq_governor_attr_set.c | 2 +- drivers/edac/synopsys_edac.c | 2 +- drivers/hid/hid-betopff.c | 13 ++++- drivers/hid/usbhid/hid-core.c | 13 ++++- drivers/hwmon/tmp421.c | 24 +++----- drivers/ipack/devices/ipoctal.c | 63 +++++++++++++++------ drivers/mcb/mcb-core.c | 12 ++-- drivers/net/ethernet/i825xx/82596.c | 2 +- drivers/net/ethernet/intel/e100.c | 22 +++++--- drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 3 + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +- drivers/net/hamradio/6pack.c | 4 +- drivers/net/phy/mdio_bus.c | 1 + drivers/net/usb/hso.c | 12 ++-- drivers/scsi/scsi_transport_iscsi.c | 8 +-- drivers/spi/spi-tegra20-slink.c | 4 +- drivers/staging/greybus/uart.c | 62 ++++++++++---------- drivers/tty/serial/mvebu-uart.c | 2 +- drivers/tty/vt/vt.c | 21 ++++++- drivers/usb/gadget/udc/r8a66597-udc.c | 2 +- drivers/usb/musb/tusb6010.c | 1 + drivers/usb/serial/cp210x.c | 1 + drivers/usb/serial/mos7840.c | 2 - drivers/usb/serial/option.c | 11 +++- drivers/usb/storage/unusual_devs.h | 9 ++- fs/cifs/connect.c | 5 +- fs/ext4/dir.c | 6 +- fs/ocfs2/dlmglue.c | 3 +- fs/qnx4/dir.c | 69 +++++++++++++++++------ include/linux/compiler.h | 2 + kernel/sched/cpufreq_schedutil.c | 16 ++++-- kernel/trace/blktrace.c | 8 +++ net/ipv4/udp.c | 10 ++-- net/ipv6/udp.c | 2 +- net/mac80211/tx.c | 4 ++ net/mac80211/wpa.c | 6 ++ net/netfilter/ipset/ip_set_hash_gen.h | 4 +- net/netfilter/ipvs/ip_vs_conn.c | 4 ++ 54 files changed, 438 insertions(+), 202 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/57 ocfs2: drop acl cache for directories too
From: Wengang Wang <[email protected]>
commit 9c0f0a03e386f4e1df33db676401547e1b7800c6 upstream.
ocfs2_data_convert_worker() is currently dropping any cached acl info for FILE before down-converting meta lock. It should also drop for DIRECTORY. Otherwise the second acl lookup returns the cached one (from VFS layer) which could be already stale.
The problem we are seeing is that the acl changes on one node doesn't get refreshed on other nodes in the following case:
Node 1 Node 2
-------------- ----------------
getfacl dir1
getfacl dir1 <-- this is OK
setfacl -m u:user1:rwX dir1
getfacl dir1 <-- see the change for user1
getfacl dir1 <-- can't see change for user1
--- fs/ocfs2/dlmglue.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/ocfs2/dlmglue.c +2 -1
@@ -3704,7 +3704,7 @@ static int ocfs2_data_convert_worker(str oi =OCFS2_I (inode); oi->ip_dir_lock_gen++;mlog (0 ,"generation: %u\n" , oi->ip_dir_lock_gen); - goto out; + goto out_forget; }if (!S_ISREG (inode->i_mode))
@@ -3735,6 +3735,7 @@ static int ocfs2_data_convert_worker(strfilemap_fdatawait (mapping); } +out_forget:forget_all_cached_acls (inode); out:
Greg Kroah-Hartman
maintainerPATCH 2/57 usb: gadget: r8a66597: fix a loop in set_feature()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
commit 17956b53ebff6a490baf580a836cbd3eae94892b upstream.
This loop is supposed to loop until if reads something other than CS_IDST or until it times out after 30,000 attempts. But because of the || vs && bug, it will never time out and instead it will loop a minimum of 30,000 times.
This bug is quite old but the code is only used in USB_DEVICE_TEST_MODE so it probably doesn't affect regular usage.
--- drivers/usb/gadget/udc/r8a66597-udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/gadget/udc/r8a66597-udc.c +1 -1
@@ -1253,7 +1253,7 @@ static void set_feature(struct r8a66597do { tmp =r8a66597_read (r8a66597,INTSTS0 ) &CTSQ ;udelay (1 ); - }while (tmp !=CS_IDST || timeout-- >0 ); + }while (tmp !=CS_IDST && timeout-- >0 );if (tmp ==CS_IDST ) r8a66597_bset(r8a66597,
Greg Kroah-Hartman
maintainerPATCH 3/57 usb: musb: tusb6010: uninitialized data in tusb_fifo_write_unaligned()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
commit 517c7bf99bad3d6b9360558414aae634b7472d80 upstream.
This is writing to the first 1 - 3 bytes of "val" and then writing all four bytes to musb_writel(). The last byte is always going to be garbage. Zero out the last bytes instead.
--- drivers/usb/musb/tusb6010.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/musb/tusb6010.c +1 -0
@@ -193,6 +193,7 @@ tusb_fifo_write_unaligned(void __iomem * }if (len >0 ) {/* Write the rest 1 - 3 bytes to FIFO */ + val =0 ;memcpy (&val, buf, len);musb_writel (fifo,0 , val); }
Greg Kroah-Hartman
maintainerPATCH 4/57 cifs: fix incorrect check for null pointer in header_assemble
In reply to Greg Kroah-HartmanFrom: Steve French <[email protected]>
commit 9ed38fd4a15417cac83967360cf20b853bfab9b6 upstream.
Although very unlikely that the tlink pointer would be null in this case, get_next_mid function can in theory return null (but not an error) so need to check for null (not for IS_ERR, which can not be returned here).
Address warning:
fs/smbfs_client/connect.c:2392 cifs_match_super()
warn: 'tlink' isn't an ERR_PTR
Pointed out by Dan Carpenter via smatch code analysis tool
--- fs/cifs/connect.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
fs/cifs/connect.c +3 -2
@@ -2960,9 +2960,10 @@ cifs_match_super(struct super_block *sb,spin_lock (&cifs_tcp_ses_lock); cifs_sb =CIFS_SB (sb); tlink =cifs_get_tlink (cifs_sb_master_tlink (cifs_sb)); -if (IS_ERR (tlink)) { +if (tlink ==NULL ) { +/* can not match superblock if tlink were ever null */ spin_unlock (&cifs_tcp_ses_lock); -return rc; +return 0 ; } tcon =tlink_tcon (tlink); ses = tcon->ses;
Greg Kroah-Hartman
maintainerPATCH 5/57 xen/x86: fix PV trap handling on secondary processors
In reply to Greg Kroah-HartmanFrom: Jan Beulich <[email protected]>
commit 0594c58161b6e0f3da8efa9c6e3d4ba52b652717 upstream.
The initial observation was that in PV mode under Xen 32-bit user space didn't work anymore. Attempts of system calls ended in #GP(0x402). All of the sudden the vector 0x80 handler was not in place anymore. As it turns out up to 5.13 redundant initialization did occur: Once from cpu_initialize_context() (through its VCPUOP_initialise hypercall) and a 2nd time while each CPU was brought fully up. This 2nd initialization is now gone, uncovering that the 1st one was flawed: Unlike for the set_trap_table hypercall, a full virtual IDT needs to be specified here; the "vector" fields of the individual entries are of no interest. With many (kernel) IDT entries still(?) (i.e. at that point at least) empty, the syscall vector 0x80 ended up in slot 0x20 of the virtual IDT, thus becoming the domain's handler for vector 0x20.
Make xen_convert_trap_info() fit for either purpose, leveraging the fact that on the xen_copy_trap_info() path the table starts out zero-filled. This includes moving out the writing of the sentinel, which would also have lead to a buffer overrun in the xen_copy_trap_info() case if all (kernel) IDT entries were populated. Convert the writing of the sentinel to clearing of the entire table entry rather than just the address field.
(I didn't bother trying to identify the commit which uncovered the issue in 5.14; the commit named below is the one which actually introduced the bad code.)
--- arch/x86/xen/enlighten.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
arch/x86/xen/enlighten.c +9 -6
@@ -872,8 +872,8 @@ static void xen_write_idt_entry(gate_despreempt_enable (); } -static void xen_convert_trap_info (const struct desc_ptr *desc, -struct trap_info *traps) +static unsigned xen_convert_trap_info (const struct desc_ptr *desc, +struct trap_info *traps,bool full) {unsigned in, out, count;
@@ -883,17 +883,18 @@ static void xen_convert_trap_info(constfor (in = out =0 ; in < count; in++) {gate_desc *entry = (gate_desc *)(desc->address) + in; -if (cvt_gate_to_trap (in, entry, &traps[out])) +if (cvt_gate_to_trap (in, entry, &traps[out]) || full) out++; } - traps[out].address =0 ; + +return out; }void xen_copy_trap_info (struct trap_info *traps) {const struct desc_ptr *desc =this_cpu_ptr (&idt_desc); -xen_convert_trap_info (desc, traps); +xen_convert_trap_info (desc, traps, true); }/* Load a new IDT into Xen. In principle this can be per-CPU, so we
@@ -903,6 +904,7 @@ static void xen_load_idt(const struct de {static DEFINE_SPINLOCK (lock);static struct trap_info traps[257 ]; +unsigned out;trace_xen_cpu_load_idt (desc);
@@ -910,7 +912,8 @@ static void xen_load_idt(const struct dememcpy (this_cpu_ptr (&idt_desc), desc,sizeof (idt_desc)); -xen_convert_trap_info (desc, traps); + out =xen_convert_trap_info (desc, traps, false); +memset (&traps[out],0 ,sizeof (traps[0 ]));xen_mc_flush ();if (HYPERVISOR_set_trap_table (traps))
Greg Kroah-Hartman
maintainerPATCH 6/57 usb-storage: Add quirk for ScanLogic SL11R-IDE older than 2.6c
In reply to Greg Kroah-HartmanFrom: Ondrej Zary <[email protected]>
commit b55d37ef6b7db3eda9b4495a8d9b0a944ee8c67d upstream.
ScanLogic SL11R-IDE with firmware older than 2.6c (the latest one) has broken tag handling, preventing the device from working at all:
usb 1-1: new full-speed USB device number 2 using uhci_hcd
usb 1-1: New USB device found, idVendor=04ce, idProduct=0002, bcdDevice= 2.60 usb 1-1: New USB device strings: Mfr=1, Product=1, SerialNumber=0 usb 1-1: Product: USB Device
usb 1-1: Manufacturer: USB Device
usb-storage 1-1:1.0: USB Mass Storage device detected
scsi host2: usb-storage 1-1:1.0
usbcore: registered new interface driver usb-storage
usb 1-1: reset full-speed USB device number 2 using uhci_hcd
usb 1-1: reset full-speed USB device number 2 using uhci_hcd
usb 1-1: reset full-speed USB device number 2 using uhci_hcd
usb 1-1: reset full-speed USB device number 2 using uhci_hcd
Add US_FL_BULK_IGNORE_TAG to fix it. Also update my e-mail address.
2.6c is the only firmware that claims Linux compatibility. The firmware can be upgraded using ezotgdbg utility:
https://github.com/asciilifeform/ezotgdbg
--- drivers/usb/storage/unusual_devs.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/usb/storage/unusual_devs.h +8 -1
@@ -435,9 +435,16 @@ UNUSUAL_DEV( 0x04cb, 0x0100, 0x0000, 0x USB_SC_UFI, USB_PR_DEVICE, NULL, US_FL_FIX_INQUIRY | US_FL_SINGLE_LUN),/* -* Reported by Ondrej Zary <[email protected]> +* Reported by Ondrej Zary <[email protected]> * The device reports one sector more and breaks when that sector is accessed +* Firmwares older than 2.6c (the latest one and the only that claims Linux +* support) have also broken tag handling */ +UNUSUAL_DEV (0x04ce ,0x0002 ,0x0000 ,0x026b , +"ScanLogic" , +"SL11R-IDE" , +USB_SC_DEVICE ,USB_PR_DEVICE ,NULL , +US_FL_FIX_CAPACITY |US_FL_BULK_IGNORE_TAG ), UNUSUAL_DEV( 0x04ce, 0x0002, 0x026c, 0x026c, "ScanLogic", "SL11R-IDE",
Greg Kroah-Hartman
maintainerPATCH 7/57 USB: serial: cp210x: add ID for GW Instek GDM-834x Digital Multimeter
In reply to Greg Kroah-HartmanFrom: Uwe Brandt <[email protected]>
commit 3bd18ba7d859eb1fbef3beb1e80c24f6f7d7596c upstream.
Add the USB serial device ID for the GW Instek GDM-834x Digital Multimeter.
--- drivers/usb/serial/cp210x.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/serial/cp210x.c +1 -0
@@ -231,6 +231,7 @@ static const struct usb_device_id id_tab { USB_DEVICE(0x1FB9, 0x0602) }, /* Lake Shore Model 648 Magnet Power Supply */ { USB_DEVICE(0x1FB9, 0x0700) }, /* Lake Shore Model 737 VSM Controller */ { USB_DEVICE(0x1FB9, 0x0701) }, /* Lake Shore Model 776 Hall Matrix */ + { USB_DEVICE(0x2184, 0x0030) }, /* GW Instek GDM-834x Digital Multimeter */ { USB_DEVICE(0x2626, 0xEA60) }, /* Aruba Networks 7xxx USB Serial Console */ { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */ { USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */
Greg Kroah-Hartman
maintainerPATCH 8/57 staging: greybus: uart: fix tty use after free
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 92dc0b1f46e12cfabd28d709bb34f7a39431b44f upstream.
User space can hold a tty open indefinitely and tty drivers must not release the underlying structures until the last user is gone.
Switch to using the tty-port reference counter to manage the life time of the greybus tty state to avoid use after free after a disconnect.
--- drivers/staging/greybus/uart.c | 62 +++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 30 deletions(-)
drivers/staging/greybus/uart.c +32 -30
@@ -812,6 +812,17 @@ out:gbphy_runtime_put_autosuspend (gb_tty->gbphy_dev); } +static void gb_tty_port_destruct (struct tty_port *port) +{ + struct gb_tty *gb_tty = container_of(port, struct gb_tty, port); + +if (gb_tty->minor !=GB_NUM_MINORS ) +release_minor (gb_tty); +kfifo_free (&gb_tty->write_fifo); +kfree (gb_tty->buffer); +kfree (gb_tty); +} +static const struct tty_operations gb_ops = { .install = gb_tty_install, .open = gb_tty_open,
@@ -834,6 +845,7 @@ static struct tty_port_operations gb_por .dtr_rts = gb_tty_dtr_rts, .activate = gb_tty_port_activate, .shutdown = gb_tty_port_shutdown, + .destruct = gb_tty_port_destruct, }; static int gb_uart_probe(struct gbphy_device *gbphy_dev,
@@ -846,17 +858,11 @@ static int gb_uart_probe(struct gbphy_deint retval;int minor; - gb_tty =kzalloc (sizeof (*gb_tty),GFP_KERNEL ); -if (!gb_tty) -return -ENOMEM ; - connection =gb_connection_create (gbphy_dev->bundle,le16_to_cpu (gbphy_dev->cport_desc->id), gb_uart_request_handler); -if (IS_ERR (connection)) { - retval =PTR_ERR (connection); - goto exit_tty_free; - } +if (IS_ERR (connection)) +return PTR_ERR (connection); max_payload =gb_operation_get_payload_size_max (connection);if (max_payload <sizeof (struct gb_uart_send_data_request )) {
@@ -864,13 +870,23 @@ static int gb_uart_probe(struct gbphy_de goto exit_connection_destroy; } + gb_tty =kzalloc (sizeof (*gb_tty),GFP_KERNEL ); +if (!gb_tty) { + retval = -ENOMEM ; + goto exit_connection_destroy; + } + +tty_port_init (&gb_tty->port); + gb_tty->port.ops = &gb_port_ops; + gb_tty->minor =GB_NUM_MINORS ; + gb_tty->buffer_payload_max = max_payload -sizeof (struct gb_uart_send_data_request ); gb_tty->buffer =kzalloc (gb_tty->buffer_payload_max,GFP_KERNEL );if (!gb_tty->buffer) { retval = -ENOMEM ; - goto exit_connection_destroy; + goto exit_put_port; }INIT_WORK (&gb_tty->tx_work, gb_uart_tx_write_work);
@@ -878,7 +894,7 @@ static int gb_uart_probe(struct gbphy_de retval =kfifo_alloc (&gb_tty->write_fifo,GB_UART_WRITE_FIFO_SIZE ,GFP_KERNEL );if (retval) - goto exit_buf_free; + goto exit_put_port; gb_tty->credits =GB_UART_FIRMWARE_CREDITS ;init_completion (&gb_tty->credits_complete);
@@ -892,7 +908,7 @@ static int gb_uart_probe(struct gbphy_de }else { retval = minor; } - goto exit_kfifo_free; + goto exit_put_port; } gb_tty->minor = minor;
@@ -901,9 +917,6 @@ static int gb_uart_probe(struct gbphy_deinit_waitqueue_head (&gb_tty->wioctl);mutex_init (&gb_tty->mutex); -tty_port_init (&gb_tty->port); - gb_tty->port.ops = &gb_port_ops; - gb_tty->connection = connection; gb_tty->gbphy_dev = gbphy_dev;gb_connection_set_data (connection, gb_tty);
@@ -911,7 +924,7 @@ static int gb_uart_probe(struct gbphy_de retval =gb_connection_enable_tx (connection);if (retval) - goto exit_release_minor; + goto exit_put_port;send_control (gb_tty, gb_tty->ctrlout);
@@ -938,16 +951,10 @@ static int gb_uart_probe(struct gbphy_de exit_connection_disable:gb_connection_disable (connection); -exit_release_minor: -release_minor (gb_tty); -exit_kfifo_free: -kfifo_free (&gb_tty->write_fifo); -exit_buf_free: -kfree (gb_tty->buffer); +exit_put_port: +tty_port_put (&gb_tty->port); exit_connection_destroy:gb_connection_destroy (connection); -exit_tty_free: -kfree (gb_tty);return retval; }
@@ -978,15 +985,10 @@ static void gb_uart_remove(struct gbphy_gb_connection_disable_rx (connection);tty_unregister_device (gb_tty_driver, gb_tty->minor); -/* FIXME - free transmit / receive buffers */ -gb_connection_disable (connection); -tty_port_destroy (&gb_tty->port);gb_connection_destroy (connection); -release_minor (gb_tty); -kfifo_free (&gb_tty->write_fifo); -kfree (gb_tty->buffer); -kfree (gb_tty); + +tty_port_put (&gb_tty->port); }static int gb_tty_init (void )
Greg Kroah-Hartman
maintainerPATCH 9/57 USB: serial: mos7840: remove duplicated 0xac24 device ID
In reply to Greg Kroah-HartmanFrom: Krzysztof Kozlowski <[email protected]>
commit 211f323768a25b30c106fd38f15a0f62c7c2b5f4 upstream.
0xac24 device ID is already defined and used via BANDB_DEVICE_ID_USO9ML2_4. Remove the duplicate from the list.
--- drivers/usb/serial/mos7840.c | 2 -- 1 file changed, 2 deletions(-)
drivers/usb/serial/mos7840.c +0 -2
@@ -126,7 +126,6 @@#define BANDB_DEVICE_ID_USOPTL4_2P 0xBC02#define BANDB_DEVICE_ID_USOPTL4_4 0xAC44#define BANDB_DEVICE_ID_USOPTL4_4P 0xBC03 -#define BANDB_DEVICE_ID_USOPTL2_4 0xAC24/* This driver also supports * ATEN UC2324 device using Moschip MCS7840
@@ -207,7 +206,6 @@ static const struct usb_device_id id_tab {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2P)}, {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4P)}, - {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL2_4)}, {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)}, {USB_DEVICE(USB_VENDOR_ID_MOXA, MOXA_DEVICE_ID_2210)},
Greg Kroah-Hartman
maintainerPATCH 10/57 USB: serial: option: add Telit LN920 compositions
In reply to Greg Kroah-HartmanFrom: Carlo Lobrano <[email protected]>
commit 7bb057134d609b9c038a00b6876cf0d37d0118ce upstream.
This patch adds the following Telit LN920 compositions:
0x1060: tty, adb, rmnet, tty, tty, tty, tty 0x1061: tty, adb, mbim, tty, tty, tty, tty 0x1062: rndis, tty, adb, tty, tty, tty, tty 0x1063: tty, adb, ecm, tty, tty, tty, tty
--- drivers/usb/serial/option.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/usb/serial/option.c +8 -0
@@ -1187,6 +1187,14 @@ static const struct usb_device_id option .driver_info = NCTRL(0) | RSVD(1) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1056, 0xff), /* Telit FD980 */ .driver_info = NCTRL(2) | RSVD(3) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1060, 0xff), /* Telit LN920 (rmnet) */ + .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1061, 0xff), /* Telit LN920 (MBIM) */ + .driver_info = NCTRL(0) | RSVD(1) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1062, 0xff), /* Telit LN920 (RNDIS) */ + .driver_info = NCTRL(2) | RSVD(3) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1063, 0xff), /* Telit LN920 (ECM) */ + .driver_info = NCTRL(0) | RSVD(1) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910), .driver_info = NCTRL(0) | RSVD(1) | RSVD(3) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM),
Greg Kroah-Hartman
maintainerPATCH 11/57 USB: serial: option: remove duplicate USB device ID
In reply to Greg Kroah-HartmanFrom: Krzysztof Kozlowski <[email protected]>
commit 1ca200a8c6f079950a04ea3c3380fe8cf78e95a2 upstream.
The device ZTE 0x0094 is already on the list.
--- drivers/usb/serial/option.c | 1 - 1 file changed, 1 deletion(-)
drivers/usb/serial/option.c +0 -1
@@ -1640,7 +1640,6 @@ static const struct usb_device_id option { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0060, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0094, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff), .driver_info = RSVD(1) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0133, 0xff, 0xff, 0xff),
Greg Kroah-Hartman
maintainerPATCH 12/57 USB: serial: option: add device id for Foxconn T99W265
In reply to Greg Kroah-HartmanFrom: Slark Xiao <[email protected]>
commit 9e3eed534f8235a4a596a9dae5b8a6425d81ea1a upstream.
Adding support for Foxconn device T99W265 for enumeration with PID 0xe0db.
usb-devices output for 0xe0db
T: Bus=04 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 19 Spd=5000 MxCh= 0 D: Ver= 3.20 Cls=ef(misc ) Sub=02 Prot=01 MxPS= 9 #Cfgs= 1 P: Vendor=0489 ProdID=e0db Rev=05.04 S: Manufacturer=Microsoft S: Product=Generic Mobile Broadband Adapter S: SerialNumber=6c50f452 C: #Ifs= 5 Cfg#= 1 Atr=a0 MxPwr=896mA I: If#=0x0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim I: If#=0x1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim I: If#=0x2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option I: If#=0x3 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) I: If#=0x4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option
if0/1: MBIM, if2:Diag, if3:GNSS, if4: Modem
--- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/serial/option.c +2 -0
@@ -2059,6 +2059,8 @@ static const struct usb_device_id option .driver_info = RSVD(0) | RSVD(1) | RSVD(6) }, { USB_DEVICE(0x0489, 0xe0b5), /* Foxconn T77W968 ESIM */ .driver_info = RSVD(0) | RSVD(1) | RSVD(6) }, + { USB_DEVICE_INTERFACE_CLASS(0x0489, 0xe0db, 0xff), /* Foxconn T99W265 MBIM */ + .driver_info = RSVD(3) }, { USB_DEVICE(0x1508, 0x1001), /* Fibocom NL668 (IOT version) */ .driver_info = RSVD(4) | RSVD(5) | RSVD(6) }, { USB_DEVICE(0x2cb7, 0x0104), /* Fibocom NL678 series */
Greg Kroah-Hartman
maintainerPATCH 13/57 mcb: fix error handling in mcb_alloc_bus()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
commit 25a1433216489de4abc889910f744e952cb6dbae upstream.
There are two bugs:
1) If ida_simple_get() fails then this code calls put_device(carrier) but we haven't yet called get_device(carrier) and probably that leads to a use after free.
2) After device_initialize() then we need to use put_device() to release the bus. This will free the internal resources tied to the device and call mcb_free_bus() which will free the rest.
--- drivers/mcb/mcb-core.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/mcb/mcb-core.c +6 -6
@@ -280,8 +280,8 @@ struct mcb_bus *mcb_alloc_bus(struct dev bus_nr =ida_simple_get (&mcb_ida,0 ,0 ,GFP_KERNEL );if (bus_nr <0 ) { - rc = bus_nr; - goto err_free; +kfree (bus); +return ERR_PTR (bus_nr); } bus->bus_nr = bus_nr;
@@ -296,12 +296,12 @@ struct mcb_bus *mcb_alloc_bus(struct devdev_set_name (&bus->dev,"mcb:%d" , bus_nr); rc =device_add (&bus->dev);if (rc) - goto err_free; + goto err_put;return bus; -err_free: -put_device (carrier); -kfree (bus); + +err_put: +put_device (&bus->dev);return ERR_PTR (rc); }EXPORT_SYMBOL_GPL (mcb_alloc_bus);
Greg Kroah-Hartman
maintainerPATCH 14/57 serial: mvebu-uart: fix drivers tx_empty callback
In reply to Greg Kroah-HartmanFrom: Pali Rohár <[email protected]>
commit 74e1eb3b4a1ef2e564b4bdeb6e92afe844e900de upstream.
Driver's tx_empty callback should signal when the transmit shift register is empty. So when the last character has been sent.
STAT_TX_FIFO_EMP bit signals only that HW transmit FIFO is empty, which happens when the last byte is loaded into transmit shift register.
STAT_TX_EMP bit signals when the both HW transmit FIFO and transmit shift register are empty.
So replace STAT_TX_FIFO_EMP check by STAT_TX_EMP in mvebu_uart_tx_empty() callback function.
--- drivers/tty/serial/mvebu-uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/tty/serial/mvebu-uart.c +1 -1
@@ -108,7 +108,7 @@ static unsigned int mvebu_uart_tx_empty( st =readl (port->membase +UART_STAT );spin_unlock_irqrestore (&port->lock, flags); -return (st &STAT_TX_FIFO_EMP ) ?TIOCSER_TEMT :0 ; +return (st &STAT_TX_EMP ) ?TIOCSER_TEMT :0 ; }static unsigned int mvebu_uart_get_mctrl (struct uart_port *port)
Greg Kroah-Hartman
maintainerPATCH 15/57 net: hso: fix muxed tty registration
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit e8f69b16ee776da88589b5271e3f46020efc8f6c upstream.
If resource allocation and registration fail for a muxed tty device (e.g. if there are no more minor numbers) the driver should not try to deregister the never-registered (or already-deregistered) tty.
Fix up the error handling to avoid dereferencing a NULL pointer when attempting to remove the character device.
--- drivers/net/usb/hso.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
drivers/net/usb/hso.c +5 -7
@@ -2715,14 +2715,14 @@ struct hso_device *hso_create_mux_serial serial =kzalloc (sizeof (*serial),GFP_KERNEL );if (!serial) - goto exit; + goto err_free_dev; hso_dev->port_data.dev_serial = serial; serial->parent = hso_dev;if (hso_serial_common_create (serial,1 ,CTRL_URB_RX_SIZE ,CTRL_URB_TX_SIZE )) - goto exit; + goto err_free_serial; serial->tx_data_length--; serial->write_data = hso_mux_serial_write_data;
@@ -2738,11 +2738,9 @@ struct hso_device *hso_create_mux_serial/* done, return it */ return hso_dev; -exit: -if (serial) { -tty_unregister_device (tty_drv, serial->minor); -kfree (serial); - } +err_free_serial: +kfree (serial); +err_free_dev:kfree (hso_dev);return NULL ;
Greg Kroah-Hartman
maintainerPATCH 16/57 net/mlx4_en: Dont allow aRFS for encapsulated packets
In reply to Greg Kroah-HartmanFrom: Aya Levin <[email protected]>
[ Upstream commit fdbccea419dc782079ce5881d2705cc9e3881480 ]
Driver doesn't support aRFS for encapsulated packets, return early error in such a case.
--- drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/ethernet/mellanox/mlx4/en_netdev.c +3 -0
@@ -309,6 +309,9 @@ mlx4_en_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb,int nhoff =skb_network_offset (skb);int ret =0 ; +if (skb->encapsulation) +return -EPROTONOSUPPORT ; +if (skb->protocol !=htons (ETH_P_IP ))return -EPROTONOSUPPORT ;
Signature · 1 line
2.33.0
Greg Kroah-Hartman
maintainerPATCH 17/57 scsi: iscsi: Adjust iface sysfs attr detection
In reply to Greg Kroah-HartmanFrom: Baokun Li <[email protected]>
[ Upstream commit 4e28550829258f7dab97383acaa477bd724c0ff4 ]
ISCSI_NET_PARAM_IFACE_ENABLE belongs to enum iscsi_net_param instead of iscsi_iface_param so move it to ISCSI_NET_PARAM. Otherwise, when we call into the driver, we might not match and return that we don't want attr visible in sysfs. Found in code review.
--- drivers/scsi/scsi_transport_iscsi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/scsi/scsi_transport_iscsi.c +4 -4
@@ -429,9 +429,7 @@ static umode_t iscsi_iface_attr_is_visible(struct kobject *kobj,struct iscsi_transport *t = iface->transport;int param =-1 ; -if (attr == &dev_attr_iface_enabled.attr) - param =ISCSI_NET_PARAM_IFACE_ENABLE ; -else if (attr == &dev_attr_iface_def_taskmgmt_tmo.attr) +if (attr == &dev_attr_iface_def_taskmgmt_tmo.attr) param =ISCSI_IFACE_PARAM_DEF_TASKMGMT_TMO ;else if (attr == &dev_attr_iface_header_digest.attr) param =ISCSI_IFACE_PARAM_HDRDGST_EN ;
@@ -471,7 +469,9 @@ static umode_t iscsi_iface_attr_is_visible(struct kobject *kobj,if (param !=-1 )return t->attr_is_visible (ISCSI_IFACE_PARAM , param); -if (attr == &dev_attr_iface_vlan_id.attr) +if (attr == &dev_attr_iface_enabled.attr) + param =ISCSI_NET_PARAM_IFACE_ENABLE ; +else if (attr == &dev_attr_iface_vlan_id.attr) param =ISCSI_NET_PARAM_VLAN_ID ;else if (attr == &dev_attr_iface_vlan_priority.attr) param =ISCSI_NET_PARAM_VLAN_PRIORITY ;
Signature · 1 line
2.33.0
Greg Kroah-Hartman
maintainerPATCH 18/57 blktrace: Fix uaf in blk_trace access after removing by sysfs
In reply to Greg Kroah-HartmanFrom: Zhihao Cheng <[email protected]>
[ Upstream commit 5afedf670caf30a2b5a52da96eb7eac7dee6a9c9 ]
There is an use-after-free problem triggered by following process:
P1(sda) P2(sdb)
echo 0 > /sys/block/sdb/trace/enable
blk_trace_remove_queue
synchronize_rcu blk_trace_free
relay_closercu_read_lock__blk_add_trace
trace_note_tsk
(Iterate running_trace_list)
relay_close_buf
relay_destroy_buf
kfree(buf)
trace_note(sdb's bt)
relay_reserve
buf->offset <- nullptr deference (use-after-free) !!!rcu_read_unlock
[ 502.714379] BUG: kernel NULL pointer dereference, address: 0000000000000010 [ 502.715260] #PF: supervisor read access in kernel mode [ 502.715903] #PF: error_code(0x0000) - not-present page [ 502.716546] PGD 103984067 P4D 103984067 PUD 17592b067 PMD 0 [ 502.717252] Oops: 0000 [#1] SMP [ 502.720308] RIP: 0010:trace_note.isra.0+0x86/0x360 [ 502.732872] Call Trace: [ 502.733193] __blk_add_trace.cold+0x137/0x1a3 [ 502.733734] blk_add_trace_rq+0x7b/0xd0 [ 502.734207] blk_add_trace_rq_issue+0x54/0xa0 [ 502.734755] blk_mq_start_request+0xde/0x1b0 [ 502.735287] scsi_queue_rq+0x528/0x1140 ... [ 502.742704] sg_new_write.isra.0+0x16e/0x3e0 [ 502.747501] sg_ioctl+0x466/0x1100
Reproduce method:
ioctl(/dev/sda, BLKTRACESETUP, blk_user_trace_setup[buf_size=127]) ioctl(/dev/sda, BLKTRACESTART)
ioctl(/dev/sdb, BLKTRACESETUP, blk_user_trace_setup[buf_size=127]) ioctl(/dev/sdb, BLKTRACESTART)
echo 0 > /sys/block/sdb/trace/enable &
// Add delay(mdelay/msleep) before kernel enters blk_trace_free()
ioctl$SG_IO(/dev/sda, SG_IO, ...)
// Enters trace_note_tsk() after blk_trace_free() returned // Use mdelay in rcu region rather than msleep(which may schedule out)
Remove blk_trace from running_list before calling blk_trace_free() by sysfs if blk_trace is at Blktrace_running state.
--- kernel/trace/blktrace.c | 8 ++++++++ 1 file changed, 8 insertions(+)
kernel/trace/blktrace.c +8 -0
@@ -1584,6 +1584,14 @@ static int blk_trace_remove_queue(struct request_queue *q)if (bt ==NULL )return -EINVAL ; +if (bt->trace_state == Blktrace_running) { + bt->trace_state = Blktrace_stopped; +spin_lock_irq (&running_trace_lock); +list_del_init (&bt->running_list); +spin_unlock_irq (&running_trace_lock); +relay_flush (bt->rchan); + } +put_probe_ref ();synchronize_rcu ();blk_trace_free (bt);
Signature · 1 line
2.33.0
Greg Kroah-Hartman
maintainerPATCH 19/57 net: stmmac: allow CSR clock of 300MHz
In reply to Greg Kroah-HartmanFrom: Jesper Nilsson <[email protected]>
[ Upstream commit 08dad2f4d541fcfe5e7bfda72cc6314bbfd2802f ]
The Synopsys Ethernet IP uses the CSR clock as a base clock for MDC. The divisor used is set in the MAC_MDIO_Address register field CR (Clock Rate)
The divisor is there to change the CSR clock into a clock that falls below the IEEE 802.3 specified max frequency of 2.5MHz.
If the CSR clock is 300MHz, the code falls back to using the reset value in the MAC_MDIO_Address register, as described in the comment above this code.
However, 300MHz is actually an allowed value and the proper divider can be estimated quite easily (it's just 1Hz difference!)
A CSR frequency of 300MHz with the maximum clock rate value of 0x5 (STMMAC_CSR_250_300M, a divisor of 124) gives somewhere around ~2.42MHz which is below the IEEE 802.3 specified maximum.
For the ARTPEC-8 SoC, the CSR clock is this problematic 300MHz, and unfortunately, the reset-value of the MAC_MDIO_Address CR field is 0x0.
This leads to a clock rate of zero and a divisor of 42, and gives an MDC frequency of ~7.14MHz.
Allow CSR clock of 300MHz by making the comparison inclusive.
--- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +1 -1
@@ -178,7 +178,7 @@ static void stmmac_clk_csr_set(struct stmmac_priv *priv) priv->clk_csr =STMMAC_CSR_100_150M ; else if ((clk_rate >= CSR_F_150M) && (clk_rate < CSR_F_250M)) priv->clk_csr = STMMAC_CSR_150_250M; - else if ((clk_rate >= CSR_F_250M) && (clk_rate < CSR_F_300M)) + else if ((clk_rate >= CSR_F_250M) && (clk_rate <= CSR_F_300M)) priv->clk_csr = STMMAC_CSR_250_300M; } }
Signature · 1 line
2.33.0
Greg Kroah-Hartman
maintainerPATCH 20/57 m68k: Double cast io functions to unsigned long
In reply to Greg Kroah-HartmanFrom: Guenter Roeck <[email protected]>
[ Upstream commit b1a89856fbf63fffde6a4771d8f1ac21df549e50 ]
m68k builds fail widely with errors such as
arch/m68k/include/asm/raw_io.h:20:19: error:
cast to pointer from integer of different sizearch/m68k/include/asm/raw_io.h:30:32: error:
cast to pointer from integer of different size [-Werror=int-to-p
On m68k, io functions are defined as macros. The problem is seen if the macro parameter variable size differs from the size of a pointer. Cast the parameter of all io macros to unsigned long before casting it to a pointer to fix the problem.
--- arch/m68k/include/asm/raw_io.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
arch/m68k/include/asm/raw_io.h +10 -10
@@ -30,21 +30,21 @@ extern void __iounmap(void *addr, unsigned long size);* two accesses to memory, which may be undesirable for some devices. */ #define in_8 (addr) \ - ({ u8 __v = (*(__force volatile u8 *) (addr)); __v; }) + ({ u8 __v = (*(__force volatile u8 *) (unsigned long)(addr)); __v; })#define in_be16 (addr) \ - ({ u16 __v = (*(__force volatile u16 *) (addr)); __v; }) + ({ u16 __v = (*(__force volatile u16 *) (unsigned long)(addr)); __v; })#define in_be32 (addr) \ - ({ u32 __v = (*(__force volatile u32 *) (addr)); __v; }) + ({ u32 __v = (*(__force volatile u32 *) (unsigned long)(addr)); __v; })#define in_le16 (addr) \ - ({ u16 __v = le16_to_cpu(*(__force volatile __le16 *) (addr)); __v; }) + ({ u16 __v = le16_to_cpu(*(__force volatile __le16 *) (unsigned long)(addr)); __v; })#define in_le32 (addr) \ - ({ u32 __v = le32_to_cpu(*(__force volatile __le32 *) (addr)); __v; }) + ({ u32 __v = le32_to_cpu(*(__force volatile __le32 *) (unsigned long)(addr)); __v; }) -#define out_8 (addr,b) (void)((*(__force volatile u8 *) (addr)) = (b)) -#define out_be16 (addr,w) (void)((*(__force volatile u16 *) (addr)) = (w)) -#define out_be32 (addr,l) (void)((*(__force volatile u32 *) (addr)) = (l)) -#define out_le16 (addr,w) (void)((*(__force volatile __le16 *) (addr)) = cpu_to_le16(w)) -#define out_le32 (addr,l) (void)((*(__force volatile __le32 *) (addr)) = cpu_to_le32(l)) +#define out_8 (addr,b) (void)((*(__force volatile u8 *) (unsigned long)(addr)) = (b)) +#define out_be16 (addr,w) (void)((*(__force volatile u16 *) (unsigned long)(addr)) = (w)) +#define out_be32 (addr,l) (void)((*(__force volatile u32 *) (unsigned long)(addr)) = (l)) +#define out_le16 (addr,w) (void)((*(__force volatile __le16 *) (unsigned long)(addr)) = cpu_to_le16(w)) +#define out_le32 (addr,l) (void)((*(__force volatile __le32 *) (unsigned long)(addr)) = cpu_to_le32(l))#define raw_inb in_8#define raw_inw in_be16
Signature · 1 line
2.33.0
Greg Kroah-Hartman
maintainerPATCH 21/57 compiler.h: Introduce absolute_pointer macro
In reply to Greg Kroah-HartmanFrom: Guenter Roeck <[email protected]>
[ Upstream commit f6b5f1a56987de837f8e25cd560847106b8632a8 ]
absolute_pointer() disassociates a pointer from its originating symbol type and context. Use it to prevent compiler warnings/errors such as
drivers/net/ethernet/i825xx/82596.c: In function 'i82596_probe':
arch/m68k/include/asm/string.h:72:25: error:
'__builtin_memcpy' reading 6 bytes from a region of size 0 [-Werror=stringop-overread]
Such warnings may be reported by gcc 11.x for string and memory operations on fixed addresses.
--- include/linux/compiler.h | 2 ++ 1 file changed, 2 insertions(+)
include/linux/compiler.h +2 -0
@@ -233,6 +233,8 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect); (typeof(ptr)) (__ptr + (off)); })#endif +#define absolute_pointer (val) RELOC_HIDE((void *)(val), 0) +#ifndef OPTIMIZER_HIDE_VAR #define OPTIMIZER_HIDE_VAR (var) barrier()#endif
Signature · 1 line
2.33.0
Greg Kroah-Hartman
maintainerPATCH 22/57 net: i825xx: Use absolute_pointer for memcpy from fixed memory location
In reply to Greg Kroah-HartmanFrom: Guenter Roeck <[email protected]>
[ Upstream commit dff2d13114f0beec448da9b3716204eb34b0cf41 ]
gcc 11.x reports the following compiler warning/error.
drivers/net/ethernet/i825xx/82596.c: In function 'i82596_probe':
arch/m68k/include/asm/string.h:72:25: error:
'__builtin_memcpy' reading 6 bytes from a region of size 0 [-Werror=stringop-overread]
Use absolute_pointer() to work around the problem.
--- drivers/net/ethernet/i825xx/82596.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/i825xx/82596.c +1 -1
@@ -1155,7 +1155,7 @@ struct net_device * __init i82596_probe(int unit) err = -ENODEV ; goto out; } -memcpy (eth_addr, (void *)0xfffc1f2c ,ETH_ALEN );/* YUCK! Get addr from NOVRAM */ +memcpy (eth_addr,absolute_pointer (0xfffc1f2c ),ETH_ALEN );/* YUCK! Get addr from NOVRAM */ dev->base_addr =MVME_I596_BASE ; dev->irq = (unsigned ) MVME16x_IRQ_I596; goto found;
Signature · 1 line
2.33.0
Greg Kroah-Hartman
maintainerPATCH 23/57 sparc: avoid stringop-overread errors
In reply to Greg Kroah-HartmanFrom: Linus Torvalds <[email protected]>
[ Upstream commit fc7c028dcdbfe981bca75d2a7b95f363eb691ef3 ]
The sparc mdesc code does pointer games with 'struct mdesc_hdr', but didn't describe to the compiler how that header is then followed by the data that the header describes.
As a result, gcc is now unhappy since it does stricter pointer range tracking, and doesn't understand about how these things work. This results in various errors like:
arch/sparc/kernel/mdesc.c: In function ‘mdesc_node_by_name’:
arch/sparc/kernel/mdesc.c:647:22: error: ‘strcmp’ reading 1 or more bytes from a region of size 0 [-Werror=stringop-overread]
647 | if (!strcmp(names + ep[ret].name_offset, name))
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
which are easily avoided by just describing 'struct mdesc_hdr' better, and making the node_block() helper function look into that unsized data[] that follows the header.
This makes the sparc64 build happy again at least for my cross-compiler version (gcc version 11.2.1).
--- arch/sparc/kernel/mdesc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/sparc/kernel/mdesc.c +2 -1
@@ -37,6 +37,7 @@ struct mdesc_hdr {u32 node_sz;/* node block size */ u32 name_sz;/* name block size */ u32 data_sz;/* data block size */ +char data[]; } __attribute__((aligned(16)));struct mdesc_elem {
@@ -369,7 +370,7 @@ out:static struct mdesc_elem *node_block (struct mdesc_hdr *mdesc) { -return (struct mdesc_elem *) (mdesc +1 ); +return (struct mdesc_elem *) mdesc->data; }static void *name_block (struct mdesc_hdr *mdesc)
Signature · 1 line
2.33.0
Greg Kroah-Hartman
maintainerPATCH 24/57 qnx4: avoid stringop-overread errors
In reply to Greg Kroah-HartmanFrom: Linus Torvalds <[email protected]>
[ Upstream commit b7213ffa0e585feb1aee3e7173e965e66ee0abaa ]
The qnx4 directory entries are 64-byte blocks that have different contents depending on the a status byte that is in the last byte of the block.
In particular, a directory entry can be either a "link info" entry with a 48-byte name and pointers to the real inode information, or an "inode entry" with a smaller 16-byte name and the full inode information.
But the code was written to always just treat the directory name as if it was part of that "inode entry", and just extend the name to the longer case if the status byte said it was a link entry.
That work just fine and gives the right results, but now that gcc is tracking data structure accesses much more, the code can trigger a compiler error about using up to 48 bytes (the long name) in a structure that only has that shorter name in it:
fs/qnx4/dir.c: In function ‘qnx4_readdir’:
fs/qnx4/dir.c:51:32: error: ‘strnlen’ specified bound 48 exceeds source size 16 [-Werror=stringop-overread]
51 | size = strnlen(de->di_fname, size);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from fs/qnx4/qnx4.h:3,
from fs/qnx4/dir.c:16:
include/uapi/linux/qnx4_fs.h:45:25: note: source object declared here
45 | char di_fname[QNX4_SHORT_NAME_MAX];
| ^~~~~~~~which is because the source code doesn't really make this whole "one of two different types" explicit.
Fix this by introducing a very explicit union of the two types, and basically explaining to the compiler what is really going on.
--- fs/qnx4/dir.c | 51 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 17 deletions(-)
fs/qnx4/dir.c +34 -17
@@ -14,13 +14,27 @@#include <linux/buffer_head.h> #include "qnx4.h" +/* +* A qnx4 directory entry is an inode entry or link info +* depending on the status field in the last byte. The +* first byte is where the name start either way, and a +* zero means it's empty. +*/ +union qnx4_directory_entry { +struct { +char de_name; +char de_pad[62 ]; +char de_status; + }; +struct qnx4_inode_entry inode; +struct qnx4_link_info link; +}; +static int qnx4_readdir (struct file *file,struct dir_context *ctx) {struct inode *inode =file_inode (file);unsigned int offset;struct buffer_head *bh; -struct qnx4_inode_entry *de; -struct qnx4_link_info *le;unsigned long blknum;int ix, ino;int size;
@@ -37,27 +51,30 @@ static int qnx4_readdir(struct file *file, struct dir_context *ctx) } ix = (ctx->pos >>QNX4_DIR_ENTRY_SIZE_BITS ) %QNX4_INODES_PER_BLOCK ;for (; ix <QNX4_INODES_PER_BLOCK ; ix++, ctx->pos +=QNX4_DIR_ENTRY_SIZE ) { +union qnx4_directory_entry *de; +const char *name; + offset = ix *QNX4_DIR_ENTRY_SIZE ; - de = (struct qnx4_inode_entry *) (bh->b_data + offset); -if (!de->di_fname[0 ]) + de = (union qnx4_directory_entry *) (bh->b_data + offset); + +if (!de->de_name)continue ; -if (!(de->di_status & (QNX4_FILE_USED |QNX4_FILE_LINK ))) +if (!(de->de_status & (QNX4_FILE_USED |QNX4_FILE_LINK )))continue ; -if (!(de->di_status &QNX4_FILE_LINK )) - size =QNX4_SHORT_NAME_MAX ; -else - size =QNX4_NAME_MAX ; - size =strnlen (de->di_fname, size); -QNX4DEBUG ((KERN_INFO "qnx4_readdir:%.*s\n" , size, de->di_fname)); -if (!(de->di_status &QNX4_FILE_LINK )) +if (!(de->de_status &QNX4_FILE_LINK )) { + size =sizeof (de->inode.di_fname); + name = de->inode.di_fname; ino = blknum *QNX4_INODES_PER_BLOCK + ix -1 ; -else { - le = (struct qnx4_link_info *)de; - ino = (le32_to_cpu (le->dl_inode_blk) -1 ) * + }else { + size =sizeof (de->link.dl_fname); + name = de->link.dl_fname; + ino = (le32_to_cpu (de->link.dl_inode_blk) -1 ) *QNX4_INODES_PER_BLOCK + - le->dl_inode_ndx; + de->link.dl_inode_ndx; } -if (!dir_emit (ctx, de->di_fname, size, ino,DT_UNKNOWN )) { + size =strnlen (name, size); +QNX4DEBUG ((KERN_INFO "qnx4_readdir:%.*s\n" , size, name)); +if (!dir_emit (ctx, name, size, ino,DT_UNKNOWN )) {brelse (bh);return 0 ; }
Signature · 1 line
2.33.0
Greg Kroah-Hartman
maintainerPATCH 25/57 parisc: Use absolute_pointer() to define PAGE0
In reply to Greg Kroah-HartmanFrom: Helge Deller <[email protected]>
[ Upstream commit 90cc7bed1ed19f869ae7221a6b41887fe762a6a3 ]
Use absolute_pointer() wrapper for PAGE0 to avoid this compiler warning:
arch/parisc/kernel/setup.c: In function 'start_parisc':
error: '__builtin_memcmp_eq' specified bound 8 exceeds source size 0
--- arch/parisc/include/asm/page.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/parisc/include/asm/page.h +1 -1
@@ -174,7 +174,7 @@ extern int npmem_ranges;#include <asm-generic/getorder.h> #include <asm/pdc.h> -#define PAGE0 ((struct zeropage *)__PAGE_OFFSET) +#define PAGE0 ((struct zeropage *)absolute_pointer(__PAGE_OFFSET))/* DEFINITION OF THE ZERO-PAGE (PAG0) */ /* based on work by Jason Eckhardt ([email protected]) */
Signature · 1 line
2.33.0
Greg Kroah-Hartman
maintainerPATCH 26/57 arm64: Mark __stack_chk_guard as __ro_after_init
In reply to Greg Kroah-HartmanFrom: Dan Li <[email protected]>
[ Upstream commit 9fcb2e93f41c07a400885325e7dbdfceba6efaec ]
__stack_chk_guard is setup once while init stage and never changed after that.
Although the modification of this variable at runtime will usually cause the kernel to crash (so does the attacker), it should be marked as __ro_after_init, and it should not affect performance if it is placed in the ro_after_init section.
--- arch/arm64/kernel/process.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/kernel/process.c +1 -1
@@ -57,7 +57,7 @@#ifdef CONFIG_CC_STACKPROTECTOR #include <linux/stackprotector.h> -unsigned long __stack_chk_guard__read_mostly ; +unsigned long __stack_chk_guard__ro_after_init ;EXPORT_SYMBOL (__stack_chk_guard);#endif
Signature · 1 line
2.33.0
Greg Kroah-Hartman
maintainerPATCH 27/57 alpha: Declare virt_to_phys and virt_to_bus parameter as pointer to volatile
In reply to Greg Kroah-HartmanFrom: Guenter Roeck <[email protected]>
[ Upstream commit 35a3f4ef0ab543daa1725b0c963eb8c05e3376f8 ]
Some drivers pass a pointer to volatile data to virt_to_bus() and virt_to_phys(), and that works fine. One exception is alpha. This results in a number of compile errors such as
drivers/net/wan/lmc/lmc_main.c: In function 'lmc_softreset':
drivers/net/wan/lmc/lmc_main.c:1782:50: error:
passing argument 1 of 'virt_to_bus' discards 'volatile' qualifier from pointer target type
drivers/atm/ambassador.c: In function 'do_loader_command':
drivers/atm/ambassador.c:1747:58: error:
passing argument 1 of 'virt_to_bus' discards 'volatile' qualifier from pointer target type
Declare the parameter of virt_to_phys and virt_to_bus as pointer to volatile to fix the problem.
--- arch/alpha/include/asm/io.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/alpha/include/asm/io.h +3 -3
@@ -60,7 +60,7 @@ extern inline void set_hae(unsigned long new_hae)* Change virtual addresses to physical addresses and vv. */ #ifdef USE_48_BIT_KSEG -static inline unsigned long virt_to_phys (void *address) +static inline unsigned long virt_to_phys (volatile void *address) {return (unsigned long )address -IDENT_ADDR ; }
@@ -70,7 +70,7 @@ static inline void * phys_to_virt(unsigned long address) return (void *) (address + IDENT_ADDR); }#else -static inline unsigned long virt_to_phys (void *address) +static inline unsigned long virt_to_phys (volatile void *address) {unsigned long phys = (unsigned long )address;
@@ -111,7 +111,7 @@ static inline dma_addr_t __deprecated isa_page_to_bus(struct page *page)extern unsigned long __direct_map_base;extern unsigned long __direct_map_size; -static inline unsigned long __deprecated virt_to_bus (void *address) +static inline unsigned long __deprecated virt_to_bus (volatile void *address) {unsigned long phys =virt_to_phys (address);unsigned long bus = phys + __direct_map_base;
Signature · 1 line
2.33.0
Greg Kroah-Hartman
maintainerPATCH 28/57 net: 6pack: Fix tx timeout and slot time
In reply to Greg Kroah-HartmanFrom: Guenter Roeck <[email protected]>
[ Upstream commit 3c0d2a46c0141913dc6fd126c57d0615677d946e ]
tx timeout and slot time are currently specified in units of HZ. On Alpha, HZ is defined as 1024. When building alpha:allmodconfig, this results in the following error message.
drivers/net/hamradio/6pack.c: In function 'sixpack_open':
drivers/net/hamradio/6pack.c:71:41: error:
unsigned conversion from 'int' to 'unsigned char' changes value from '256' to '0'
In the 6PACK protocol, tx timeout is specified in units of 10 ms and transmitted over the wire:
https://www.linux-ax25.org/wiki/6PACK
Defining a value dependent on HZ doesn't really make sense, and presumably comes from the (very historical) situation where HZ was originally 100.
Note that the SIXP_SLOTTIME use explicitly is about 10ms granularity:
mod_timer(&sp->tx_t, jiffies + ((when + 1) * HZ) / 100);
and the SIXP_TXDELAY walue is sent as a byte over the wire.
--- drivers/net/hamradio/6pack.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/hamradio/6pack.c +2 -2
@@ -68,9 +68,9 @@#define SIXP_DAMA_OFF 0/* default level 2 parameters */ -#define SIXP_TXDELAY (HZ/4)/* in 1 s */ +#define SIXP_TXDELAY 25/* 250 ms */ #define SIXP_PERSIST 50/* in 256ths */ -#define SIXP_SLOTTIME (HZ/10)/* in 1 s */ +#define SIXP_SLOTTIME 10/* 100 ms */ #define SIXP_INIT_RESYNC_TIMEOUT (3*HZ/2)/* in 1 s */ #define SIXP_RESYNC_TIMEOUT 5*HZ/* in 1 s */
Signature · 1 line
2.33.0
Greg Kroah-Hartman
maintainerPATCH 29/57 spi: Fix tegra20 build with CONFIG_PM=n
In reply to Greg Kroah-HartmanFrom: Linus Torvalds <[email protected]>
[ Upstream commit efafec27c5658ed987e720130772f8933c685e87 ]
Without CONFIG_PM enabled, the SET_RUNTIME_PM_OPS() macro ends up being empty, and the only use of tegra_slink_runtime_{resume,suspend} goes away, resulting in
drivers/spi/spi-tegra20-slink.c:1200:12: error: ‘tegra_slink_runtime_resume’ defined but not used [-Werror=unused-function]
1200 | static int tegra_slink_runtime_resume(struct device *dev)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/spi/spi-tegra20-slink.c:1188:12: error: ‘tegra_slink_runtime_suspend’ defined but not used [-Werror=unused-function]
1188 | static int tegra_slink_runtime_suspend(struct device *dev)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~mark the functions __maybe_unused to make the build happy.
This hits the alpha allmodconfig build (and others).
--- drivers/spi/spi-tegra20-slink.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/spi/spi-tegra20-slink.c +2 -2
@@ -1210,7 +1210,7 @@ static int tegra_slink_resume(struct device *dev) }#endif -static int tegra_slink_runtime_suspend (struct device *dev) +static int __maybe_unused tegra_slink_runtime_suspend (struct device *dev) {struct spi_master *master =dev_get_drvdata (dev);struct tegra_slink_data *tspi =spi_master_get_devdata (master);
@@ -1222,7 +1222,7 @@ static int tegra_slink_runtime_suspend(struct device *dev)return 0 ; } -static int tegra_slink_runtime_resume (struct device *dev) +static int __maybe_unused tegra_slink_runtime_resume (struct device *dev) {struct spi_master *master =dev_get_drvdata (dev);struct tegra_slink_data *tspi =spi_master_get_devdata (master);
Signature · 1 line
2.33.0
Greg Kroah-Hartman
maintainerPATCH 30/57 arm64: dts: marvell: armada-37xx: Extend PCIe MEM space
In reply to Greg Kroah-HartmanFrom: Pali Rohár <[email protected]>
commit 514ef1e62d6521c2199d192b1c71b79d2aa21d5a upstream.
Current PCIe MEM space of size 16 MB is not enough for some combination of PCIe cards (e.g. NVMe disk together with ath11k wifi card). ARM Trusted Firmware for Armada 3700 platform already assigns 128 MB for PCIe window, so extend PCIe MEM space to the end of 128 MB PCIe window which allows to allocate more PCIe BARs for more PCIe cards.
Without this change some combination of PCIe cards cannot be used and kernel show error messages in dmesg during initialization:
pci 0000:00:00.0: BAR 8: no space for [mem size 0x01800000]
pci 0000:00:00.0: BAR 8: failed to assign [mem size 0x01800000]
pci 0000:00:00.0: BAR 6: assigned [mem 0xe8000000-0xe80007ff pref]
pci 0000:01:00.0: BAR 8: no space for [mem size 0x01800000]
pci 0000:01:00.0: BAR 8: failed to assign [mem size 0x01800000]
pci 0000:02:03.0: BAR 8: no space for [mem size 0x01000000]
pci 0000:02:03.0: BAR 8: failed to assign [mem size 0x01000000]
pci 0000:02:07.0: BAR 8: no space for [mem size 0x00100000]
pci 0000:02:07.0: BAR 8: failed to assign [mem size 0x00100000]
pci 0000:03:00.0: BAR 0: no space for [mem size 0x01000000 64bit]
pci 0000:03:00.0: BAR 0: failed to assign [mem size 0x01000000 64bit]Due to bugs in U-Boot port for Turris Mox, the second range in Turris Mox kernel DTS file for PCIe must start at 16 MB offset. Otherwise U-Boot crashes during loading of kernel DTB file. This bug is present only in U-Boot code for Turris Mox and therefore other Armada 3700 devices are not affected by this bug. Bug is fixed in U-Boot version 2021.07.
To not break booting new kernels on existing versions of U-Boot on Turris Mox, use first 16 MB range for IO and second range with rest of PCIe window for MEM.
--- arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/marvell/armada-37xx.dtsi +9 -2
@@ -186,8 +186,15 @@ #interrupt-cells = <1>; msi-parent = <&pcie0>; msi-controller; - ranges = <0x82000000 0 0xe8000000 0 0xe8000000 0 0x1000000 /* Port 0 MEM */ - 0x81000000 0 0xe9000000 0 0xe9000000 0 0x10000>; /* Port 0 IO*/ + /* + * The 128 MiB address range [0xe8000000-0xf0000000] is + * dedicated for PCIe and can be assigned to 8 windows + * with size a power of two. Use one 64 KiB window for + * IO at the end and the remaining seven windows + * (totaling 127 MiB) for MEM. + */ + ranges = <0x82000000 0 0xe8000000 0 0xe8000000 0 0x07f00000 /* Port 0 MEM */ + 0x81000000 0 0xefff0000 0 0xefff0000 0 0x00010000>; /* Port 0 IO */ interrupt-map-mask = <0 0 0 7>; interrupt-map = <0 0 0 1 &pcie_intc 0>, <0 0 0 2 &pcie_intc 1>,
Greg Kroah-Hartman
maintainerPATCH 31/57 qnx4: work around gcc false positive warning bug
In reply to Greg Kroah-HartmanFrom: Linus Torvalds <[email protected]>
commit d5f6545934c47e97c0b48a645418e877b452a992 upstream.
In commit b7213ffa0e58 ("qnx4: avoid stringop-overread errors") I tried to teach gcc about how the directory entry structure can be two different things depending on a status flag. It made the code clearer, and it seemed to make gcc happy.
However, Arnd points to a gcc bug, where despite using two different members of a union, gcc then gets confused, and uses the size of one of the members to decide if a string overrun happens. And not necessarily the rigth one.
End result: with some configurations, gcc-11 will still complain about the source buffer size being overread:
fs/qnx4/dir.c: In function 'qnx4_readdir':
fs/qnx4/dir.c:76:32: error: 'strnlen' specified bound [16, 48] exceeds source size 1 [-Werror=stringop-overread]
76 | size = strnlen(name, size);
| ^~~~~~~~~~~~~~~~~~~
fs/qnx4/dir.c:26:22: note: source object declared here
26 | char de_name;
| ^~~~~~~because gcc will get confused about which union member entry is actually getting accessed, even when the source code is very clear about it. Gcc internally will have combined two "redundant" pointers (pointing to different union elements that are at the same offset), and takes the size checking from one or the other - not necessarily the right one.
This is clearly a gcc bug, but we can work around it fairly easily. The biggest thing here is the big honking comment about why we do what we do.
--- fs/qnx4/dir.c | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-)
fs/qnx4/dir.c +27 -9
@@ -19,12 +19,33 @@* depending on the status field in the last byte. The * first byte is where the name start either way, and a * zero means it's empty. +* +* Also, due to a bug in gcc, we don't want to use the +* real (differently sized) name arrays in the inode and +* link entries, but always the 'de_name[]' one in the +* fake struct entry. +* +* See +* +* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99578#c6 +* +* for details, but basically gcc will take the size of the +* 'name' array from one of the used union entries randomly. +* +* This use of 'de_name[]' (48 bytes) avoids the false positive +* warnings that would happen if gcc decides to use 'inode.di_name' +* (16 bytes) even when the pointer and size were to come from +* 'link.dl_name' (48 bytes). +* +* In all cases the actual name pointer itself is the same, it's +* only the gcc internal 'what is the size of this field' logic +* that can get confused. */ union qnx4_directory_entry {struct { -char de_name; -char de_pad[62 ]; -char de_status; +const char de_name[48 ]; +u8 de_pad[15 ]; +u8 de_status; };struct qnx4_inode_entry inode;struct qnx4_link_info link;
@@ -52,29 +73,26 @@ static int qnx4_readdir(struct file *fil ix = (ctx->pos >>QNX4_DIR_ENTRY_SIZE_BITS ) %QNX4_INODES_PER_BLOCK ;for (; ix <QNX4_INODES_PER_BLOCK ; ix++, ctx->pos +=QNX4_DIR_ENTRY_SIZE ) {union qnx4_directory_entry *de; -const char *name; offset = ix *QNX4_DIR_ENTRY_SIZE ; de = (union qnx4_directory_entry *) (bh->b_data + offset); -if (!de->de_name) +if (!de->de_name[0 ])continue ;if (!(de->de_status & (QNX4_FILE_USED |QNX4_FILE_LINK )))continue ;if (!(de->de_status &QNX4_FILE_LINK )) { size =sizeof (de->inode.di_fname); - name = de->inode.di_fname; ino = blknum *QNX4_INODES_PER_BLOCK + ix -1 ; }else { size =sizeof (de->link.dl_fname); - name = de->link.dl_fname; ino = (le32_to_cpu (de->link.dl_inode_blk) -1 ) *QNX4_INODES_PER_BLOCK + de->link.dl_inode_ndx; } - size =strnlen (name, size); + size =strnlen (de->de_name, size);QNX4DEBUG ((KERN_INFO "qnx4_readdir:%.*s\n" , size, name)); -if (!dir_emit (ctx, name, size, ino,DT_UNKNOWN )) { +if (!dir_emit (ctx, de->de_name, size, ino,DT_UNKNOWN )) {brelse (bh);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 32/57 tty: Fix out-of-bound vmalloc access in imageblit
In reply to Greg Kroah-HartmanFrom: Igor Matheus Andrade Torrente <[email protected]>
[ Upstream commit 3b0c406124719b625b1aba431659f5cdc24a982c ]
This issue happens when a userspace program does an ioctl FBIOPUT_VSCREENINFO passing the fb_var_screeninfo struct containing only the fields xres, yres, and bits_per_pixel with values.
If this struct is the same as the previous ioctl, the vc_resize() detects it and doesn't call the resize_screen(), leaving the fb_var_screeninfo incomplete. And this leads to the updatescrollmode() calculates a wrong value to fbcon_display->vrows, which makes the real_y() return a wrong value of y, and that value, eventually, causes the imageblit to access an out-of-bound address value.
To solve this issue I made the resize_screen() be called even if the screen does not need any resizing, so it will "fix and fill" the fb_var_screeninfo independently.
--- drivers/tty/vt/vt.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-)
drivers/tty/vt/vt.c +19 -2
@@ -886,8 +886,25 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc, new_row_size = new_cols <<1 ; new_screen_size = new_row_size * new_rows; -if (new_cols == vc->vc_cols && new_rows == vc->vc_rows) -return 0 ; +if (new_cols == vc->vc_cols && new_rows == vc->vc_rows) { +/* +* This function is being called here to cover the case +* where the userspace calls the FBIOPUT_VSCREENINFO twice, +* passing the same fb_var_screeninfo containing the fields +* yres/xres equal to a number non-multiple of vc_font.height +* and yres_virtual/xres_virtual equal to number lesser than the +* vc_font.height and yres/xres. +* In the second call, the struct fb_var_screeninfo isn't +* being modified by the underlying driver because of the +* if above, and this causes the fbcon_display->vrows to become +* negative and it eventually leads to out-of-bound +* access by the imageblit function. +* To give the correct values to the struct and to not have +* to deal with possible errors from the code below, we call +* the resize_screen here as well. +*/ +return resize_screen (vc, new_cols, new_rows, user); + }if (new_screen_size > (4 <<20 ) || !new_screen_size)return -EINVAL ;
Signature · 1 line
2.33.0
Greg Kroah-Hartman
maintainerPATCH 33/57 cpufreq: schedutil: Use kobject release() method to free sugov_tunables
In reply to Greg Kroah-HartmanFrom: Kevin Hao <[email protected]>
[ Upstream commit e5c6b312ce3cc97e90ea159446e6bfa06645364d ]
The struct sugov_tunables is protected by the kobject, so we can't free
it directly. Otherwise we would get a call trace like this:
ODEBUG: free active (active state 0) object type: timer_list hint: delayed_work_timer_fn+0x0/0x30
WARNING: CPU: 3 PID: 720 at lib/debugobjects.c:505 debug_print_object+0xb8/0x100 Modules linked in: CPU: 3 PID: 720 Comm: a.sh Tainted: G W 5.14.0-rc1-next-20210715-yocto-standard+ #507 Hardware name: Marvell OcteonTX CN96XX board (DT) pstate: 40400009 (nZcv daif +PAN -UAO -TCO BTYPE=--) pc : debug_print_object+0xb8/0x100 lr : debug_print_object+0xb8/0x100 sp : ffff80001ecaf910 x29: ffff80001ecaf910 x28: ffff00011b10b8d0 x27: ffff800011043d80 x26: ffff00011a8f0000 x25: ffff800013cb3ff0 x24: 0000000000000000 x23: ffff80001142aa68 x22: ffff800011043d80 x21: ffff00010de46f20 x20: ffff800013c0c520 x19: ffff800011d8f5b0 x18: 0000000000000010 x17: 6e6968207473696c x16: 5f72656d6974203a x15: 6570797420746365 x14: 6a626f2029302065 x13: 303378302f307830 x12: 2b6e665f72656d69 x11: ffff8000124b1560 x10: ffff800012331520 x9 : ffff8000100ca6b0 x8 : 000000000017ffe8 x7 : c0000000fffeffff x6 : 0000000000000001 x5 : ffff800011d8c000 x4 : ffff800011d8c740 x3 : 0000000000000000 x2 : ffff0001108301c0 x1 : ab3c90eedf9c0f00 x0 : 0000000000000000 Call trace: debug_print_object+0xb8/0x100 __debug_check_no_obj_freed+0x1c0/0x230 debug_check_no_obj_freed+0x20/0x88 slab_free_freelist_hook+0x154/0x1c8 kfree+0x114/0x5d0 sugov_exit+0xbc/0xc0 cpufreq_exit_governor+0x44/0x90 cpufreq_set_policy+0x268/0x4a8 store_scaling_governor+0xe0/0x128 store+0xc0/0xf0 sysfs_kf_write+0x54/0x80 kernfs_fop_write_iter+0x128/0x1c0 new_sync_write+0xf0/0x190 vfs_write+0x2d4/0x478 ksys_write+0x74/0x100 __arm64_sys_write+0x24/0x30 invoke_syscall.constprop.0+0x54/0xe0 do_el0_svc+0x64/0x158 el0_svc+0x2c/0xb0 el0t_64_sync_handler+0xb0/0xb8 el0t_64_sync+0x198/0x19c irq event stamp: 5518 hardirqs last enabled at (5517): [<ffff8000100cbd7c>] console_unlock+0x554/0x6c8 hardirqs last disabled at (5518): [<ffff800010fc0638>] el1_dbg+0x28/0xa0 softirqs last enabled at (5504): [<ffff8000100106e0>] __do_softirq+0x4d0/0x6c0 softirqs last disabled at (5483): [<ffff800010049548>] irq_exit+0x1b0/0x1b8
So split the original sugov_tunables_free() into two functions, sugov_clear_global_tunables() is just used to clear the global_tunables and the new sugov_tunables_free() is used as kobj_type::release to release the sugov_tunables safely.
--- kernel/sched/cpufreq_schedutil.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
kernel/sched/cpufreq_schedutil.c +11 -5
@@ -353,9 +353,17 @@ static struct attribute *sugov_attributes[] = {NULL }; +static void sugov_tunables_free (struct kobject *kobj) +{ + struct gov_attr_set *attr_set = container_of(kobj, struct gov_attr_set, kobj); + +kfree (to_sugov_tunables (attr_set)); +} +static struct kobj_type sugov_tunables_ktype = { .default_attrs = sugov_attributes, .sysfs_ops = &governor_sysfs_ops, + .release = &sugov_tunables_free, };/********************** cpufreq governor interface *********************/
@@ -397,12 +405,10 @@ static struct sugov_tunables *sugov_tunables_alloc(struct sugov_policy *sg_policreturn tunables; } -static void sugov_tunables_free (struct sugov_tunables *tunables) +static void sugov_clear_global_tunables (void ) {if (!have_governor_per_policy ()) global_tunables =NULL ; - -kfree (tunables); }static int sugov_init (struct cpufreq_policy *policy)
@@ -462,7 +468,7 @@ static int sugov_init(struct cpufreq_policy *policy) fail: policy->governor_data =NULL ; -sugov_tunables_free (tunables); +sugov_clear_global_tunables (); free_sg_policy:mutex_unlock (&global_tunables_lock);
@@ -485,7 +491,7 @@ static void sugov_exit(struct cpufreq_policy *policy) count =gov_attr_set_put (&tunables->attr_set, &sg_policy->tunables_hook); policy->governor_data =NULL ;if (!count) -sugov_tunables_free (tunables); +sugov_clear_global_tunables ();mutex_unlock (&global_tunables_lock);
Signature · 1 line
2.33.0
Greg Kroah-Hartman
maintainerPATCH 34/57 cpufreq: schedutil: Destroy mutex before kobject_put() frees the memory
In reply to Greg Kroah-HartmanFrom: James Morse <[email protected]>
[ Upstream commit cdef1196608892b9a46caa5f2b64095a7f0be60c ]
Since commit e5c6b312ce3c ("cpufreq: schedutil: Use kobject release() method to free sugov_tunables") kobject_put() has kfree()d the attr_set before gov_attr_set_put() returns.
kobject_put() isn't the last user of attr_set in gov_attr_set_put(), the subsequent mutex_destroy() triggers a use-after-free:
| BUG: KASAN: use-after-free in mutex_is_locked+0x20/0x60 | Read of size 8 at addr ffff000800ca4250 by task cpuhp/2/20 | | CPU: 2 PID: 20 Comm: cpuhp/2 Not tainted 5.15.0-rc1 #12369 | Hardware name: ARM LTD ARM Juno Development Platform/ARM Juno Development | Platform, BIOS EDK II Jul 30 2018 | Call trace: | dump_backtrace+0x0/0x380 | show_stack+0x1c/0x30 | dump_stack_lvl+0x8c/0xb8 | print_address_description.constprop.0+0x74/0x2b8 | kasan_report+0x1f4/0x210 | kasan_check_range+0xfc/0x1a4 | __kasan_check_read+0x38/0x60 | mutex_is_locked+0x20/0x60 | mutex_destroy+0x80/0x100 | gov_attr_set_put+0xfc/0x150 | sugov_exit+0x78/0x190 | cpufreq_offline.isra.0+0x2c0/0x660 | cpuhp_cpufreq_offline+0x14/0x24 | cpuhp_invoke_callback+0x430/0x6d0 | cpuhp_thread_fun+0x1b0/0x624 | smpboot_thread_fn+0x5e0/0xa6c | kthread+0x3a0/0x450 | ret_from_fork+0x10/0x20
Swap the order of the calls.
--- drivers/cpufreq/cpufreq_governor_attr_set.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/cpufreq/cpufreq_governor_attr_set.c +1 -1
@@ -77,8 +77,8 @@ unsigned int gov_attr_set_put(struct gov_attr_set *attr_set, struct list_head *lif (count)return count; -kobject_put (&attr_set->kobj);mutex_destroy (&attr_set->update_lock); +kobject_put (&attr_set->kobj);return 0 ; }EXPORT_SYMBOL_GPL (gov_attr_set_put);
Signature · 1 line
2.33.0
Greg Kroah-Hartman
maintainerPATCH 35/57 mac80211: fix use-after-free in CCMP/GCMP RX
In reply to Greg Kroah-HartmanFrom: Johannes Berg <[email protected]>
commit 94513069eb549737bcfc3d988d6ed4da948a2de8 upstream.
When PN checking is done in mac80211, for fragmentation we need to copy the PN to the RX struct so we can later use it to do a comparison, since commit bf30ca922a0c ("mac80211: check defrag PN against current frame").
Unfortunately, in that commit I used the 'hdr' variable without it being necessarily valid, so use-after-free could occur if it was necessary to reallocate (parts of) the frame.
Fix this by reloading the variable after the code that results in the reallocations, if any.
This fixes https://bugzilla.kernel.org/show_bug.cgi?id=214401.
--- net/mac80211/wpa.c | 6 ++++++ 1 file changed, 6 insertions(+)
net/mac80211/wpa.c +6 -0
@@ -514,6 +514,9 @@ ieee80211_crypto_ccmp_decrypt(struct ieereturn RX_DROP_UNUSABLE ; } +/* reload hdr - skb might have been reallocated */ + hdr = (void *)rx->skb->data; + data_len = skb->len - hdrlen -IEEE80211_CCMP_HDR_LEN - mic_len;if (!rx->sta || data_len <0 )return RX_DROP_UNUSABLE ;
@@ -744,6 +747,9 @@ ieee80211_crypto_gcmp_decrypt(struct ieereturn RX_DROP_UNUSABLE ; } +/* reload hdr - skb might have been reallocated */ + hdr = (void *)rx->skb->data; + data_len = skb->len - hdrlen -IEEE80211_GCMP_HDR_LEN - mic_len;if (!rx->sta || data_len <0 )return RX_DROP_UNUSABLE ;
Greg Kroah-Hartman
maintainerPATCH 36/57 ipvs: check that ip_vs_conn_tab_bits is between 8 and 20
In reply to Greg Kroah-HartmanFrom: Andrea Claudi <[email protected]>
[ Upstream commit 69e73dbfda14fbfe748d3812da1244cce2928dcb ]
ip_vs_conn_tab_bits may be provided by the user through the conn_tab_bits module parameter. If this value is greater than 31, or less than 0, the shift operator used to derive tab_size causes undefined behaviour.
Fix this checking ip_vs_conn_tab_bits value to be in the range specified in ipvs Kconfig. If not, simply use default value.
--- net/netfilter/ipvs/ip_vs_conn.c | 4 ++++ 1 file changed, 4 insertions(+)
net/netfilter/ipvs/ip_vs_conn.c +4 -0
@@ -1406,6 +1406,10 @@ int __init ip_vs_conn_init(void)int idx;/* Compute size and mask */ +if (ip_vs_conn_tab_bits <8 || ip_vs_conn_tab_bits >20 ) { +pr_info ("conn_tab_bits not in [8, 20]. Using default value\n" ); + ip_vs_conn_tab_bits =CONFIG_IP_VS_TAB_BITS ; + } ip_vs_conn_tab_size =1 << ip_vs_conn_tab_bits; ip_vs_conn_tab_mask = ip_vs_conn_tab_size -1 ;
Signature · 1 line
2.33.0
Greg Kroah-Hartman
maintainerPATCH 37/57 mac80211: limit injected vht mcs/nss in ieee80211_parse_tx_radiotap
In reply to Greg Kroah-HartmanFrom: Lorenzo Bianconi <[email protected]>
[ Upstream commit 13cb6d826e0ac0d144b0d48191ff1a111d32f0c6 ]
Limit max values for vht mcs and nss in ieee80211_parse_tx_radiotap routine in order to fix the following warning reported by syzbot:
WARNING: CPU: 0 PID: 10717 at include/net/mac80211.h:989 ieee80211_rate_set_vht include/net/mac80211.h:989 [inline] WARNING: CPU: 0 PID: 10717 at include/net/mac80211.h:989 ieee80211_parse_tx_radiotap+0x101e/0x12d0 net/mac80211/tx.c:2244 Modules linked in: CPU: 0 PID: 10717 Comm: syz-executor.5 Not tainted 5.14.0-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 RIP: 0010:ieee80211_rate_set_vht include/net/mac80211.h:989 [inline] RIP: 0010:ieee80211_parse_tx_radiotap+0x101e/0x12d0 net/mac80211/tx.c:2244 RSP: 0018:ffffc9000186f3e8 EFLAGS: 00010216 RAX: 0000000000000618 RBX: ffff88804ef76500 RCX: ffffc900143a5000 RDX: 0000000000040000 RSI: ffffffff888f478e RDI: 0000000000000003 RBP: 00000000ffffffff R08: 0000000000000000 R09: 0000000000000100 R10: ffffffff888f46f9 R11: 0000000000000000 R12: 00000000fffffff8 R13: ffff88804ef7653c R14: 0000000000000001 R15: 0000000000000004 FS: 00007fbf5718f700(0000) GS:ffff8880b9c00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000001b2de23000 CR3: 000000006a671000 CR4: 00000000001506f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000600 Call Trace: ieee80211_monitor_select_queue+0xa6/0x250 net/mac80211/iface.c:740 netdev_core_pick_tx+0x169/0x2e0 net/core/dev.c:4089 __dev_queue_xmit+0x6f9/0x3710 net/core/dev.c:4165 __bpf_tx_skb net/core/filter.c:2114 [inline] __bpf_redirect_no_mac net/core/filter.c:2139 [inline] __bpf_redirect+0x5ba/0xd20 net/core/filter.c:2162 ____bpf_clone_redirect net/core/filter.c:2429 [inline] bpf_clone_redirect+0x2ae/0x420 net/core/filter.c:2401 bpf_prog_eeb6f53a69e5c6a2+0x59/0x234 bpf_dispatcher_nop_func include/linux/bpf.h:717 [inline] __bpf_prog_run include/linux/filter.h:624 [inline] bpf_prog_run include/linux/filter.h:631 [inline] bpf_test_run+0x381/0xa30 net/bpf/test_run.c:119 bpf_prog_test_run_skb+0xb84/0x1ee0 net/bpf/test_run.c:663 bpf_prog_test_run kernel/bpf/syscall.c:3307 [inline] __sys_bpf+0x2137/0x5df0 kernel/bpf/syscall.c:4605 __do_sys_bpf kernel/bpf/syscall.c:4691 [inline] __se_sys_bpf kernel/bpf/syscall.c:4689 [inline] __x64_sys_bpf+0x75/0xb0 kernel/bpf/syscall.c:4689 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x44/0xae RIP: 0033:0x4665f9
--- net/mac80211/tx.c | 4 ++++ 1 file changed, 4 insertions(+)
net/mac80211/tx.c +4 -0
@@ -2064,7 +2064,11 @@ static bool ieee80211_parse_tx_radiotap(struct ieee80211_local *local, } vht_mcs = iterator.this_arg[4 ] >>4 ; +if (vht_mcs >11 ) + vht_mcs =0 ; vht_nss = iterator.this_arg[4 ] &0xF ; +if (!vht_nss || vht_nss >8 ) + vht_nss =1 ;break ;/*
Signature · 1 line
2.33.0
Greg Kroah-Hartman
maintainerPATCH 38/57 hwmon: (tmp421) fix rounding for negative values
In reply to Greg Kroah-HartmanFrom: Paul Fertser <[email protected]>
[ Upstream commit 724e8af85854c4d3401313b6dd7d79cf792d8990 ]
Old code produces -24999 for 0b1110011100000000 input in standard format due to always rounding up rather than "away from zero".
Use the common macro for division, unify and simplify the conversion code along the way.
--- drivers/hwmon/tmp421.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-)
drivers/hwmon/tmp421.c +8 -16
@@ -83,23 +83,17 @@ struct tmp421_data {s16 temp[4 ]; }; -static int temp_from_s16 (s16 reg) +static int temp_from_raw (u16 reg,bool extended) {/* Mask out status bits */ int temp = reg & ~0xf ; -return (temp *1000 +128 ) /256 ; -} - -static int temp_from_u16 (u16 reg) -{ -/* Mask out status bits */ -int temp = reg & ~0xf ; - -/* Add offset for extended temperature range. */ - temp -=64 *256 ; +if (extended) + temp = temp -64 *256 ; +else + temp = (s16 )temp; -return (temp *1000 +128 ) /256 ; +return DIV_ROUND_CLOSEST (temp *1000 ,256 ); }static struct tmp421_data *tmp421_update_device (struct device *dev)
@@ -136,10 +130,8 @@ static int tmp421_read(struct device *dev, enum hwmon_sensor_types type,switch (attr) {case hwmon_temp_input: -if (tmp421->config &TMP421_CONFIG_RANGE ) - *val =temp_from_u16 (tmp421->temp[channel]); -else - *val =temp_from_s16 (tmp421->temp[channel]); + *val =temp_from_raw (tmp421->temp[channel], + tmp421->config &TMP421_CONFIG_RANGE );return 0 ;case hwmon_temp_fault:/*
Signature · 1 line
2.33.0
Greg Kroah-Hartman
maintainerPATCH 39/57 e100: fix length calculation in e100_get_regs_len
In reply to Greg Kroah-HartmanFrom: Jacob Keller <[email protected]>
[ Upstream commit 4329c8dc110b25d5f04ed20c6821bb60deff279f ]
commit abf9b902059f ("e100: cleanup unneeded math") tried to simplify e100_get_regs_len and remove a double 'divide and then multiply' calculation that the e100_reg_regs_len function did.
This change broke the size calculation entirely as it failed to account for the fact that the numbered registers are actually 4 bytes wide and not 1 byte. This resulted in a significant under allocation of the register buffer used by e100_get_regs.
Fix this by properly multiplying the register count by u32 first before adding the size of the dump buffer.
--- drivers/net/ethernet/intel/e100.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/net/ethernet/intel/e100.c +5 -1
@@ -2466,7 +2466,11 @@ static void e100_get_drvinfo(struct net_device *netdev,static int e100_get_regs_len (struct net_device *netdev) {struct nic *nic =netdev_priv (netdev); -return 1 +E100_PHY_REGS +sizeof (nic->mem->dump_buf); + +/* We know the number of registers, and the size of the dump buffer. +* Calculate the total size in bytes. +*/ +return (1 +E100_PHY_REGS ) *sizeof (u32) +sizeof (nic->mem->dump_buf); } static void e100_get_regs(struct net_device *netdev,
Signature · 1 line
2.33.0
Greg Kroah-Hartman
maintainerPATCH 40/57 e100: fix buffer overrun in e100_get_regs
In reply to Greg Kroah-HartmanFrom: Jacob Keller <[email protected]>
[ Upstream commit 51032e6f17ce990d06123ad7307f258c50d25aa7 ]
The e100_get_regs function is used to implement a simple register dump for the e100 device. The data is broken into a couple of MAC control registers, and then a series of PHY registers, followed by a memory dump buffer.
The total length of the register dump is defined as (1 + E100_PHY_REGS)
* sizeof(u32) + sizeof(nic->mem->dump_buf).
The logic for filling in the PHY registers uses a convoluted inverted count for loop which counts from E100_PHY_REGS (0x1C) down to 0, and assigns the slots 1 + E100_PHY_REGS - i. The first loop iteration will fill in [1] and the final loop iteration will fill in [1 + 0x1C]. This is actually one more than the supposed number of PHY registers.
The memory dump buffer is then filled into the space at
[2 + E100_PHY_REGS] which will cause that memcpy to assign 4 bytes past the total size.
The end result is that we overrun the total buffer size allocated by the kernel, which could lead to a panic or other issues due to memory corruption.
It is difficult to determine the actual total number of registers here. The only 8255x datasheet I could find indicates there are 28 total MDI registers. However, we're reading 29 here, and reading them in reverse!
In addition, the ethtool e100 register dump interface appears to read the first PHY register to determine if the device is in MDI or MDIx mode. This doesn't appear to be documented anywhere within the 8255x datasheet. I can only assume it must be in register 28 (the extra register we're reading here).
Lets not change any of the intended meaning of what we copy here. Just extend the space by 4 bytes to account for the extra register and continue copying the data out in the same order.
Change the E100_PHY_REGS value to be the correct total (29) so that the total register dump size is calculated properly. Fix the offset for where we copy the dump buffer so that it doesn't overrun the total size.
Re-write the for loop to use counting up instead of the convoluted down-counting. Correct the mdio_read offset to use the 0-based register offsets, but maintain the bizarre reverse ordering so that we have the ABI expected by applications like ethtool. This requires and additional subtraction of 1. It seems a bit odd but it makes the flow of assignment into the register buffer easier to follow.
--- drivers/net/ethernet/intel/e100.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
drivers/net/ethernet/intel/e100.c +10 -6
@@ -2462,7 +2462,7 @@ static void e100_get_drvinfo(struct net_device *netdev, sizeof(info->bus_info)); } -#define E100_PHY_REGS 0x1C +#define E100_PHY_REGS 0x1Dstatic int e100_get_regs_len (struct net_device *netdev) {struct nic *nic =netdev_priv (netdev);
@@ -2484,14 +2484,18 @@ static void e100_get_regs(struct net_device *netdev, buff[0 ] =ioread8 (&nic->csr->scb.cmd_hi) <<24 |ioread8 (&nic->csr->scb.cmd_lo) <<16 |ioread16 (&nic->csr->scb.status); -for (i =E100_PHY_REGS ; i >=0 ; i--) - buff[1 +E100_PHY_REGS - i] = -mdio_read (netdev, nic->mii.phy_id, i); +for (i =0 ; i <E100_PHY_REGS ; i++) +/* Note that we read the registers in reverse order. This +* ordering is the ABI apparently used by ethtool and other +* applications. +*/ + buff[1 + i] =mdio_read (netdev, nic->mii.phy_id, +E100_PHY_REGS -1 - i);memset (nic->mem->dump_buf,0 ,sizeof (nic->mem->dump_buf));e100_exec_cb (nic,NULL , e100_dump);msleep (10 ); -memcpy (&buff[2 +E100_PHY_REGS ], nic->mem->dump_buf, -sizeof (nic->mem->dump_buf)); +memcpy (&buff[1 +E100_PHY_REGS ], nic->mem->dump_buf, +sizeof (nic->mem->dump_buf)); }static void e100_get_wol (struct net_device *netdev,struct ethtool_wolinfo *wol)
Signature · 1 line
2.33.0
Greg Kroah-Hartman
maintainerPATCH 41/57 ipack: ipoctal: fix stack information leak
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit a89936cce87d60766a75732a9e7e25c51164f47c upstream.
The tty driver name is used also after registering the driver and must specifically not be allocated on the stack to avoid leaking information to user space (or triggering an oops).
Drivers should not try to encode topology information in the tty device name but this one snuck in through staging without anyone noticing and another driver has since copied this malpractice.
Fixing the ABI is a separate issue, but this at least plugs the security hole.
--- drivers/ipack/devices/ipoctal.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)
drivers/ipack/devices/ipoctal.c +14 -5
@@ -269,7 +269,6 @@ static int ipoctal_inst_slot(struct ipocint res;int i;struct tty_driver *tty; -char name[20 ];struct ipoctal_channel *channel;struct ipack_region *region;void __iomem *addr;
@@ -360,8 +359,11 @@ static int ipoctal_inst_slot(struct ipoc/* Fill struct tty_driver with ipoctal data */ tty->owner =THIS_MODULE ; tty->driver_name =KBUILD_MODNAME ; -sprintf (name,KBUILD_MODNAME ".%d.%d." , bus_nr, slot); - tty->name = name; + tty->name =kasprintf (GFP_KERNEL ,KBUILD_MODNAME ".%d.%d." , bus_nr, slot); +if (!tty->name) { + res = -ENOMEM ; + goto err_put_driver; + } tty->major =0 ; tty->minor_start =0 ;
@@ -377,8 +379,7 @@ static int ipoctal_inst_slot(struct ipoc res =tty_register_driver (tty);if (res) {dev_err (&ipoctal->dev->dev,"Can't register tty driver.\n" ); -put_tty_driver (tty); -return res; + goto err_free_name; }/* Save struct tty_driver for use it when uninstalling the device */
@@ -415,6 +416,13 @@ static int ipoctal_inst_slot(struct ipoc ipoctal_irq_handler, ipoctal);return 0 ; + +err_free_name: +kfree (tty->name); +err_put_driver: +put_tty_driver (tty); + +return res; } static inline int ipoctal_copy_write_buffer(struct ipoctal_channel *channel,
@@ -703,6 +711,7 @@ static void __ipoctal_remove(struct ipoc }tty_unregister_driver (ipoctal->tty_drv); +kfree (ipoctal->tty_drv->name);put_tty_driver (ipoctal->tty_drv);kfree (ipoctal); }
Greg Kroah-Hartman
maintainerPATCH 42/57 ipack: ipoctal: fix tty registration race
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 65c001df517a7bf9be8621b53d43c89f426ce8d6 upstream.
Make sure to set the tty class-device driver data before registering the tty to avoid having a racing open() dereference a NULL pointer.
--- drivers/ipack/devices/ipoctal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/ipack/devices/ipoctal.c +2 -2
@@ -398,13 +398,13 @@ static int ipoctal_inst_slot(struct ipocspin_lock_init (&channel->lock); channel->pointer_read =0 ; channel->pointer_write =0 ; - tty_dev =tty_port_register_device (&channel->tty_port, tty, i,NULL ); + tty_dev =tty_port_register_device_attr (&channel->tty_port, tty, + i,NULL , channel,NULL );if (IS_ERR (tty_dev)) {dev_err (&ipoctal->dev->dev,"Failed to register tty device.\n" );tty_port_destroy (&channel->tty_port);continue ; } -dev_set_drvdata (tty_dev, channel); }/*
Greg Kroah-Hartman
maintainerPATCH 43/57 ipack: ipoctal: fix tty-registration error handling
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit cd20d59291d1790dc74248476e928f57fc455189 upstream.
Registration of the ipoctal tty devices is unlikely to fail, but if it ever does, make sure not to deregister a never registered tty device (and dereference a NULL pointer) when the driver is later unbound.
--- drivers/ipack/devices/ipoctal.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/ipack/devices/ipoctal.c +7 -0
@@ -38,6 +38,7 @@ struct ipoctal_channel {unsigned int pointer_read;unsigned int pointer_write;struct tty_port tty_port; +bool tty_registered;union scc2698_channel __iomem *regs;union scc2698_block __iomem *block_regs;unsigned int board_id;
@@ -402,9 +403,11 @@ static int ipoctal_inst_slot(struct ipoc i, NULL, channel, NULL);if (IS_ERR (tty_dev)) {dev_err (&ipoctal->dev->dev,"Failed to register tty device.\n" ); +tty_port_free_xmit_buf (&channel->tty_port);tty_port_destroy (&channel->tty_port);continue ; } + channel->tty_registered = true; }/*
@@ -705,6 +708,10 @@ static void __ipoctal_remove(struct ipocfor (i =0 ; i <NR_CHANNELS ; i++) {struct ipoctal_channel *channel = &ipoctal->channel[i]; + +if (!channel->tty_registered) +continue ; +tty_unregister_device (ipoctal->tty_drv, i);tty_port_free_xmit_buf (&channel->tty_port);tty_port_destroy (&channel->tty_port);
Greg Kroah-Hartman
maintainerPATCH 44/57 ipack: ipoctal: fix missing allocation-failure check
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 445c8132727728dc297492a7d9fc074af3e94ba3 upstream.
Add the missing error handling when allocating the transmit buffer to avoid dereferencing a NULL pointer in write() should the allocation ever fail.
--- drivers/ipack/devices/ipoctal.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/ipack/devices/ipoctal.c +3 -1
@@ -391,7 +391,9 @@ static int ipoctal_inst_slot(struct ipoc channel = &ipoctal->channel[i];tty_port_init (&channel->tty_port); -tty_port_alloc_xmit_buf (&channel->tty_port); + res =tty_port_alloc_xmit_buf (&channel->tty_port); +if (res) +continue ; channel->tty_port.ops = &ipoctal_tty_port_ops;ipoctal_reset_stats (&channel->stats);
Greg Kroah-Hartman
maintainerPATCH 45/57 ipack: ipoctal: fix module reference leak
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit bb8a4fcb2136508224c596a7e665bdba1d7c3c27 upstream.
A reference to the carrier module was taken on every open but was only released once when the final reference to the tty struct was dropped.
Fix this by taking the module reference and initialising the tty driver data when installing the tty.
--- drivers/ipack/devices/ipoctal.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-)
drivers/ipack/devices/ipoctal.c +21 -8
@@ -87,22 +87,34 @@ static int ipoctal_port_activate(structreturn 0 ; } -static int ipoctal_open (struct tty_struct *tty,struct file *file) +static int ipoctal_install (struct tty_driver *driver,struct tty_struct *tty) {struct ipoctal_channel *channel =dev_get_drvdata (tty->dev);struct ipoctal *ipoctal =chan_to_ipoctal (channel, tty->index); -int err; - - tty->driver_data = channel; +int res;if (!ipack_get_carrier (ipoctal->dev))return -EBUSY ; - err =tty_port_open (&channel->tty_port, tty, file); -if (err) -ipack_put_carrier (ipoctal->dev); + res =tty_standard_install (driver, tty); +if (res) + goto err_put_carrier; + + tty->driver_data = channel; + +return 0 ; + +err_put_carrier: +ipack_put_carrier (ipoctal->dev); + +return res; +} + +static int ipoctal_open (struct tty_struct *tty,struct file *file) +{ +struct ipoctal_channel *channel = tty->driver_data; -return err; +return tty_port_open (&channel->tty_port, tty, file); }static void ipoctal_reset_stats (struct ipoctal_stats *stats)
@@ -668,6 +680,7 @@ static void ipoctal_cleanup(struct tty_sstatic const struct tty_operations ipoctal_fops = { .ioctl =NULL , + .install = ipoctal_install, .open = ipoctal_open, .close = ipoctal_close, .write = ipoctal_write_tty,
Greg Kroah-Hartman
maintainerPATCH 46/57 ext4: fix potential infinite loop in ext4_dx_readdir()
In reply to Greg Kroah-HartmanFrom: yangerkun <[email protected]>
commit 42cb447410d024e9d54139ae9c21ea132a8c384c upstream.
When ext4_htree_fill_tree() fails, ext4_dx_readdir() can run into an infinite loop since if info->last_pos != ctx->pos this will reset the directory scan and reread the failing entry. For example:
1. a dx_dir which has 3 block, block 0 as dx_root block, block 1/2 as leaf block which own the ext4_dir_entry_2
2. block 1 read ok and call_filldir which will fill the dirent and update the ctx->pos
3. block 2 read fail, but we has already fill some dirent, so we will return back to userspace will a positive return val(see ksys_getdents64)
4. the second ext4_dx_readdir will reset the world since info->last_pos != ctx->pos, and will also init the curr_hash which pos to block 1
5. So we will read block1 too, and once block2 still read fail, we can only fill one dirent because the hash of the entry in block1(besides the last one) won't greater than curr_hash
6. this time, we forget update last_pos too since the read for block2 will fail, and since we has got the one entry, ksys_getdents64 can return success
7. Latter we will trapped in a loop with step 4~6
--- fs/ext4/dir.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
fs/ext4/dir.c +3 -3
@@ -531,7 +531,7 @@ static int ext4_dx_readdir(struct file *struct dir_private_info *info = file->private_data;struct inode *inode =file_inode (file);struct fname *fname; -int ret; +int ret =0 ;if (!info) { info =ext4_htree_create_dir_info (file, ctx->pos);
@@ -579,7 +579,7 @@ static int ext4_dx_readdir(struct file * info->curr_minor_hash, &info->next_hash);if (ret <0 ) -return ret; + goto finished;if (ret ==0 ) { ctx->pos =ext4_get_htree_eof (file);break ;
@@ -610,7 +610,7 @@ static int ext4_dx_readdir(struct file * } finished: info->last_pos = ctx->pos; -return 0 ; +return ret <0 ? ret :0 ; }static int ext4_dir_open (struct inode * inode,struct file * filp)
Greg Kroah-Hartman
maintainerPATCH 47/57 net: udp: annotate data race around udp_sk(sk)->corkflag
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
commit a9f5970767d11eadc805d5283f202612c7ba1f59 upstream.
up->corkflag field can be read or written without any lock. Annotate accesses to avoid possible syzbot/KCSAN reports.
--- net/ipv4/udp.c | 10 +++++----- net/ipv6/udp.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-)
net/ipv4/udp.c +5 -5
@@ -886,7 +886,7 @@ int udp_sendmsg(struct sock *sk, struct__be16 dport;u8 tos;int err, is_udplite =IS_UDPLITE (sk); -int corkreq = up->corkflag || msg->msg_flags&MSG_MORE ; +int corkreq =READ_ONCE (up->corkflag) || msg->msg_flags&MSG_MORE ;int (*getfrag)(void *,char *,int ,int ,int ,struct sk_buff *);struct sk_buff *skb;struct ip_options_data opt_copy;
@@ -1167,7 +1167,7 @@ int udp_sendpage(struct sock *sk, struct } up->len += size; -if (!(up->corkflag || (flags&MSG_MORE ))) +if (!(READ_ONCE (up->corkflag) || (flags&MSG_MORE ))) ret =udp_push_pending_frames (sk);if (!ret) ret = size;
@@ -2034,9 +2034,9 @@ int udp_lib_setsockopt(struct sock *sk,switch (optname) {case UDP_CORK :if (val !=0 ) { - up->corkflag =1 ; +WRITE_ONCE (up->corkflag,1 ); }else { - up->corkflag =0 ; +WRITE_ONCE (up->corkflag,0 );lock_sock (sk);push_pending_frames (sk);release_sock (sk);
@@ -2143,7 +2143,7 @@ int udp_lib_getsockopt(struct sock *sk,switch (optname) {case UDP_CORK : - val = up->corkflag; + val =READ_ONCE (up->corkflag);break ;case UDP_ENCAP :
net/ipv6/udp.c +1 -1
@@ -1028,7 +1028,7 @@ int udpv6_sendmsg(struct sock *sk, strucstruct ipcm6_cookie ipc6;int addr_len = msg->msg_namelen;int ulen = len; -int corkreq = up->corkflag || msg->msg_flags&MSG_MORE ; +int corkreq =READ_ONCE (up->corkflag) || msg->msg_flags&MSG_MORE ;int err;int connected =0 ;int is_udplite =IS_UDPLITE (sk);
Greg Kroah-Hartman
maintainerPATCH 48/57 EDAC/synopsys: Fix wrong value type assignment for edac_mode
In reply to Greg Kroah-HartmanFrom: Sai Krishna Potthuri <[email protected]>
commit 5297cfa6bdf93e3889f78f9b482e2a595a376083 upstream.
dimm->edac_mode contains values of type enum edac_type - not the corresponding capability flags. Fix that.
Issue caught by Coverity check "enumerated type mixed with another type."
[ bp: Rewrite commit message, add tags. ]
--- drivers/edac/synopsys_edac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/edac/synopsys_edac.c +1 -1
@@ -371,7 +371,7 @@ static int synps_edac_init_csrows(structfor (j =0 ; j < csi->nr_channels; j++) { dimm = csi->channels[j]->dimm; - dimm->edac_mode =EDAC_FLAG_SECDED ; + dimm->edac_mode =EDAC_SECDED ; dimm->mtype =synps_edac_get_mtype (priv->baseaddr); dimm->nr_pages = (size >>PAGE_SHIFT ) / csi->nr_channels; dimm->grain =SYNPS_EDAC_ERR_GRAIN ;
Greg Kroah-Hartman
maintainerPATCH 49/57 ARM: 9077/1: PLT: Move struct plt_entries definition to header
In reply to Greg Kroah-HartmanFrom: Alex Sverdlin <[email protected]>
commit 4e271701c17dee70c6e1351c4d7d42e70405c6a9 upstream
No functional change, later it will be re-used in several files.
--- arch/arm/include/asm/module.h | 9 +++++++++ arch/arm/kernel/module-plts.c | 9 --------- 2 files changed, 9 insertions(+), 9 deletions(-)
arch/arm/include/asm/module.h +9 -0
@@ -18,6 +18,15 @@ enum { };#endif +#define PLT_ENT_STRIDE L1_CACHE_BYTES +#define PLT_ENT_COUNT (PLT_ENT_STRIDE / sizeof(u32)) +#define PLT_ENT_SIZE (sizeof(struct plt_entries) / PLT_ENT_COUNT) + +struct plt_entries { +u32 ldr[PLT_ENT_COUNT ]; +u32 lit[PLT_ENT_COUNT ]; +}; +struct mod_plt_sec {struct elf32_shdr *plt;int plt_count;
arch/arm/kernel/module-plts.c +0 -9
@@ -14,10 +14,6 @@#include <asm/cache.h> #include <asm/opcodes.h> -#define PLT_ENT_STRIDE L1_CACHE_BYTES -#define PLT_ENT_COUNT (PLT_ENT_STRIDE / sizeof(u32)) -#define PLT_ENT_SIZE (sizeof(struct plt_entries) / PLT_ENT_COUNT) -#ifdef CONFIG_THUMB2_KERNEL #define PLT_ENT_LDR __opcode_to_mem_thumb32(0xf8dff000 | \ (PLT_ENT_STRIDE - 4))
@@ -26,11 +22,6 @@ (PLT_ENT_STRIDE - 8))#endif -struct plt_entries { -u32 ldr[PLT_ENT_COUNT ]; -u32 lit[PLT_ENT_COUNT ]; -}; -static bool in_init (const struct module *mod,unsigned long loc) {return loc - (u32 )mod->init_layout.base < mod->init_layout.size;
Greg Kroah-Hartman
maintainerPATCH 50/57 ARM: 9078/1: Add warn suppress parameter to arm_gen_branch_link()
In reply to Greg Kroah-HartmanFrom: Alex Sverdlin <[email protected]>
commit 890cb057a46d323fd8c77ebecb6485476614cd21 upstream
Will be used in the following patch. No functional change.
--- arch/arm/include/asm/insn.h | 8 ++++---- arch/arm/kernel/ftrace.c | 2 +- arch/arm/kernel/insn.c | 19 ++++++++++--------- 3 files changed, 15 insertions(+), 14 deletions(-)
arch/arm/include/asm/insn.h +4 -4
@@ -12,18 +12,18 @@ arm_gen_nop(void) }unsigned long -__arm_gen_branch (unsigned long pc,unsigned long addr,bool link); +__arm_gen_branch (unsigned long pc,unsigned long addr,bool link,bool warn);static inline unsigned long arm_gen_branch (unsigned long pc,unsigned long addr) { -return __arm_gen_branch (pc, addr, false); +return __arm_gen_branch (pc, addr, false, true); }static inline unsigned long -arm_gen_branch_link (unsigned long pc,unsigned long addr) +arm_gen_branch_link (unsigned long pc,unsigned long addr,bool warn) { -return __arm_gen_branch (pc, addr, true); +return __arm_gen_branch (pc, addr, true, warn); }#endif
arch/arm/kernel/ftrace.c +1 -1
@@ -97,7 +97,7 @@ int ftrace_arch_code_modify_post_processstatic unsigned long ftrace_call_replace (unsigned long pc,unsigned long addr) { -return arm_gen_branch_link (pc, addr); +return arm_gen_branch_link (pc, addr, true); } static int ftrace_modify_code(unsigned long pc, unsigned long old,
arch/arm/kernel/insn.c +10 -9
@@ -2,8 +2,9 @@#include <linux/kernel.h> #include <asm/opcodes.h> -static unsigned long -__arm_gen_branch_thumb2 (unsigned long pc,unsigned long addr,bool link) +static unsigned long __arm_gen_branch_thumb2 (unsigned long pc, +unsigned long addr,bool link, +bool warn) {unsigned long s, j1, j2, i1, i2, imm10, imm11;unsigned long first, second;
@@ -11,7 +12,7 @@ __arm_gen_branch_thumb2(unsigned long pc offset = (long )addr - (long )(pc +4 );if (offset <-16777216 || offset >16777214 ) { -WARN_ON_ONCE (1 ); +WARN_ON_ONCE (warn);return 0 ; }
@@ -32,8 +33,8 @@ __arm_gen_branch_thumb2(unsigned long pcreturn __opcode_thumb32_compose (first, second); } -static unsigned long -__arm_gen_branch_arm (unsigned long pc,unsigned long addr,bool link) +static unsigned long __arm_gen_branch_arm (unsigned long pc,unsigned long addr, +bool link,bool warn) {unsigned long opcode =0xea000000 ;long offset;
@@ -43,7 +44,7 @@ __arm_gen_branch_arm(unsigned long pc, u offset = (long )addr - (long )(pc +8 );if (unlikely (offset <-33554432 || offset >33554428 )) { -WARN_ON_ONCE (1 ); +WARN_ON_ONCE (warn);return 0 ; }
@@ -53,10 +54,10 @@ __arm_gen_branch_arm(unsigned long pc, u }unsigned long -__arm_gen_branch (unsigned long pc,unsigned long addr,bool link) +__arm_gen_branch (unsigned long pc,unsigned long addr,bool link,bool warn) {if (IS_ENABLED (CONFIG_THUMB2_KERNEL )) -return __arm_gen_branch_thumb2 (pc, addr, link); +return __arm_gen_branch_thumb2 (pc, addr, link, warn);else -return __arm_gen_branch_arm (pc, addr, link); +return __arm_gen_branch_arm (pc, addr, link, warn); }
Greg Kroah-Hartman
maintainerPATCH 51/57 ARM: 9079/1: ftrace: Add MODULE_PLTS support
In reply to Greg Kroah-HartmanFrom: Alex Sverdlin <[email protected]>
commit 79f32b221b18c15a98507b101ef4beb52444cc6f upstream
Teach ftrace_make_call() and ftrace_make_nop() about PLTs. Teach PLT code about FTRACE and all its callbacks. Otherwise the following might happen:
------------[ cut here ]------------ WARNING: CPU: 14 PID: 2265 at .../arch/arm/kernel/insn.c:14 __arm_gen_branch+0x83/0x8c() ... Hardware name: LSI Axxia AXM55XX [<c0314a49>] (unwind_backtrace) from [<c03115e9>] (show_stack+0x11/0x14) [<c03115e9>] (show_stack) from [<c0519f51>] (dump_stack+0x81/0xa8) [<c0519f51>] (dump_stack) from [<c032185d>] (warn_slowpath_common+0x69/0x90) [<c032185d>] (warn_slowpath_common) from [<c03218f3>] (warn_slowpath_null+0x17/0x1c) [<c03218f3>] (warn_slowpath_null) from [<c03143cf>] (__arm_gen_branch+0x83/0x8c) [<c03143cf>] (__arm_gen_branch) from [<c0314337>] (ftrace_make_nop+0xf/0x24) [<c0314337>] (ftrace_make_nop) from [<c038ebcb>] (ftrace_process_locs+0x27b/0x3e8) [<c038ebcb>] (ftrace_process_locs) from [<c0378d79>] (load_module+0x11e9/0x1a44) [<c0378d79>] (load_module) from [<c037974d>] (SyS_finit_module+0x59/0x84) [<c037974d>] (SyS_finit_module) from [<c030e981>] (ret_fast_syscall+0x1/0x18) ---[ end trace e1b64ced7a89adcc ]--- ------------[ cut here ]------------ WARNING: CPU: 14 PID: 2265 at .../kernel/trace/ftrace.c:1979 ftrace_bug+0x1b1/0x234() ... Hardware name: LSI Axxia AXM55XX [<c0314a49>] (unwind_backtrace) from [<c03115e9>] (show_stack+0x11/0x14) [<c03115e9>] (show_stack) from [<c0519f51>] (dump_stack+0x81/0xa8) [<c0519f51>] (dump_stack) from [<c032185d>] (warn_slowpath_common+0x69/0x90) [<c032185d>] (warn_slowpath_common) from [<c03218f3>] (warn_slowpath_null+0x17/0x1c) [<c03218f3>] (warn_slowpath_null) from [<c038e87d>] (ftrace_bug+0x1b1/0x234) [<c038e87d>] (ftrace_bug) from [<c038ebd5>] (ftrace_process_locs+0x285/0x3e8) [<c038ebd5>] (ftrace_process_locs) from [<c0378d79>] (load_module+0x11e9/0x1a44) [<c0378d79>] (load_module) from [<c037974d>] (SyS_finit_module+0x59/0x84) [<c037974d>] (SyS_finit_module) from [<c030e981>] (ret_fast_syscall+0x1/0x18) ---[ end trace e1b64ced7a89adcd ]---
ftrace failed to modify [<e9ef7006>] 0xe9ef7006
actual: 02:f0:3b:fa
ftrace record flags: 0
(0) expected tramp: c0314265
--- arch/arm/include/asm/ftrace.h | 3 ++ arch/arm/include/asm/module.h | 1 arch/arm/kernel/ftrace.c | 45 +++++++++++++++++++++++++++++++++++------- arch/arm/kernel/module-plts.c | 44 +++++++++++++++++++++++++++++++++++++---- 4 files changed, 82 insertions(+), 11 deletions(-)
arch/arm/include/asm/ftrace.h +3 -0
@@ -14,6 +14,9 @@ struct dyn_arch_ftrace {#ifdef CONFIG_OLD_MCOUNT bool old_mcount;#endif +#ifdef CONFIG_ARM_MODULE_PLTS +struct module *mod; +#endif };static inline unsigned long ftrace_call_adjust (unsigned long addr)
arch/arm/include/asm/module.h +1 -0
@@ -29,6 +29,7 @@ struct plt_entries {struct mod_plt_sec {struct elf32_shdr *plt; +struct plt_entries *plt_ent;int plt_count; };
arch/arm/kernel/ftrace.c +38 -7
89 lines not on this page · raw message
arch/arm/kernel/module-plts.c +40 -4
85 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 52/57 ARM: 9098/1: ftrace: MODULE_PLT: Fix build problem without DYNAMIC_FTRACE
In reply to Greg Kroah-HartmanFrom: Alex Sverdlin <[email protected]>
commit 6fa630bf473827aee48cbf0efbbdf6f03134e890 upstream
FTRACE_ADDR is only defined when CONFIG_DYNAMIC_FTRACE is defined, the latter is even stronger requirement than CONFIG_FUNCTION_TRACER (which is enough for MCOUNT_ADDR).
--- arch/arm/kernel/module-plts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/kernel/module-plts.c +1 -1
@@ -24,7 +24,7 @@#endif static const u32 fixed_plts[] = { -#ifdef CONFIG_FUNCTION_TRACER +#ifdef CONFIG_DYNAMIC_FTRACEFTRACE_ADDR ,MCOUNT_ADDR , #endif
Greg Kroah-Hartman
maintainerPATCH 53/57 arm64: Extend workaround for erratum 1024718 to all versions of Cortex-A55
In reply to Greg Kroah-HartmanFrom: Suzuki K Poulose <[email protected]>
commit c0b15c25d25171db4b70cc0b7dbc1130ee94017d upstream.
The erratum 1024718 affects Cortex-A55 r0p0 to r2p0. However we apply the work around for r0p0 - r1p0. Unfortunately this won't be fixed for the future revisions for the CPU. Thus extend the work around for all versions of A55, to cover for r2p0 and any future revisions.
[Nanyon: adjust for stable version below v4.16, which set TCR_HD earlier in assembly code]
--- arch/arm64/Kconfig | 2 +- arch/arm64/mm/proc.S | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
arch/arm64/Kconfig +1 -1
@@ -433,7 +433,7 @@ config ARM64_ERRATUM_1024718 help This option adds work around for Arm Cortex-A55 Erratum 1024718. - Affected Cortex-A55 cores (r0p0, r0p1, r1p0) could cause incorrect + Affected Cortex-A55 cores (all revisions) could cause incorrect update of the hardware dirty bit when the DBM/AP bits are updated without a break-before-make. The work around is to disable the usage of hardware DBM locally on the affected cores. CPUs not affected by
arch/arm64/mm/proc.S +2 -2
@@ -442,8 +442,8 @@ ENTRY(__cpu_setup) cmp x9, #2 b.lt 1f #ifdef CONFIG_ARM64_ERRATUM_1024718 - /* Disable hardware DBM on Cortex-A55 r0p0, r0p1 & r1p0 */ - cpu_midr_match MIDR_CORTEX_A55, MIDR_CPU_VAR_REV(0, 0), MIDR_CPU_VAR_REV(1, 0), x1, x2, x3, x4 + /* Disable hardware DBM on Cortex-A55 all versions */ + cpu_midr_match MIDR_CORTEX_A55, MIDR_CPU_VAR_REV(0, 0), MIDR_CPU_VAR_REV(0xf, 0xf), x1, x2, x3, x4 cbnz x1, 1f #endif orr x10, x10, #TCR_HD // hardware Dirty flag update
Greg Kroah-Hartman
maintainerPATCH 54/57 HID: betop: fix slab-out-of-bounds Write in betop_probe
In reply to Greg Kroah-HartmanFrom: F.A.Sulaiman <[email protected]>
commit 1e4ce418b1cb1a810256b5fb3fd33d22d1325993 upstream.
Syzbot reported slab-out-of-bounds Write bug in hid-betopff driver. The problem is the driver assumes the device must have an input report but some malicious devices violate this assumption.
So this patch checks hid_device's input is non empty before it's been used.
--- drivers/hid/hid-betopff.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
drivers/hid/hid-betopff.c +10 -3
@@ -59,15 +59,22 @@ static int betopff_init(struct hid_devic {struct betopff_device *betopff;struct hid_report *report; -struct hid_input *hidinput = - list_first_entry(&hid->inputs, struct hid_input, list); +struct hid_input *hidinput;struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT ].report_list; -struct input_dev *dev = hidinput->input; +struct input_dev *dev;int field_count =0 ;int error;int i, j; +if (list_empty (&hid->inputs)) { +hid_err (hid,"no inputs found\n" ); +return -ENODEV ; + } + + hidinput = list_first_entry(&hid->inputs, struct hid_input, list); + dev = hidinput->input; +if (list_empty (report_list)) {hid_err (hid,"no output reports found\n" );return -ENODEV ;
Greg Kroah-Hartman
maintainerPATCH 55/57 netfilter: ipset: Fix oversized kvmalloc() calls
In reply to Greg Kroah-HartmanFrom: Jozsef Kadlecsik <[email protected]>
commit 7bbc3d385bd813077acaf0e6fdb2a86a901f5382 upstream.
The commit
commit 7661809d493b426e979f39ab512e3adf41fbcc69
Author: Linus Torvalds <[email protected]> Date: Wed Jul 14 09:45:49 2021 -0700
mm: don't allow oversized kvmalloc() calls
limits the max allocatable memory via kvmalloc() to MAX_INT. Apply the same limit in ipset.
--- net/netfilter/ipset/ip_set_hash_gen.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/netfilter/ipset/ip_set_hash_gen.h +2 -2
@@ -102,11 +102,11 @@ htable_size(u8 hbits) {size_t hsize; -/* We must fit both into u32 in jhash and size_t */ +/* We must fit both into u32 in jhash and INT_MAX in kvmalloc_node() */ if (hbits >31 )return 0 ; hsize =jhash_size (hbits); -if ((((size_t )-1 ) -sizeof (struct htable )) /sizeof (struct hbucket *) +if ((INT_MAX -sizeof (struct htable )) /sizeof (struct hbucket *) < hsize)return 0 ;
Greg Kroah-Hartman
maintainerPATCH 56/57 HID: usbhid: free raw_report buffers in usbhid_stop
In reply to Greg Kroah-HartmanFrom: Anirudh Rayabharam <[email protected]>
commit f7744fa16b96da57187dc8e5634152d3b63d72de upstream.
Free the unsent raw_report buffers when the device is removed.
Fixes a memory leak reported by syzbot at:
https://syzkaller.appspot.com/bug?id=7b4fa7cb1a7c2d3342a2a8a6c53371c8c418ab47
--- drivers/hid/usbhid/hid-core.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
drivers/hid/usbhid/hid-core.c +12 -1
@@ -500,7 +500,7 @@ static void hid_ctrl(struct urb *urb)if (unplug) { usbhid->ctrltail = usbhid->ctrlhead; - }else { + }else if (usbhid->ctrlhead != usbhid->ctrltail) { usbhid->ctrltail = (usbhid->ctrltail +1 ) & (HID_CONTROL_FIFO_SIZE -1 ); if (usbhid->ctrlhead != usbhid->ctrltail &&
@@ -1185,9 +1185,20 @@ static void usbhid_stop(struct hid_devic usbhid->intf->needs_remote_wakeup =0 ;clear_bit (HID_STARTED , &usbhid->iofl); +spin_lock_irq (&usbhid->lock);/* Sync with error and led handlers */ set_bit (HID_DISCONNECTED , &usbhid->iofl); +while (usbhid->ctrltail != usbhid->ctrlhead) { +if (usbhid->ctrl[usbhid->ctrltail].dir ==USB_DIR_OUT ) { +kfree (usbhid->ctrl[usbhid->ctrltail].raw_report); + usbhid->ctrl[usbhid->ctrltail].raw_report =NULL ; + } + + usbhid->ctrltail = (usbhid->ctrltail +1 ) & + (HID_CONTROL_FIFO_SIZE -1 ); + }spin_unlock_irq (&usbhid->lock); +usb_kill_urb (usbhid->urbin);usb_kill_urb (usbhid->urbout);usb_kill_urb (usbhid->urbctrl);
Greg Kroah-Hartman
maintainerPATCH 57/57 net: mdiobus: Fix memory leak in __mdiobus_register
In reply to Greg Kroah-HartmanFrom: Yanfei Xu <[email protected]>
commit ab609f25d19858513919369ff3d9a63c02cd9e2e upstream.
Once device_register() failed, we should call put_device() to decrement reference count for cleanup. Or it will cause memory leak.
BUG: memory leak
unreferenced object 0xffff888114032e00 (size 256):
comm "kworker/1:3", pid 2960, jiffies 4294943572 (age 15.920s)
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 08 2e 03 14 81 88 ff ff ................
08 2e 03 14 81 88 ff ff 90 76 65 82 ff ff ff ff .........ve.....
backtrace:
[<ffffffff8265cfab>] kmalloc include/linux/slab.h:591 [inline]
[<ffffffff8265cfab>] kzalloc include/linux/slab.h:721 [inline]
[<ffffffff8265cfab>] device_private_init drivers/base/core.c:3203 [inline]
[<ffffffff8265cfab>] device_add+0x89b/0xdf0 drivers/base/core.c:3253
[<ffffffff828dd643>] __mdiobus_register+0xc3/0x450 drivers/net/phy/mdio_bus.c:537
[<ffffffff828cb835>] __devm_mdiobus_register+0x75/0xf0 drivers/net/phy/mdio_devres.c:87
[<ffffffff82b92a00>] ax88772_init_mdio drivers/net/usb/asix_devices.c:676 [inline]
[<ffffffff82b92a00>] ax88772_bind+0x330/0x480 drivers/net/usb/asix_devices.c:786
[<ffffffff82baa33f>] usbnet_probe+0x3ff/0xdf0 drivers/net/usb/usbnet.c:1745
[<ffffffff82c36e17>] usb_probe_interface+0x177/0x370 drivers/usb/core/driver.c:396
[<ffffffff82661d17>] call_driver_probe drivers/base/dd.c:517 [inline]
[<ffffffff82661d17>] really_probe.part.0+0xe7/0x380 drivers/base/dd.c:596
[<ffffffff826620bc>] really_probe drivers/base/dd.c:558 [inline]
[<ffffffff826620bc>] __driver_probe_device+0x10c/0x1e0 drivers/base/dd.c:751
[<ffffffff826621ba>] driver_probe_device+0x2a/0x120 drivers/base/dd.c:781
[<ffffffff82662a26>] __device_attach_driver+0xf6/0x140 drivers/base/dd.c:898
[<ffffffff8265eca7>] bus_for_each_drv+0xb7/0x100 drivers/base/bus.c:427
[<ffffffff826625a2>] __device_attach+0x122/0x260 drivers/base/dd.c:969
[<ffffffff82660916>] bus_probe_device+0xc6/0xe0 drivers/base/bus.c:487
[<ffffffff8265cd0b>] device_add+0x5fb/0xdf0 drivers/base/core.c:3359
[<ffffffff82c343b9>] usb_set_configuration+0x9d9/0xb90 drivers/usb/core/message.c:2170
[<ffffffff82c4473c>] usb_generic_driver_probe+0x8c/0xc0 drivers/usb/core/generic.c:238
BUG: memory leak
unreferenced object 0xffff888116f06900 (size 32):
comm "kworker/0:2", pid 2670, jiffies 4294944448 (age 7.160s)
hex dump (first 32 bytes):
75 73 62 2d 30 30 31 3a 30 30 33 00 00 00 00 00 usb-001:003.....
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<ffffffff81484516>] kstrdup+0x36/0x70 mm/util.c:60
[<ffffffff814845a3>] kstrdup_const+0x53/0x80 mm/util.c:83
[<ffffffff82296ba2>] kvasprintf_const+0xc2/0x110 lib/kasprintf.c:48
[<ffffffff82358d4b>] kobject_set_name_vargs+0x3b/0xe0 lib/kobject.c:289
[<ffffffff826575f3>] dev_set_name+0x63/0x90 drivers/base/core.c:3147
[<ffffffff828dd63b>] __mdiobus_register+0xbb/0x450 drivers/net/phy/mdio_bus.c:535
[<ffffffff828cb835>] __devm_mdiobus_register+0x75/0xf0 drivers/net/phy/mdio_devres.c:87
[<ffffffff82b92a00>] ax88772_init_mdio drivers/net/usb/asix_devices.c:676 [inline]
[<ffffffff82b92a00>] ax88772_bind+0x330/0x480 drivers/net/usb/asix_devices.c:786
[<ffffffff82baa33f>] usbnet_probe+0x3ff/0xdf0 drivers/net/usb/usbnet.c:1745
[<ffffffff82c36e17>] usb_probe_interface+0x177/0x370 drivers/usb/core/driver.c:396
[<ffffffff82661d17>] call_driver_probe drivers/base/dd.c:517 [inline]
[<ffffffff82661d17>] really_probe.part.0+0xe7/0x380 drivers/base/dd.c:596
[<ffffffff826620bc>] really_probe drivers/base/dd.c:558 [inline]
[<ffffffff826620bc>] __driver_probe_device+0x10c/0x1e0 drivers/base/dd.c:751
[<ffffffff826621ba>] driver_probe_device+0x2a/0x120 drivers/base/dd.c:781
[<ffffffff82662a26>] __device_attach_driver+0xf6/0x140 drivers/base/dd.c:898
[<ffffffff8265eca7>] bus_for_each_drv+0xb7/0x100 drivers/base/bus.c:427
[<ffffffff826625a2>] __device_attach+0x122/0x260 drivers/base/dd.c:969--- drivers/net/phy/mdio_bus.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/phy/mdio_bus.c +1 -0
@@ -319,6 +319,7 @@ int __mdiobus_register(struct mii_bus *b err =device_register (&bus->dev);if (err) {pr_err ("mii_bus %s failed to register\n" , bus->id); +put_device (&bus->dev);return -EINVAL ; }
Re: [PATCH 4.9 57/57] net: mdiobus: Fix memory leak in __mdiobus_register
Quoted 7 lines · Greg Kroah-Hartman
From: Yanfei Xu <[email protected]>
commit
ab609f25d19858513919369ff3d9a63c02cd9e2eupstream.Once
device_register()failed, we should callput_device()to decrement reference count for cleanup. Or it will cause memory leak.
This changed has since been reverted upstream, please drop this change:
Signature · 1 line
Florian
Greg Kroah-Hartman
maintainerRe: [PATCH 4.9 57/57] net: mdiobus: Fix memory leak in __mdiobus_register
Quoted 5 lines · Florian Fainelli
Quoted 4 lines · Greg Kroah-Hartman
From: Yanfei Xu <[email protected]>
commit
ab609f25d19858513919369ff3d9a63c02cd9e2eupstream.
Quoted 7 lines
Quoted 3 lines
Once
device_register()failed, we should callput_device()to decrement reference count for cleanup. Or it will cause memory leak.This changed has since been reverted upstream, please drop this change:
Now dropped from everywhere, thanks.
greg k-h
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.9.285 release. There are 57 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 06 Oct 2021 12:50:17 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.9.285-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.9.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.9.285 release. There are 57 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 06 Oct 2021 12:50:17 +0000. Anything received after that time might be too late.
Build results:
total: 163 pass: 163 fail: 0 Qemu test results: total: 394 pass: 394 fail: 0
Guenter