5.15.174-rc1 review
Subsystems (4)
Greg Kroah-Hartman
maintainerPATCH 281/565 octeontx2-af: RPM: Fix mismatch in lmac type
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hariprasad Kelam <[email protected]>
[ Upstream commit 7ebbbb23ea5b6d051509cb11399afac5042c9266 ]
Due to a bug in the previous patch, there is a mismatch between the lmac type reported by the driver and the actual hardware configuration.
--- drivers/net/ethernet/marvell/octeontx2/af/rpm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/marvell/octeontx2/af/rpm.c +1 -1
@@ -256,7 +256,7 @@ u8 rpm_get_lmac_type(void *rpmd, int lmac_id)int err; req =FIELD_SET (CMDREG_ID ,CGX_CMD_GET_LINK_STS , req); - err =cgx_fwi_cmd_generic (req, &resp, rpm,0 ); + err =cgx_fwi_cmd_generic (req, &resp, rpm, lmac_id);if (!err)return FIELD_GET (RESP_LINKSTAT_LMAC_TYPE , resp);return err;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 282/565 spi: atmel-quadspi: Fix register name in verbose logging function
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Csókás, Bence <[email protected]>
[ Upstream commit 2ac40e6d0ccdd93031f8b1af61b0fe5cdd704923 ]
atmel_qspi_reg_name() is used for pretty-printing register offsets for verbose logging of register accesses. However, due to a typo (likely a copy-paste error), QSPI_RD's offset prints as "MR", the name of the previous register. Fix this typo.
--- drivers/spi/atmel-quadspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/spi/atmel-quadspi.c +1 -1
@@ -182,7 +182,7 @@ static const char *atmel_qspi_reg_name(u32 offset, char *tmp, size_t sz)case QSPI_MR :return "MR" ;case QSPI_RD : -return "MR" ; +return "RD" ;case QSPI_TD :return "TD" ;case QSPI_SR :
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 283/565 net: hsr: fix hsr_init_sk() vs network/transport headers.
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 9cfb5e7f0ded2bfaabc270ceb5f91d13f0e805b9 ]
Following sequence in hsr_init_sk() is invalid :
skb_reset_mac_header(skb);
skb_reset_mac_len(skb);
skb_reset_network_header(skb);
skb_reset_transport_header(skb);It is invalid because skb_reset_mac_len() needs the correct network header, which should be after the mac header.
This patch moves the skb_reset_network_header() and skb_reset_transport_header() before
the call to dev_hard_header().
As a result skb->mac_len is no longer set to a value close to 65535.
--- net/hsr/hsr_device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/hsr/hsr_device.c +2 -2
@@ -256,6 +256,8 @@ static struct sk_buff *hsr_init_skb(struct hsr_port *master) skb->dev = master->dev; skb->priority =TC_PRIO_CONTROL ; +skb_reset_network_header (skb); +skb_reset_transport_header (skb);if (dev_hard_header (skb, skb->dev,ETH_P_PRP , hsr->sup_multicast_addr, skb->dev->dev_addr, skb->len) <=0 )
@@ -263,8 +265,6 @@ static struct sk_buff *hsr_init_skb(struct hsr_port *master)skb_reset_mac_header (skb);skb_reset_mac_len (skb); -skb_reset_network_header (skb); -skb_reset_transport_header (skb);return skb; out:
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 284/565 bnxt_en: Reserve rings after PCIe AER recovery if NIC interface is down
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Saravanan Vajravel <[email protected]>
[ Upstream commit 5311598f7f3293683cdc761df71ae3469327332c ]
After successful PCIe AER recovery, FW will reset all resource reservations. If it is IF_UP, the driver will call bnxt_open() and all resources will be reserved again. It it is IF_DOWN, we should call bnxt_reserve_rings() so that we can reserve resources including RoCE resources to allow RoCE to resume after AER. Without this patch, RoCE fails to resume in this IF_DOWN scenario.
Later, if it becomes IF_UP, bnxt_open() will see that resources have been reserved and will not reserve again.
--- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/net/ethernet/broadcom/bnxt/bnxt.c +6 -2
@@ -13692,8 +13692,12 @@ static void bnxt_io_resume(struct pci_dev *pdev)rtnl_lock (); err =bnxt_hwrm_func_qcaps (bp); -if (!err &&netif_running (netdev)) - err =bnxt_open (netdev); +if (!err) { +if (netif_running (netdev)) + err =bnxt_open (netdev); +else + err =bnxt_reserve_rings (bp, true); + }bnxt_ulp_start (bp, err);if (!err) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 285/565 tcp: Fix use-after-free of nreq in reqsk_timer_handler().
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit c31e72d021db2714df03df6c42855a1db592716c ]
The cited commit replaced inet_csk_reqsk_queue_drop_and_put() with __inet_csk_reqsk_queue_drop() and reqsk_put() in reqsk_timer_handler().
Then, oreq should be passed to reqsk_put() instead of req; otherwise use-after-free of nreq could happen when reqsk is migrated but the retry attempt failed (e.g. due to timeout).
Let's pass oreq to reqsk_put().
--- net/ipv4/inet_connection_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv4/inet_connection_sock.c +1 -1
@@ -935,7 +935,7 @@ static void reqsk_timer_handler(struct timer_list *t) drop:__inet_csk_reqsk_queue_drop (sk_listener, oreq, true); -reqsk_put (req); +reqsk_put (oreq); } static bool reqsk_queue_hash_req(struct request_sock *req,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 286/565 iio: light: al3010: Fix an error handling path in al3010_probe()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe JAILLET <[email protected]>
[ Upstream commit a4b7064d34186cf4970fe0333c3b27346cf8f819 ]
If i2c_smbus_write_byte_data() fails in al3010_init(), al3010_set_pwr(false) is not called.
In order to avoid such a situation, move the devm_add_action_or_reset() witch calls al3010_set_pwr(false) right after a successful al3010_set_pwr(true).
--- drivers/iio/light/al3010.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
drivers/iio/light/al3010.c +5 -6
@@ -87,7 +87,12 @@ static int al3010_init(struct al3010_data *data)int ret; ret =al3010_set_pwr (data->client, true); +if (ret <0 ) +return ret; + ret =devm_add_action_or_reset (&data->client->dev, + al3010_set_pwr_off, + data);if (ret <0 )return ret;
@@ -191,12 +196,6 @@ static int al3010_probe(struct i2c_client *client,return ret; } - ret =devm_add_action_or_reset (&client->dev, - al3010_set_pwr_off, - data); -if (ret <0 ) -return ret; -return devm_iio_device_register (&client->dev, indio_dev); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 287/565 usb: using mutex lock and supporting O_NONBLOCK flag in iowarrior_read()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeongjun Park <[email protected]>
[ Upstream commit 44feafbaa66ec86232b123bb8437a6a262442025 ]
iowarrior_read() uses the iowarrior dev structure, but does not use any lock on the structure. This can cause various bugs including data-races, so it is more appropriate to use a mutex lock to safely protect the iowarrior dev structure. When using a mutex lock, you should split the branch to prevent blocking when the O_NONBLOCK flag is set.
In addition, it is unnecessary to check for NULL on the iowarrior dev structure obtained by reading file->private_data. Therefore, it is better to remove the check.
--- drivers/usb/misc/iowarrior.c | 46 ++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 10 deletions(-)
drivers/usb/misc/iowarrior.c +36 -10
@@ -277,28 +277,45 @@ static ssize_t iowarrior_read(struct file *file, char __user *buffer,struct iowarrior *dev;int read_idx;int offset; +int retval; dev = file->private_data; +if (file->f_flags &O_NONBLOCK ) { + retval =mutex_trylock (&dev->mutex); +if (!retval) +return -EAGAIN ; + }else { + retval =mutex_lock_interruptible (&dev->mutex); +if (retval) +return -ERESTARTSYS ; + } +/* verify that the device wasn't unplugged */ -if (!dev || !dev->present) -return -ENODEV ; +if (!dev->present) { + retval = -ENODEV ; + goto exit; + }dev_dbg (&dev->interface->dev,"minor %d, count = %zd\n" , dev->minor, count);/* read count must be packet size (+ time stamp) */ if ((count != dev->report_size) - && (count != (dev->report_size +1 ))) -return -EINVAL ; + && (count != (dev->report_size +1 ))) { + retval = -EINVAL ; + goto exit; + }/* repeat until no buffer overrun in callback handler occur */ do { atomic_set(&dev->overflow_flag, 0); if ((read_idx = read_index(dev)) == -1) { /* queue empty */ - if (file->f_flags & O_NONBLOCK) - return -EAGAIN; + if (file->f_flags & O_NONBLOCK) { + retval = -EAGAIN; + goto exit; + } else { //next line will return when there is either new data, or the device is unplugged int r = wait_event_interruptible(dev->read_wait,
@@ -309,28 +326,37 @@ static ssize_t iowarrior_read(struct file *file, char __user *buffer, -1));if (r) {//we were interrupted by a signal -return -ERESTART ; + retval = -ERESTART ; + goto exit; }if (!dev->present) {//The device was unplugged -return -ENODEV ; + retval = -ENODEV ; + goto exit; }if (read_idx ==-1 ) {// Can this happen ??? -return 0 ; + retval =0 ; + goto exit; } } } offset = read_idx * (dev->report_size +1 );if (copy_to_user (buffer, dev->read_queue + offset, count)) { -return -EFAULT ; + retval = -EFAULT ; + goto exit; } }while (atomic_read (&dev->overflow_flag)); read_idx = ++read_idx ==MAX_INTERRUPT_BUFFER ?0 : read_idx;atomic_set (&dev->read_idx, read_idx); +mutex_unlock (&dev->mutex);return count; + +exit: +mutex_unlock (&dev->mutex); +return retval; }/*
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 288/565 usb: yurex: make waiting on yurex_write interruptible
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum <[email protected]>
[ Upstream commit e0aa9614ab0fd35b404e4b16ebe879f9fc152591 ]
The IO yurex_write() needs to wait for in order to have a device ready for writing again can take a long time time. Consequently the sleep is done in an interruptible state. Therefore others waiting for yurex_write() itself to finish should use mutex_lock_interruptible.
Rule: add
--- drivers/usb/misc/iowarrior.c | 4 ---- drivers/usb/misc/yurex.c | 5 ++++- 2 files changed, 4 insertions(+), 5 deletions(-)
drivers/usb/misc/iowarrior.c +0 -4
@@ -912,7 +912,6 @@ static int iowarrior_probe(struct usb_interface *interface,static void iowarrior_disconnect (struct usb_interface *interface) {struct iowarrior *dev =usb_get_intfdata (interface); -int minor = dev->minor;usb_deregister_dev (interface, &iowarrior_class);
@@ -936,9 +935,6 @@ static void iowarrior_disconnect(struct usb_interface *interface)mutex_unlock (&dev->mutex);iowarrior_delete (dev); } - -dev_info (&interface->dev,"I/O-Warror #%d now disconnected\n" , - minor -IOWARRIOR_MINOR_BASE ); }/* usb specific object needed to register this driver with the usb subsystem */
drivers/usb/misc/yurex.c +4 -1
@@ -441,7 +441,10 @@ static ssize_t yurex_write(struct file *file, const char __user *user_buffer,if (count ==0 ) goto error; -mutex_lock (&dev->io_mutex); + retval =mutex_lock_interruptible (&dev->io_mutex); +if (retval <0 ) +return -EINTR ; +if (dev->disconnected) {/* already disconnected */ mutex_unlock (&dev->io_mutex); retval = -ENODEV ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 289/565 USB: chaoskey: fail open after removal
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum <[email protected]>
[ Upstream commit 422dc0a4d12d0b80dd3aab3fe5943f665ba8f041 ]
chaoskey_open() takes the lock only to increase the counter of openings. That means that the mutual exclusion with chaoskey_disconnect() cannot prevent an increase of the counter and chaoskey_open() returning a success.
If that race is hit, chaoskey_disconnect() will happily free all resources associated with the device after it has dropped the lock, as it has read the counter as zero.
To prevent this race chaoskey_open() has to check the presence of the device under the lock. However, the current per device lock cannot be used, because it is a part of the data structure to be freed. Hence an additional global mutex is needed. The issue is as old as the driver.
Rule: add
--- drivers/usb/misc/chaoskey.c | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-)
drivers/usb/misc/chaoskey.c +24 -11
@@ -27,6 +27,8 @@ static struct usb_class_driver chaoskey_class;static int chaoskey_rng_read (struct hwrng *rng,void *data,size_t max,bool wait); +static DEFINE_MUTEX (chaoskey_list_lock); + #define usb_dbg(usb_if, format, arg...) \ dev_dbg(&(usb_if)->dev, format, ## arg)
@@ -231,6 +233,7 @@ static void chaoskey_disconnect(struct usb_interface *interface)if (dev->hwrng_registered)hwrng_unregister (&dev->hwrng); +mutex_lock (&chaoskey_list_lock);usb_deregister_dev (interface, &chaoskey_class);usb_set_intfdata (interface,NULL );
@@ -245,6 +248,7 @@ static void chaoskey_disconnect(struct usb_interface *interface) }else mutex_unlock (&dev->lock); +mutex_unlock (&chaoskey_list_lock);usb_dbg (interface,"disconnect done" ); }
@@ -252,6 +256,7 @@ static int chaoskey_open(struct inode *inode, struct file *file) {struct chaoskey *dev;struct usb_interface *interface; +int rv =0 ;/* get the interface from minor number and driver information */ interface =usb_find_interface (&chaoskey_driver,iminor (inode));
@@ -267,18 +272,23 @@ static int chaoskey_open(struct inode *inode, struct file *file) } file->private_data = dev; +mutex_lock (&chaoskey_list_lock);mutex_lock (&dev->lock); - ++dev->open; +if (dev->present) + ++dev->open; +else + rv = -ENODEV ;mutex_unlock (&dev->lock); +mutex_unlock (&chaoskey_list_lock); -usb_dbg (interface,"open success" ); -return 0 ; +return rv; }static int chaoskey_release (struct inode *inode,struct file *file) {struct chaoskey *dev = file->private_data;struct usb_interface *interface; +int rv =0 ;if (dev ==NULL )return -ENODEV ;
@@ -287,14 +297,15 @@ static int chaoskey_release(struct inode *inode, struct file *file)usb_dbg (interface,"release" ); +mutex_lock (&chaoskey_list_lock);mutex_lock (&dev->lock);usb_dbg (interface,"open count at release is %d" , dev->open);if (dev->open <=0 ) {usb_dbg (interface,"invalid open count (%d)" , dev->open); -mutex_unlock (&dev->lock); -return -ENODEV ; + rv = -ENODEV ; + goto bail; } --dev->open;
@@ -303,13 +314,15 @@ static int chaoskey_release(struct inode *inode, struct file *file)if (dev->open ==0 ) {mutex_unlock (&dev->lock);chaoskey_free (dev); - }else -mutex_unlock (&dev->lock); - }else -mutex_unlock (&dev->lock); - + goto destruction; + } + } +bail: +mutex_unlock (&dev->lock); +destruction: +mutex_lock (&chaoskey_list_lock);usb_dbg (interface,"release success" ); -return 0 ; +return rv; }static void chaos_read_callback (struct urb *urb)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 290/565 USB: chaoskey: Fix possible deadlock chaoskey_list_lock
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Edward Adam Davis <[email protected]>
[ Upstream commit d73dc7b182be4238b75278bfae16afb4c5564a58 ]
[Syzbot reported two possible deadlocks]
The first possible deadlock is:
WARNING: possible recursive locking detected
6.12.0-rc1-syzkaller-00027-g4a9fe2a8ac53 #0 Not tainted
--------------------------------------------
syz-executor363/2651 is trying to acquire lock:ffffffff89b120e8 (chaoskey_list_lock){+.+.}-{3:3}, at: chaoskey_release+0x15d/0x2c0 drivers/usb/misc/chaoskey.c:322
but task is already holding lock:ffffffff89b120e8 (chaoskey_list_lock){+.+.}-{3:3}, at: chaoskey_release+0x7f/0x2c0 drivers/usb/misc/chaoskey.c:299
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0
---- lock(chaoskey_list_lock);
lock(chaoskey_list_lock);
*** DEADLOCK ***
The second possible deadlock is:
WARNING: possible circular locking dependency detected 6.12.0-rc1-syzkaller-00027-g4a9fe2a8ac53 #0 Not tainted
------------------------------------------------------
kworker/0:2/804 is trying to acquire lock:ffffffff899dadb0 (minor_rwsem){++++}-{3:3}, at: usb_deregister_dev+0x7c/0x1e0 drivers/usb/core/file.c:186
but task is already holding lock:ffffffff89b120e8 (chaoskey_list_lock){+.+.}-{3:3}, at: chaoskey_disconnect+0xa8/0x2a0 drivers/usb/misc/chaoskey.c:235
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (chaoskey_list_lock){+.+.}-{3:3}:
__mutex_lock_common kernel/locking/mutex.c:608 [inline]
__mutex_lock+0x175/0x9c0 kernel/locking/mutex.c:752
chaoskey_open+0xdd/0x220 drivers/usb/misc/chaoskey.c:274
usb_open+0x186/0x220 drivers/usb/core/file.c:47
chrdev_open+0x237/0x6a0 fs/char_dev.c:414
do_dentry_open+0x6cb/0x1390 fs/open.c:958
vfs_open+0x82/0x3f0 fs/open.c:1088
do_open fs/namei.c:3774 [inline]
path_openat+0x1e6a/0x2d60 fs/namei.c:3933
do_filp_open+0x1dc/0x430 fs/namei.c:3960
do_sys_openat2+0x17a/0x1e0 fs/open.c:1415
do_sys_open fs/open.c:1430 [inline]
__do_sys_openat fs/open.c:1446 [inline]
__se_sys_openat fs/open.c:1441 [inline]
__x64_sys_openat+0x175/0x210 fs/open.c:1441
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0xcd/0x250 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x77/0x7f-> #0 (minor_rwsem){++++}-{3:3}:
check_prev_add kernel/locking/lockdep.c:3161 [inline]
check_prevs_add kernel/locking/lockdep.c:3280 [inline]
validate_chain kernel/locking/lockdep.c:3904 [inline]
__lock_acquire+0x250b/0x3ce0 kernel/locking/lockdep.c:5202
lock_acquire.part.0+0x11b/0x380 kernel/locking/lockdep.c:5825
down_write+0x93/0x200 kernel/locking/rwsem.c:1577
usb_deregister_dev+0x7c/0x1e0 drivers/usb/core/file.c:186
chaoskey_disconnect+0xb7/0x2a0 drivers/usb/misc/chaoskey.c:236
usb_unbind_interface+0x1e8/0x970 drivers/usb/core/driver.c:461
device_remove drivers/base/dd.c:569 [inline]
device_remove+0x122/0x170 drivers/base/dd.c:561
__device_release_driver drivers/base/dd.c:1273 [inline]
device_release_driver_internal+0x44a/0x610 drivers/base/dd.c:1296
bus_remove_device+0x22f/0x420 drivers/base/bus.c:576
device_del+0x396/0x9f0 drivers/base/core.c:3864
usb_disable_device+0x36c/0x7f0 drivers/usb/core/message.c:1418
usb_disconnect+0x2e1/0x920 drivers/usb/core/hub.c:2304
hub_port_connect drivers/usb/core/hub.c:5361 [inline]
hub_port_connect_change drivers/usb/core/hub.c:5661 [inline]
port_event drivers/usb/core/hub.c:5821 [inline]
hub_event+0x1bed/0x4f40 drivers/usb/core/hub.c:5903
process_one_work+0x9c5/0x1ba0 kernel/workqueue.c:3229
process_scheduled_works kernel/workqueue.c:3310 [inline]
worker_thread+0x6c8/0xf00 kernel/workqueue.c:3391
kthread+0x2c1/0x3a0 kernel/kthread.c:389
ret_from_fork+0x45/0x80 arch/x86/kernel/process.c:147
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244other info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(chaoskey_list_lock);
lock(minor_rwsem);
lock(chaoskey_list_lock); lock(minor_rwsem);
*** DEADLOCK ***
[Analysis]
The first is AA lock, it because wrong logic, it need a unlock. The second is AB lock, it needs to rearrange the order of lock usage.
--- drivers/usb/misc/chaoskey.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/misc/chaoskey.c +2 -2
@@ -233,10 +233,10 @@ static void chaoskey_disconnect(struct usb_interface *interface)if (dev->hwrng_registered)hwrng_unregister (&dev->hwrng); -mutex_lock (&chaoskey_list_lock);usb_deregister_dev (interface, &chaoskey_class);usb_set_intfdata (interface,NULL ); +mutex_lock (&chaoskey_list_lock);mutex_lock (&dev->lock); dev->present = false;
@@ -320,7 +320,7 @@ static int chaoskey_release(struct inode *inode, struct file *file) bail:mutex_unlock (&dev->lock); destruction: -mutex_lock (&chaoskey_list_lock); +mutex_unlock (&chaoskey_list_lock);usb_dbg (interface,"release success" );return rv; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 291/565 misc: apds990x: Fix missing pm_runtime_disable()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
[ Upstream commit 3c5d8b819d27012264edd17e6ae7fffda382fe44 ]
The pm_runtime_disable() is missing in probe error path, so add it to fix it.
--- drivers/misc/apds990x.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
drivers/misc/apds990x.c +7 -5
@@ -1148,7 +1148,7 @@ static int apds990x_probe(struct i2c_client *client, err = chip->pdata->setup_resources ();if (err) { err = -EINVAL ; - goto fail3; + goto fail4; } }
@@ -1156,7 +1156,7 @@ static int apds990x_probe(struct i2c_client *client, apds990x_attribute_group);if (err <0 ) {dev_err (&chip->client->dev,"Sysfs registration failed\n" ); - goto fail4; + goto fail5; } err = request_threaded_irq(client->irq, NULL,
@@ -1167,15 +1167,17 @@ static int apds990x_probe(struct i2c_client *client,if (err) {dev_err (&client->dev,"could not get IRQ %d\n" , client->irq); - goto fail5; + goto fail6; }return err; -fail5: +fail6:sysfs_remove_group (&chip->client->dev.kobj, &apds990x_attribute_group[0 ]); -fail4: +fail5:if (chip->pdata && chip->pdata->release_resources) chip->pdata->release_resources (); +fail4: +pm_runtime_disable (&client->dev); fail3:regulator_bulk_disable (ARRAY_SIZE (chip->regs), chip->regs); fail2:
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 292/565 counter: stm32-timer-cnt: Add check for clk_enable()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiasheng Jiang <[email protected]>
[ Upstream commit 842c3755a6bfbfcafa4a1438078d2485a9eb1d87 ]
Add check for the return value of clk_enable() in order to catch the potential exception.
--- drivers/counter/stm32-timer-cnt.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
drivers/counter/stm32-timer-cnt.c +13 -3
@@ -196,11 +196,17 @@ static int stm32_count_enable_write(struct counter_device *counter, {struct stm32_timer_cnt *const priv = counter->priv;u32 cr1; +int ret;if (enable) {regmap_read (priv->regmap,TIM_CR1 , &cr1); -if (!(cr1 &TIM_CR1_CEN )) -clk_enable (priv->clk); +if (!(cr1 &TIM_CR1_CEN )) { + ret =clk_enable (priv->clk); +if (ret) { +dev_err (counter->parent,"Cannot enable clock %d\n" , ret); +return ret; + } + }regmap_update_bits (priv->regmap,TIM_CR1 ,TIM_CR1_CEN ,TIM_CR1_CEN );
@@ -374,7 +380,11 @@ static int __maybe_unused stm32_timer_cnt_resume(struct device *dev)return ret;if (priv->enabled) { -clk_enable (priv->clk); + ret =clk_enable (priv->clk); +if (ret) { +dev_err (dev,"Cannot enable clock %d\n" , ret); +return ret; + }/* Restore registers that may have been lost */ regmap_write (priv->regmap,TIM_SMCR , priv->bak.smcr);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 293/565 ALSA: hda/realtek: Update ALC256 depop procedure
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kailang Yang <[email protected]>
[ Upstream commit cc3d0b5dd989d3238d456f9fd385946379a9c13d ]
Old procedure has a chance to meet Headphone no output.
--- sound/pci/hda/patch_realtek.c | 42 ++++++++++++++++------------------- 1 file changed, 19 insertions(+), 23 deletions(-)
sound/pci/hda/patch_realtek.c +19 -23
@@ -3593,25 +3593,22 @@ static void alc256_init(struct hda_codec *codec) hp_pin_sense =snd_hda_jack_detect (codec, hp_pin); -if (hp_pin_sense) +if (hp_pin_sense) {msleep (2 ); +alc_update_coefex_idx (codec,0x57 ,0x04 ,0x0007 ,0x1 );/* Low power */ -alc_update_coefex_idx (codec,0x57 ,0x04 ,0x0007 ,0x1 );/* Low power */ - -snd_hda_codec_write (codec, hp_pin,0 , -AC_VERB_SET_AMP_GAIN_MUTE ,AMP_OUT_MUTE ); - -if (hp_pin_sense || spec->ultra_low_power) -msleep (85 ); - -snd_hda_codec_write (codec, hp_pin,0 , +snd_hda_codec_write (codec, hp_pin,0 ,AC_VERB_SET_PIN_WIDGET_CONTROL ,PIN_OUT ); -if (hp_pin_sense || spec->ultra_low_power) -msleep (100 ); +msleep (75 ); + +snd_hda_codec_write (codec, hp_pin,0 , +AC_VERB_SET_AMP_GAIN_MUTE ,AMP_OUT_UNMUTE ); +msleep (75 ); +alc_update_coefex_idx (codec,0x57 ,0x04 ,0x0007 ,0x4 );/* Hight power */ + }alc_update_coef_idx (codec,0x46 ,3 <<12 ,0 ); -alc_update_coefex_idx (codec,0x57 ,0x04 ,0x0007 ,0x4 );/* Hight power */ alc_update_coefex_idx (codec,0x53 ,0x02 ,0x8000 ,1 <<15 );/* Clear bit */ alc_update_coefex_idx (codec,0x53 ,0x02 ,0x8000 ,0 <<15 );/*
@@ -3635,29 +3632,28 @@ static void alc256_shutup(struct hda_codec *codec)alc_update_coefex_idx (codec,0x57 ,0x04 ,0x0007 ,0x1 );/* Low power */ hp_pin_sense =snd_hda_jack_detect (codec, hp_pin); -if (hp_pin_sense) +if (hp_pin_sense) {msleep (2 ); -snd_hda_codec_write (codec, hp_pin,0 , +snd_hda_codec_write (codec, hp_pin,0 ,AC_VERB_SET_AMP_GAIN_MUTE ,AMP_OUT_MUTE ); -if (hp_pin_sense || spec->ultra_low_power) -msleep (85 ); +msleep (75 );/* 3k pull low control for Headset jack. */ /* NOTE: call this before clearing the pin, otherwise codec stalls */ /* If disable 3k pulldown control for alc257, the Mic detection will not work correctly * when booting with headset plugged. So skip setting it for the codec alc257 */ -if (spec->en_3kpull_low) -alc_update_coef_idx (codec,0x46 ,0 ,3 <<12 ); +if (spec->en_3kpull_low) +alc_update_coef_idx (codec,0x46 ,0 ,3 <<12 ); -if (!spec->no_shutup_pins) -snd_hda_codec_write (codec, hp_pin,0 , +if (!spec->no_shutup_pins) +snd_hda_codec_write (codec, hp_pin,0 ,AC_VERB_SET_PIN_WIDGET_CONTROL ,0x0 ); -if (hp_pin_sense || spec->ultra_low_power) -msleep (100 ); +msleep (75 ); + }alc_auto_setup_eapd (codec, false);alc_shutup_pins (codec);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 294/565 apparmor: fix Do simple duplicate message elimination
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: chao liu <[email protected]>
[ Upstream commit 9b897132424fe76bf6c61f22f9cf12af7f1d1e6a ]
Multiple profiles shared 'ent->caps', so some logs missed.
--- security/apparmor/capability.c | 2 ++ 1 file changed, 2 insertions(+)
security/apparmor/capability.c +2 -0
@@ -94,6 +94,8 @@ static int audit_caps(struct common_audit_data *sa, struct aa_profile *profile,return error; }else {aa_put_profile (ent->profile); +if (profile != ent->profile) +cap_clear (ent->caps); ent->profile =aa_get_profile (profile);cap_raise (ent->caps, cap); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 295/565 parisc: fix a possible DMA corruption
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikulas Patocka <[email protected]>
commit 7ae04ba36b381bffe2471eff3a93edced843240f upstream.
ARCH_DMA_MINALIGN was defined as 16 - this is too small - it may be possible that two unrelated 16-byte allocations share a cache line. If one of these allocations is written using DMA and the other is written using cached write, the value that was written with DMA may be corrupted.
This commit changes ARCH_DMA_MINALIGN to be 128 on PA20 and 32 on PA1.1 - that's the largest possible cache line size.
As different parisc microarchitectures have different cache line size, we define arch_slab_minalign(), cache_line_size() and dma_get_cache_alignment() so that the kernel may tune slab cache parameters dynamically, based on the detected cache line size.
--- arch/parisc/Kconfig | 1 + arch/parisc/include/asm/cache.h | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-)
arch/parisc/Kconfig +1 -0
@@ -15,6 +15,7 @@ config PARISC select ARCH_SPLIT_ARG64 if !64BIT select ARCH_SUPPORTS_HUGETLBFS if PA20 select ARCH_SUPPORTS_MEMORY_FAILURE + select ARCH_HAS_CACHE_LINE_SIZE select DMA_OPS select RTC_CLASS select RTC_DRV_GENERIC
arch/parisc/include/asm/cache.h +10 -1
@@ -20,7 +20,16 @@#define SMP_CACHE_BYTES L1_CACHE_BYTES -#define ARCH_DMA_MINALIGN L1_CACHE_BYTES +#ifdef CONFIG_PA20 +#define ARCH_DMA_MINALIGN 128 +#else +#define ARCH_DMA_MINALIGN 32 +#endif +#define ARCH_KMALLOC_MINALIGN 16/* ldcw requires 16-byte alignment */ + +#define arch_slab_minalign () ((unsigned)dcache_stride) +#define cache_line_size () dcache_stride +#define dma_get_cache_alignment cache_line_size#define __read_mostly __section(".data..read_mostly")
Greg Kroah-Hartman
maintainerPATCH 296/565 ksmbd: fix slab-use-after-free in smb3_preauth_hash_rsp
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <[email protected]>
commit b8fc56fbca7482c1e5c0e3351c6ae78982e25ada upstream.
ksmbd_user_session_put should be called under smb3_preauth_hash_rsp(). It will avoid freeing session before calling smb3_preauth_hash_rsp().
--- fs/ksmbd/server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/ksmbd/server.c +2 -2
@@ -238,11 +238,11 @@ static void __handle_ksmbd_work(struct k }while (is_chained == true); send: -if (work->sess) -ksmbd_user_session_put (work->sess);if (work->tcon)ksmbd_tree_connect_put (work->tcon);smb3_preauth_hash_rsp (work); +if (work->sess) +ksmbd_user_session_put (work->sess);if (work->sess && work->sess->enc && work->encrypted && conn->ops->encrypt_resp) { rc = conn->ops->encrypt_resp (work);
Greg Kroah-Hartman
maintainerPATCH 297/565 xen: Fix the issue of resource not being properly released in xenbus_dev_probe()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qiu-ji Chen <[email protected]>
commit afc545da381ba0c651b2658966ac737032676f01 upstream.
This patch fixes an issue in the function xenbus_dev_probe(). In the xenbus_dev_probe() function, within the if (err) branch at line 313, the program incorrectly returns err directly without releasing the resources allocated by err = drv->probe(dev, id). As the return value is non-zero, the upper layers assume the processing logic has failed. However, the probe operation was performed earlier without a corresponding remove operation. Since the probe actually allocates resources, failing to perform the remove operation could lead to problems.
To fix this issue, we followed the resource release logic of the xenbus_dev_remove() function by adding a new block fail_remove before the fail_put block. After entering the branch if (err) at line 313, the function will use a goto statement to jump to the fail_remove block, ensuring that the previously acquired resources are correctly released, thus preventing the reference count leak.
This bug was identified by an experimental static analysis tool developed by our team. The tool specializes in analyzing reference count operations and detecting potential issues where resources are not properly managed. In this case, the tool flagged the missing release operation as a potential problem, which led to the development of this patch.
Message-ID: <[email protected]>
--- drivers/xen/xenbus/xenbus_probe.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/xen/xenbus/xenbus_probe.c +7 -1
@@ -308,7 +308,7 @@ int xenbus_dev_probe(struct device *_devif (err) {dev_warn (&dev->dev,"watch_otherend on %s failed.\n" , dev->nodename); -return err; + goto fail_remove; } dev->spurious_threshold =1 ;
@@ -317,6 +317,12 @@ int xenbus_dev_probe(struct device *_dev dev->nodename);return 0 ; +fail_remove: +if (drv->remove) { +down (&dev->reclaim_sem); + drv->remove (dev); +up (&dev->reclaim_sem); + } fail_put:module_put (drv->driver.owner); fail:
Greg Kroah-Hartman
maintainerPATCH 298/565 ALSA: usb-audio: Fix out of bounds reads when finding clock sources
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit a3dd4d63eeb452cfb064a13862fb376ab108f6a6 upstream.
The current USB-audio driver code doesn't check bLength of each descriptor at traversing for clock descriptors. That is, when a device provides a bogus descriptor with a shorter bLength, the driver might hit out-of-bounds reads.
For addressing it, this patch adds sanity checks to the validator functions for the clock descriptor traversal. When the descriptor length is shorter than expected, it's skipped in the loop.
For the clock source and clock multiplier descriptors, we can just check bLength against the sizeof() of each descriptor type. OTOH, the clock selector descriptor of UAC2 and UAC3 has an array of bNrInPins elements and two more fields at its tail, hence those have to be checked in addition to the sizeof() check.
--- sound/usb/clock.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-)
sound/usb/clock.c +23 -1
@@ -36,6 +36,12 @@ union uac23_clock_multiplier_desc {struct uac_clock_multiplier_descriptor v3; }; +/* check whether the descriptor bLength has the minimal length */ +#define DESC_LENGTH_CHECK (p, proto) \ + ((proto) == UAC_VERSION_3 ? \ + ((p)->v3.bLength >= sizeof((p)->v3)) : \ + ((p)->v2.bLength >= sizeof((p)->v2))) +#define GET_VAL (p, proto, field) \ ((proto) == UAC_VERSION_3 ? (p)->v3.field : (p)->v2.field)
@@ -58,6 +64,8 @@ static bool validate_clock_source(void * {union uac23_clock_source_desc *cs = p; +if (!DESC_LENGTH_CHECK (cs, proto)) +return false;return GET_VAL (cs, proto, bClockID) == id; }
@@ -65,13 +73,27 @@ static bool validate_clock_selector(void {union uac23_clock_selector_desc *cs = p; -return GET_VAL (cs, proto, bClockID) == id; +if (!DESC_LENGTH_CHECK (cs, proto)) +return false; +if (GET_VAL (cs, proto, bClockID) != id) +return false; +/* additional length check for baCSourceID array (in bNrInPins size) +* and two more fields (which sizes depend on the protocol) +*/ +if (proto ==UAC_VERSION_3 ) +return cs->v3.bLength >=sizeof (cs->v3) + cs->v3.bNrInPins + +4 /* bmControls */ +2 /* wCSelectorDescrStr */ ; +else +return cs->v2.bLength >=sizeof (cs->v2) + cs->v2.bNrInPins + +1 /* bmControls */ +1 /* iClockSelector */ ; }static bool validate_clock_multiplier (void *p,int id,int proto) {union uac23_clock_multiplier_desc *cs = p; +if (!DESC_LENGTH_CHECK (cs, proto)) +return false;return GET_VAL (cs, proto, bClockID) == id; }
Greg Kroah-Hartman
maintainerPATCH 299/565 usb: ehci-spear: fix call balance of sehci clk handling routines
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vitalii Mordan <[email protected]>
commit 40c974826734836402abfd44efbf04f63a2cc1c1 upstream.
If the clock sehci->clk was not enabled in spear_ehci_hcd_drv_probe, it should not be disabled in any path.
Conversely, if it was enabled in spear_ehci_hcd_drv_probe, it must be disabled in all error paths to ensure proper cleanup.
Found by Linux Verification Center (linuxtesting.org) with Klever.
--- drivers/usb/host/ehci-spear.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/usb/host/ehci-spear.c +4 -3
@@ -108,7 +108,9 @@ static int spear_ehci_hcd_drv_probe(stru/* registers start at offset 0x0 */ hcd_to_ehci (hcd)->caps = hcd->regs; -clk_prepare_enable (sehci->clk); + retval =clk_prepare_enable (sehci->clk); +if (retval) + goto err_put_hcd; retval =usb_add_hcd (hcd, irq,IRQF_SHARED );if (retval) goto err_stop_ehci;
@@ -133,8 +135,7 @@ static int spear_ehci_hcd_drv_remove(strusb_remove_hcd (hcd); -if (sehci->clk) -clk_disable_unprepare (sehci->clk); +clk_disable_unprepare (sehci->clk);usb_put_hcd (hcd);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 300/565 Revert "drivers: clk: zynqmp: update divider round rate logic"
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joel Guittet <[email protected]>
This reverts commit 9117fc44fd3a9538261e530ba5a022dfc9519620 which is commit 1fe15be1fb613534ecbac5f8c3f8744f757d237d upstream.
It is reported to cause regressions in the 5.15.y tree, so revert it for now.
--- drivers/clk/zynqmp/divider.c | 66 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 5 deletions(-)
drivers/clk/zynqmp/divider.c +61 -5
@@ -110,6 +110,52 @@ static unsigned long zynqmp_clk_divider_return DIV_ROUND_UP_ULL (parent_rate, value); } +static void zynqmp_get_divider2_val (struct clk_hw *hw, +unsigned long rate, +struct zynqmp_clk_divider *divider, +u32 *bestdiv) +{ +int div1; +int div2; +long error =LONG_MAX ; +unsigned long div1_prate; +struct clk_hw *div1_parent_hw; +struct zynqmp_clk_divider *pdivider; +struct clk_hw *div2_parent_hw =clk_hw_get_parent (hw); + +if (!div2_parent_hw) +return ; + + pdivider =to_zynqmp_clk_divider (div2_parent_hw); +if (!pdivider) +return ; + + div1_parent_hw =clk_hw_get_parent (div2_parent_hw); +if (!div1_parent_hw) +return ; + + div1_prate =clk_hw_get_rate (div1_parent_hw); + *bestdiv =1 ; +for (div1 =1 ; div1 <= pdivider->max_div;) { +for (div2 =1 ; div2 <= divider->max_div;) { +long new_error = ((div1_prate / div1) / div2) - rate; + +if (abs (new_error) <abs (error)) { + *bestdiv = div2; + error = new_error; + } +if (divider->flags &CLK_DIVIDER_POWER_OF_TWO ) + div2 = div2 <<1 ; +else + div2++; + } +if (pdivider->flags &CLK_DIVIDER_POWER_OF_TWO ) + div1 = div1 <<1 ; +else + div1++; + } +} +/** * zynqmp_clk_divider_round_rate() - Round rate of divider clock * @hw: handle between common and hardware-specific interfaces
@@ -128,7 +174,6 @@ static long zynqmp_clk_divider_round_ratu32 div_type = divider->div_type;u32 bestdiv;int ret; -u8 width;/* if read only, just return current value */ if (divider->flags &CLK_DIVIDER_READ_ONLY ) {
@@ -148,12 +193,23 @@ static long zynqmp_clk_divider_round_ratreturn DIV_ROUND_UP_ULL ((u64)*prate, bestdiv); } - width =fls (divider->max_div); + bestdiv =zynqmp_divider_get_val (*prate, rate, divider->flags); + +/* +* In case of two divisors, compute best divider values and return +* divider2 value based on compute value. div1 will be automatically +* set to optimum based on required total divider value. +*/ +if (div_type ==TYPE_DIV2 && + (clk_hw_get_flags (hw) &CLK_SET_RATE_PARENT )) { +zynqmp_get_divider2_val (hw, rate, divider, &bestdiv); + } - rate =divider_round_rate (hw, rate, prate,NULL , width, divider->flags); +if ((clk_hw_get_flags (hw) &CLK_SET_RATE_PARENT ) && divider->is_frac) + bestdiv = rate % *prate ?1 : bestdiv; -if (divider->is_frac && (clk_hw_get_flags (hw) &CLK_SET_RATE_PARENT ) && (rate % *prate)) - *prate = rate; + bestdiv =min_t (u32, bestdiv, divider->max_div); + *prate = rate * bestdiv;return rate; }
Greg Kroah-Hartman
maintainerPATCH 301/565 ASoC: Intel: sst: Fix used of uninitialized ctx to log an error
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede <[email protected]>
commit c1895ba181e560144601fafe46aeedbafdf4dbc4 upstream.
Fix the new "LPE0F28" code path using the uninitialized ctx variable to log an error.
--- sound/soc/intel/atom/sst/sst_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/intel/atom/sst/sst_acpi.c +1 -1
@@ -309,7 +309,7 @@ static int sst_acpi_probe(struct platfor rsrc =platform_get_resource (pdev,IORESOURCE_MEM , pdata->res_info->acpi_lpe_res_index);if (!rsrc) { -dev_err (ctx->dev,"Invalid SHIM base\n" ); +dev_err (dev,"Invalid SHIM base\n" );return -EIO ; } rsrc->start -= pdata->res_info->shim_offset;
Greg Kroah-Hartman
maintainerPATCH 302/565 soc: qcom: socinfo: fix revision check in qcom_socinfo_probe()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manikanta Mylavarapu <[email protected]>
commit 128fdbf36cddc2a901c4889ba1c89fa9f2643f2c upstream.
In success case, the revision holds a non-null pointer. The current logic incorrectly returns an error for a non-null pointer, whereas it should return an error for a null pointer.
The socinfo driver for IPQ9574 and IPQ5332 is currently broken, resulting in the following error message
qcom-socinfo qcom-socinfo: probe with driver qcom-socinfo failed with error -12
Add a null check for the revision to ensure it returns an error only in failure case (null pointer).
--- drivers/soc/qcom/socinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/soc/qcom/socinfo.c +1 -1
@@ -614,7 +614,7 @@ static int qcom_socinfo_probe(struct pla qs->attr.revision =devm_kasprintf (&pdev->dev,GFP_KERNEL ,"%u.%u" ,SOCINFO_MAJOR (le32_to_cpu (info->ver)),SOCINFO_MINOR (le32_to_cpu (info->ver))); -if (!qs->attr.soc_id || qs->attr.revision) +if (!qs->attr.soc_id || !qs->attr.revision)return -ENOMEM ;if (offsetof(struct socinfo , serial_num) <= item_size) {
Greg Kroah-Hartman
maintainerPATCH 303/565 ALSA: usb-audio: Fix potential out-of-bound accesses for Extigy and Mbox devices
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benoît Sevens <[email protected]>
commit b909df18ce2a998afef81d58bbd1a05dc0788c40 upstream.
A bogus device can provide a bNumConfigurations value that exceeds the initial value used in usb_get_configuration for allocating dev->config.
This can lead to out-of-bounds accesses later, e.g. in usb_destroy_configuration.
--- sound/usb/quirks.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)
sound/usb/quirks.c +14 -5
@@ -591,6 +591,7 @@ int snd_usb_create_quirk(struct snd_usb_static int snd_usb_extigy_boot_quirk (struct usb_device *dev,struct usb_interface *intf) {struct usb_host_config *config = dev->actconfig; +struct usb_device_descriptor new_device_descriptor;int err; if (le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_OLD ||
@@ -602,10 +603,14 @@ static int snd_usb_extigy_boot_quirk(strif (err <0 )dev_dbg (&dev->dev,"error sending boot message: %d\n" , err); err =usb_get_descriptor (dev,USB_DT_DEVICE ,0 , - &dev->descriptor,sizeof (dev->descriptor)); - config = dev->actconfig; + &new_device_descriptor,sizeof (new_device_descriptor));if (err <0 )dev_dbg (&dev->dev,"error usb_get_descriptor: %d\n" , err); +if (new_device_descriptor.bNumConfigurations > dev->descriptor.bNumConfigurations) +dev_dbg (&dev->dev,"error too large bNumConfigurations: %d\n" , + new_device_descriptor.bNumConfigurations); +else +memcpy (&dev->descriptor, &new_device_descriptor,sizeof (dev->descriptor)); err =usb_reset_configuration (dev);if (err <0 )dev_dbg (&dev->dev,"error usb_reset_configuration: %d\n" , err);
@@ -937,6 +942,7 @@ static void mbox2_setup_48_24_magic(strustatic int snd_usb_mbox2_boot_quirk (struct usb_device *dev) {struct usb_host_config *config = dev->actconfig; +struct usb_device_descriptor new_device_descriptor;int err;u8 bootresponse[0x12 ];int fwsize;
@@ -972,10 +978,14 @@ static int snd_usb_mbox2_boot_quirk(strudev_dbg (&dev->dev,"device initialised!\n" ); err =usb_get_descriptor (dev,USB_DT_DEVICE ,0 , - &dev->descriptor,sizeof (dev->descriptor)); - config = dev->actconfig; + &new_device_descriptor,sizeof (new_device_descriptor));if (err <0 )dev_dbg (&dev->dev,"error usb_get_descriptor: %d\n" , err); +if (new_device_descriptor.bNumConfigurations > dev->descriptor.bNumConfigurations) +dev_dbg (&dev->dev,"error too large bNumConfigurations: %d\n" , + new_device_descriptor.bNumConfigurations); +else +memcpy (&dev->descriptor, &new_device_descriptor,sizeof (dev->descriptor)); err =usb_reset_configuration (dev);if (err <0 )
@@ -1020,7 +1030,6 @@ static int snd_usb_axefx3_boot_quirk(strreturn 0 ; } -#define MICROBOOK_BUF_SIZE 128 static int snd_usb_motu_microbookii_communicate(struct usb_device *dev, u8 *buf,
Greg Kroah-Hartman
maintainerPATCH 304/565 ext4: supress data-race warnings in ext4_free_inodes_{count,set}()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeongjun Park <[email protected]>
commit 902cc179c931a033cd7f4242353aa2733bf8524c upstream.
find_group_other() and find_group_orlov() read *_lo, *_hi with ext4_free_inodes_count without additional locking. This can cause data-race warning, but since the lock is held for most writes and free inodes value is generally not a problem even if it is incorrect, it is more appropriate to use READ_ONCE()/WRITE_ONCE() than to add locking.
==================================================================
BUG: KCSAN: data-race in ext4_free_inodes_count / ext4_free_inodes_set
write to 0xffff88810404300e of 2 bytes by task 6254 on cpu 1:
ext4_free_inodes_set+0x1f/0x80 fs/ext4/super.c:405 __ext4_new_inode+0x15ca/0x2200 fs/ext4/ialloc.c:1216 ext4_symlink+0x242/0x5a0 fs/ext4/namei.c:3391 vfs_symlink+0xca/0x1d0 fs/namei.c:4615 do_symlinkat+0xe3/0x340 fs/namei.c:4641 __do_sys_symlinkat fs/namei.c:4657 [inline] __se_sys_symlinkat fs/namei.c:4654 [inline] __x64_sys_symlinkat+0x5e/0x70 fs/namei.c:4654 x64_sys_call+0x1dda/0x2d60 arch/x86/include/generated/asm/syscalls_64.h:267 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0x54/0x120 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x76/0x7e
read to 0xffff88810404300e of 2 bytes by task 6257 on cpu 0:
ext4_free_inodes_count+0x1c/0x80 fs/ext4/super.c:349 find_group_other fs/ext4/ialloc.c:594 [inline] __ext4_new_inode+0x6ec/0x2200 fs/ext4/ialloc.c:1017 ext4_symlink+0x242/0x5a0 fs/ext4/namei.c:3391 vfs_symlink+0xca/0x1d0 fs/namei.c:4615 do_symlinkat+0xe3/0x340 fs/namei.c:4641 __do_sys_symlinkat fs/namei.c:4657 [inline] __se_sys_symlinkat fs/namei.c:4654 [inline] __x64_sys_symlinkat+0x5e/0x70 fs/namei.c:4654 x64_sys_call+0x1dda/0x2d60 arch/x86/include/generated/asm/syscalls_64.h:267 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0x54/0x120 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x76/0x7e
--- fs/ext4/super.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
fs/ext4/super.c +4 -4
@@ -320,9 +320,9 @@ __u32 ext4_free_group_clusters(struct su__u32 ext4_free_inodes_count (struct super_block *sb,struct ext4_group_desc *bg) { -return le16_to_cpu (bg->bg_free_inodes_count_lo) | +return le16_to_cpu (READ_ONCE (bg->bg_free_inodes_count_lo)) | (EXT4_DESC_SIZE (sb) >=EXT4_MIN_DESC_SIZE_64BIT ? - (__u32 )le16_to_cpu (bg->bg_free_inodes_count_hi) <<16 :0 ); + (__u32 )le16_to_cpu (READ_ONCE (bg->bg_free_inodes_count_hi)) <<16 :0 ); } __u32 ext4_used_dirs_count(struct super_block *sb,
@@ -376,9 +376,9 @@ void ext4_free_group_clusters_set(structvoid ext4_free_inodes_set (struct super_block *sb,struct ext4_group_desc *bg,__u32 count) { - bg->bg_free_inodes_count_lo =cpu_to_le16 ((__u16 )count); +WRITE_ONCE (bg->bg_free_inodes_count_lo,cpu_to_le16 ((__u16 )count));if (EXT4_DESC_SIZE (sb) >=EXT4_MIN_DESC_SIZE_64BIT ) - bg->bg_free_inodes_count_hi =cpu_to_le16 (count >>16 ); +WRITE_ONCE (bg->bg_free_inodes_count_hi,cpu_to_le16 (count >>16 )); } void ext4_used_dirs_set(struct super_block *sb,
Greg Kroah-Hartman
maintainerPATCH 305/565 ext4: fix FS_IOC_GETFSMAP handling
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <[email protected]>
commit 4a622e4d477bb12ad5ed4abbc7ad1365de1fa347 upstream.
The original implementation ext4's FS_IOC_GETFSMAP handling only worked when the range of queried blocks included at least one free (unallocated) block range. This is because how the metadata blocks were emitted was as a side effect of ext4_mballoc_query_range() calling ext4_getfsmap_datadev_helper(), and that function was only called when a free block range was identified. As a result, this caused generic/365 to fail.
Fix this by creating a new function ext4_getfsmap_meta_helper() which gets called so that blocks before the first free block range in a block group can get properly reported.
--- fs/ext4/fsmap.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++- fs/ext4/mballoc.c | 18 ++++++++++++++---- fs/ext4/mballoc.h | 1 + 3 files changed, 68 insertions(+), 5 deletions(-)
fs/ext4/fsmap.c +53 -1
@@ -185,6 +185,56 @@ static inline ext4_fsblk_t ext4_fsmap_nereturn fmr->fmr_physical + fmr->fmr_length; } +static int ext4_getfsmap_meta_helper (struct super_block *sb, +ext4_group_t agno,ext4_grpblk_t start, +ext4_grpblk_t len,void *priv) +{ +struct ext4_getfsmap_info *info = priv; +struct ext4_fsmap *p; +struct ext4_fsmap *tmp; +struct ext4_sb_info *sbi =EXT4_SB (sb); +ext4_fsblk_t fsb, fs_start, fs_end; +int error; + + fs_start = fsb = (EXT4_C2B (sbi, start) + +ext4_group_first_block_no (sb, agno)); + fs_end = fs_start +EXT4_C2B (sbi, len); + +/* Return relevant extents from the meta_list */ +list_for_each_entry_safe (p, tmp, &info->gfi_meta_list, fmr_list) { +if (p->fmr_physical < info->gfi_next_fsblk) { +list_del (&p->fmr_list); +kfree (p); +continue ; + } +if (p->fmr_physical <= fs_start || + p->fmr_physical + p->fmr_length <= fs_end) { +/* Emit the retained free extent record if present */ +if (info->gfi_lastfree.fmr_owner) { + error =ext4_getfsmap_helper (sb, info, + &info->gfi_lastfree); +if (error) +return error; + info->gfi_lastfree.fmr_owner =0 ; + } + error =ext4_getfsmap_helper (sb, info, p); +if (error) +return error; + fsb = p->fmr_physical + p->fmr_length; +if (info->gfi_next_fsblk < fsb) + info->gfi_next_fsblk = fsb; +list_del (&p->fmr_list); +kfree (p); +continue ; + } + } +if (info->gfi_next_fsblk < fsb) + info->gfi_next_fsblk = fsb; + +return 0 ; +} + +/* Transform a blockgroup's free record into a fsmap */ static int ext4_getfsmap_datadev_helper(struct super_block *sb, ext4_group_t agno, ext4_grpblk_t start,
@@ -539,6 +589,7 @@ static int ext4_getfsmap_datadev(struct error =ext4_mballoc_query_range (sb, info->gfi_agno,EXT4_B2C (sbi, info->gfi_low.fmr_physical),EXT4_B2C (sbi, info->gfi_high.fmr_physical), + ext4_getfsmap_meta_helper, ext4_getfsmap_datadev_helper, info);if (error) goto err;
@@ -560,7 +611,8 @@ static int ext4_getfsmap_datadev(struct/* Report any gaps at the end of the bg */ info->gfi_last = true; - error =ext4_getfsmap_datadev_helper (sb, end_ag, last_cluster,0 , info); + error =ext4_getfsmap_datadev_helper (sb, end_ag, last_cluster +1 , +0 , info);if (error) goto err;
fs/ext4/mballoc.c +14 -4
@@ -6698,13 +6698,14 @@ intext4_mballoc_query_range ( struct super_block *sb, ext4_group_t group, - ext4_grpblk_t start, + ext4_grpblk_t first, ext4_grpblk_t end, + ext4_mballoc_query_range_fn meta_formatter, ext4_mballoc_query_range_fn formatter, void *priv) { void *bitmap; -ext4_grpblk_t next; +ext4_grpblk_t start, next;struct ext4_buddy e4b;int error;
@@ -6715,10 +6716,19 @@ ext4_mballoc_query_range(ext4_lock_group (sb, group); - start =max (e4b.bd_info->bb_first_free, start); + start =max (e4b.bd_info->bb_first_free, first);if (end >=EXT4_CLUSTERS_PER_GROUP (sb)) end =EXT4_CLUSTERS_PER_GROUP (sb) -1 ; - +if (meta_formatter && start != first) { +if (start > end) + start = end; +ext4_unlock_group (sb, group); + error =meta_formatter (sb, group, first, start - first, + priv); +if (error) + goto out_unload; +ext4_lock_group (sb, group); + }while (start <= end) { start =mb_find_next_zero_bit (bitmap, end +1 , start);if (start > end)
fs/ext4/mballoc.h +1 -0
@@ -246,6 +246,7 @@ ext4_mballoc_query_range(ext4_group_t agno, ext4_grpblk_t start, ext4_grpblk_t end, + ext4_mballoc_query_range_fn meta_formatter, ext4_mballoc_query_range_fn formatter, void *priv);
Greg Kroah-Hartman
maintainerPATCH 306/565 jfs: xattr: check invalid xattr size more strictly
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Artem Sadovnikov <[email protected]>
commit d9f9d96136cba8fedd647d2c024342ce090133c2 upstream.
Commit 7c55b78818cf ("jfs: xattr: fix buffer overflow for invalid xattr") also addresses this issue but it only fixes it for positive values, while ea_size is an integer type and can take negative values, e.g. in case of a corrupted filesystem. This still breaks validation and would overflow because of implicit conversion from int to size_t in print_hex_dump().
Fix this issue by clamping the ea_size value instead.
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
--- fs/jfs/xattr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/jfs/xattr.c +1 -1
@@ -559,7 +559,7 @@ static int ea_get(struct inode *inode, s size_check:if (EALIST_SIZE (ea_buf->xattr) != ea_size) { -int size =min_t (int,EALIST_SIZE (ea_buf->xattr), ea_size); +int size =clamp_t (int, ea_size,0 ,EALIST_SIZE (ea_buf->xattr));printk (KERN_ERR "ea_get: invalid extended attribute\n" ); print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 16, 1,
Greg Kroah-Hartman
maintainerPATCH 307/565 ASoC: codecs: Fix atomicity violation in snd_soc_component_get_drvdata()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qiu-ji Chen <[email protected]>
commit 1157733344651ca505e259d6554591ff156922fa upstream.
An atomicity violation occurs when the validity of the variables da7219->clk_src and da7219->mclk_rate is being assessed. Since the entire assessment is not protected by a lock, the da7219 variable might still be in flux during the assessment, rendering this check invalid.
To fix this issue, we recommend adding a lock before the block if ((da7219->clk_src == clk_id) && (da7219->mclk_rate == freq)) so that the legitimacy check for da7219->clk_src and da7219->mclk_rate is protected by the lock, ensuring the validity of the check.
This possible bug is found by an experimental static analysis tool developed by our team. This tool analyzes the locking APIs to extract function pairs that can be concurrently executed, and then analyzes the instructions in the paired functions to identify possible concurrency bugs including data races and atomicity violations.
--- sound/soc/codecs/da7219.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
sound/soc/codecs/da7219.c +6 -3
@@ -1167,17 +1167,20 @@ static int da7219_set_dai_sysclk(structstruct da7219_priv *da7219 =snd_soc_component_get_drvdata (component);int ret =0 ; -if ((da7219->clk_src == clk_id) && (da7219->mclk_rate == freq)) +mutex_lock (&da7219->pll_lock); + +if ((da7219->clk_src == clk_id) && (da7219->mclk_rate == freq)) { +mutex_unlock (&da7219->pll_lock);return 0 ; + }if ((freq <2000000 ) || (freq >54000000 )) { +mutex_unlock (&da7219->pll_lock);dev_err (codec_dai->dev,"Unsupported MCLK value %d\n" , freq);return -EINVAL ; } -mutex_lock (&da7219->pll_lock); -switch (clk_id) {case DA7219_CLKSRC_MCLK_SQR : snd_soc_component_update_bits(component, DA7219_PLL_CTRL,
Greg Kroah-Hartman
maintainerPATCH 308/565 perf/x86/intel/pt: Fix buffer full but size is 0 case
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adrian Hunter <[email protected]>
commit 5b590160d2cf776b304eb054afafea2bd55e3620 upstream.
If the trace data buffer becomes full, a truncated flag [T] is reported in PERF_RECORD_AUX. In some cases, the size reported is 0, even though data must have been added to make the buffer full.
That happens when the buffer fills up from empty to full before the Intel PT driver has updated the buffer position. Then the driver calculates the new buffer position before calculating the data size. If the old and new positions are the same, the data size is reported as 0, even though it is really the whole buffer size.
Fix by detecting when the buffer position is wrapped, and adjust the data size calculation accordingly.
Example
Use a very small buffer size (8K) and observe the size of truncated [T] data. Before the fix, it is possible to see records of 0 size.
Before:
$ perf record -m,8K -e intel_pt// uname
Linux
[ perf record: Woken up 2 times to write data ]
[ perf record: Captured and wrote 0.105 MB perf.data ]
$ perf script -D --no-itrace | grep AUX | grep -F '[T]'
Warning:
AUX data lost 2 times out of 3! 5 19462712368111 0x19710 [0x40]: PERF_RECORD_AUX offset: 0 size: 0 flags: 0x1 [T]
5 19462712700046 0x19ba8 [0x40]: PERF_RECORD_AUX offset: 0x170 size: 0xe90 flags: 0x1 [T]After:
$ perf record -m,8K -e intel_pt// uname
Linux
[ perf record: Woken up 3 times to write data ]
[ perf record: Captured and wrote 0.040 MB perf.data ]
$ perf script -D --no-itrace | grep AUX | grep -F '[T]'
Warning:
AUX data lost 2 times out of 3! 1 113720802995 0x4948 [0x40]: PERF_RECORD_AUX offset: 0 size: 0x2000 flags: 0x1 [T]
1 113720979812 0x6b10 [0x40]: PERF_RECORD_AUX offset: 0x2000 size: 0x2000 flags: 0x1 [T]--- arch/x86/events/intel/pt.c | 11 ++++++++--- arch/x86/events/intel/pt.h | 2 ++ 2 files changed, 10 insertions(+), 3 deletions(-)
arch/x86/events/intel/pt.c +8 -3
@@ -811,11 +811,13 @@ static void pt_buffer_advance(struct pt_ buf->cur_idx++;if (buf->cur_idx == buf->cur->last) { -if (buf->cur == buf->last) +if (buf->cur == buf->last) { buf->cur = buf->first; -else + buf->wrapped = true; + }else { buf->cur = list_entry(buf->cur->list.next, struct topa, list); + } buf->cur_idx =0 ; } }
@@ -829,8 +831,11 @@ static void pt_buffer_advance(struct pt_static void pt_update_head (struct pt *pt) {struct pt_buffer *buf =perf_get_aux (&pt->handle); +bool wrapped = buf->wrapped;u64 topa_idx, base, old; + buf->wrapped = false; +if (buf->single) {local_set (&buf->data_size, buf->output_off);return ;
@@ -848,7 +853,7 @@ static void pt_update_head(struct pt *pt }else { old = (local64_xchg (&buf->head, base) & ((buf->nr_pages <<PAGE_SHIFT ) -1 )); -if (base < old) +if (base < old || (base == old && wrapped)) base += buf->nr_pages <<PAGE_SHIFT ;local_add (base - old, &buf->data_size);
arch/x86/events/intel/pt.h +2 -0
@@ -65,6 +65,7 @@ struct pt_pmu {* @head: logical write offset inside the buffer * @snapshot: if this is for a snapshot/overwrite counter * @single: use Single Range Output instead of ToPA +* @wrapped: buffer advance wrapped back to the first topa table * @stop_pos: STOP topa entry index * @intr_pos: INT topa entry index * @stop_te: STOP topa entry pointer
@@ -82,6 +83,7 @@ struct pt_buffer {local64_t head;bool snapshot;bool single; +bool wrapped;long stop_pos, intr_pos;struct topa_entry *stop_te, *intr_te;void **data_pages;
Greg Kroah-Hartman
maintainerPATCH 309/565 crypto: x86/aegis128 - access 32-bit arguments as 32-bit
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <[email protected]>
commit 3b2f2d22fb424e9bebda4dbf6676cbfc7f9f62cd upstream.
Fix the AEGIS assembly code to access 'unsigned int' arguments as 32-bit values instead of 64-bit, since the upper bits of the corresponding 64-bit registers are not guaranteed to be zero.
Note: there haven't been any reports of this bug actually causing incorrect behavior. Neither gcc nor clang guarantee zero-extension to 64 bits, but zero-extension is likely to happen in practice because most instructions that operate on 32-bit registers zero-extend to 64 bits.
--- arch/x86/crypto/aegis128-aesni-asm.S | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-)
arch/x86/crypto/aegis128-aesni-asm.S +15 -14
@@ -20,7 +20,7 @@ #define T1 %xmm7 #define STATEP %rdi -#define LEN %rsi +#define LEN %esi #define SRC %rdx #define DST %rcx
@@ -75,32 +75,32 @@ SYM_FUNC_START_LOCAL(__load_partial) xor %r9d, %r9d pxor MSG, MSG - mov LEN, %r8 + mov LEN, %r8d and $0x1, %r8 jz .Lld_partial_1 - mov LEN, %r8 + mov LEN, %r8d and $0x1E, %r8 add SRC, %r8 mov (%r8), %r9b .Lld_partial_1: - mov LEN, %r8 + mov LEN, %r8d and $0x2, %r8 jz .Lld_partial_2 - mov LEN, %r8 + mov LEN, %r8d and $0x1C, %r8 add SRC, %r8 shl $0x10, %r9 mov (%r8), %r9w .Lld_partial_2: - mov LEN, %r8 + mov LEN, %r8d and $0x4, %r8 jz .Lld_partial_4 - mov LEN, %r8 + mov LEN, %r8d and $0x18, %r8 add SRC, %r8 shl $32, %r9
@@ -110,11 +110,11 @@ SYM_FUNC_START_LOCAL(__load_partial) .Lld_partial_4: movq %r9, MSG - mov LEN, %r8 + mov LEN, %r8d and $0x8, %r8 jz .Lld_partial_8 - mov LEN, %r8 + mov LEN, %r8d and $0x10, %r8 add SRC, %r8 pslldq $8, MSG
@@ -138,7 +138,7 @@ SYM_FUNC_END(__load_partial) * %r10 */ SYM_FUNC_START_LOCAL(__store_partial) - mov LEN, %r8 + mov LEN, %r8d mov DST, %r9 movq T0, %r10
@@ -676,7 +676,7 @@ SYM_FUNC_START(crypto_aegis128_aesni_dec call __store_partial /* mask with byte count: */ - movq LEN, T0 + movd LEN, T0 punpcklbw T0, T0 punpcklbw T0, T0 punpcklbw T0, T0
@@ -701,7 +701,8 @@ SYM_FUNC_END(crypto_aegis128_aesni_dec_t /* * void crypto_aegis128_aesni_final(void *state, void *tag_xor, - * u64 assoclen, u64 cryptlen); + * unsigned int assoclen, + * unsigned int cryptlen); */ SYM_FUNC_START(crypto_aegis128_aesni_final) FRAME_BEGIN
@@ -714,8 +715,8 @@ SYM_FUNC_START(crypto_aegis128_aesni_fin movdqu 0x40(STATEP), STATE4 /* prepare length block: */ - movq %rdx, MSG - movq %rcx, T0 + movd %edx, MSG + movd %ecx, T0 pslldq $8, T0 pxor T0, MSG psllq $3, MSG /* multiply by 8 (to get bit count) */
Greg Kroah-Hartman
maintainerPATCH 310/565 powerpc/pseries: Fix KVM guest detection for disabling hardlockup detector
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gautam Menghani <[email protected]>
commit 44e5d21e6d3fd2a1fed7f0327cf72e99397e2eaf upstream.
As per the kernel documentation[1], hardlockup detector should be disabled in KVM guests as it may give false positives. On PPC, hardlockup detector is enabled inside KVM guests because disable_hardlockup_detector() is marked as early_initcall and it relies on kvm_guest static key (is_kvm_guest()) which is initialized later during boot by check_kvm_guest(), which is a core_initcall. check_kvm_guest() is also called in pSeries_smp_probe(), which is called before initcalls, but it is skipped if KVM guest does not have doorbell support or if the guest is launched with SMT=1.
Call check_kvm_guest() in disable_hardlockup_detector() so that is_kvm_guest() check goes through fine and hardlockup detector can be disabled inside the KVM guest.
[1]: Documentation/admin-guide/sysctl/kernel.rst
--- arch/powerpc/kernel/setup_64.c | 1 + 1 file changed, 1 insertion(+)
arch/powerpc/kernel/setup_64.c +1 -0
@@ -952,6 +952,7 @@ static int __init disable_hardlockup_dethardlockup_detector_disable ();#else if (firmware_has_feature (FW_FEATURE_LPAR )) { +check_kvm_guest ();if (is_kvm_guest ())hardlockup_detector_disable (); }
Greg Kroah-Hartman
maintainerPATCH 311/565 KVM: arm64: Ignore PMCNTENSET_EL0 while checking for overflow status
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Raghavendra Rao Ananta <[email protected]>
commit 54bbee190d42166209185d89070c58a343bf514b upstream.
DDI0487K.a D13.3.1 describes the PMU overflow condition, which evaluates to true if any counter's global enable (PMCR_EL0.E), overflow flag (PMOVSSET_EL0[n]), and interrupt enable (PMINTENSET_EL1[n]) are all 1. Of note, this does not require a counter to be enabled
(i.e. PMCNTENSET_EL0[n] = 1) to generate an overflow.
Align kvm_pmu_overflow_status() with the reality of the architecture and stop using PMCNTENSET_EL0 as part of the overflow condition. The bug was discovered while running an SBSA PMU test [*], which only sets PMCR.E, PMOVSSET<0>, PMINTENSET<0>, and expects an overflow interrupt.
--- arch/arm64/kvm/pmu-emul.c | 1 - 1 file changed, 1 deletion(-)
arch/arm64/kvm/pmu-emul.c +0 -1
@@ -371,7 +371,6 @@ static u64 kvm_pmu_overflow_status(strucif ((__vcpu_sys_reg (vcpu,PMCR_EL0 ) &ARMV8_PMU_PMCR_E )) { reg =__vcpu_sys_reg (vcpu,PMOVSSET_EL0 ); - reg &=__vcpu_sys_reg (vcpu,PMCNTENSET_EL0 ); reg &=__vcpu_sys_reg (vcpu,PMINTENSET_EL1 ); }
Greg Kroah-Hartman
maintainerPATCH 312/565 PCI: Fix use-after-free of slot->bus on hot remove
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lukas Wunner <[email protected]>
commit c7acef99642b763ba585f4a43af999fcdbcc3dc4 upstream.
Dennis reports a boot crash on recent Lenovo laptops with a USB4 dock.
Since commit 0fc70886569c ("thunderbolt: Reset USB4 v2 host router") and commit 59a54c5f3dbd ("thunderbolt: Reset topology created by the boot firmware"), USB4 v2 and v1 Host Routers are reset on probe of the thunderbolt driver.
The reset clears the Presence Detect State and Data Link Layer Link Active bits at the USB4 Host Router's Root Port and thus causes hot removal of the dock.
The crash occurs when pciehp is unbound from one of the dock's Downstream
Ports: pciehp creates a pci_slot on bind and destroys it on unbind. The pci_slot contains a pointer to the pci_bus below the Downstream Port, but a reference on that pci_bus is never acquired. The pci_bus is destroyed before the pci_slot, so a use-after-free ensues when pci_slot_release() accesses slot->bus.
In principle this should not happen because pci_stop_bus_device() unbinds pciehp (and therefore destroys the pci_slot) before the pci_bus is destroyed by pci_remove_bus_device().
However the stacktrace provided by Dennis shows that pciehp is unbound from pci_remove_bus_device() instead of pci_stop_bus_device(). To understand the significance of this, one needs to know that the PCI core uses a two step process to remove a portion of the hierarchy: It first unbinds all drivers in the sub-hierarchy in pci_stop_bus_device() and then actually removes the devices in pci_remove_bus_device(). There is no precaution to prevent driver binding in-between pci_stop_bus_device() and pci_remove_bus_device().
In Dennis' case, it seems removal of the hierarchy by pciehp races with driver binding by pci_bus_add_devices(). pciehp is bound to the Downstream Port after pci_stop_bus_device() has run, so it is unbound by pci_remove_bus_device() instead of pci_stop_bus_device(). Because the pci_bus has already been destroyed at that point, accesses to it result in a use-after-free.
One might conclude that driver binding needs to be prevented after pci_stop_bus_device() has run. However it seems risky that pci_slot points to pci_bus without holding a reference. Solely relying on correct ordering of driver unbind versus pci_bus destruction is certainly not defensive programming.
If pci_slot has a need to access data in pci_bus, it ought to acquire a reference. Amend pci_create_slot() accordingly. Dennis reports that the crash is not reproducible with this change.
Abridged stacktrace:
pcieport 0000:00:07.0: PME: Signaling with IRQ 156
pcieport 0000:00:07.0: pciehp: Slot #12 AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug+ Surprise+ Interlock- NoCompl+ IbPresDis- LLActRep+ pci_bus 0000:20: dev 00, created physical slot 12
pcieport 0000:00:07.0: pciehp: Slot(12): Card not present
...
pcieport 0000:21:02.0: pciehp: pcie_disable_notification: SLOTCTRL d8 write cmd 0
Oops: general protection fault, probably for non-canonical address 0x6b6b6b6b6b6b6b6b: 0000 [#1] PREEMPT SMP NOPTI CPU: 13 UID: 0 PID: 134 Comm: irq/156-pciehp Not tainted 6.11.0-devel+ #1 RIP: 0010:dev_driver_string+0x12/0x40 pci_destroy_slot pciehp_remove pcie_port_remove_service device_release_driver_internal bus_remove_device device_del device_unregister remove_iter device_for_each_child pcie_portdrv_remove pci_device_remove device_release_driver_internal bus_remove_device device_del pci_remove_bus_device (recursive invocation) pci_remove_bus_device pciehp_unconfigure_device pciehp_disable_slot pciehp_handle_presence_or_link_change pciehp_ist
--- drivers/pci/slot.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/pci/slot.c +3 -1
@@ -79,6 +79,7 @@ static void pci_slot_release(struct kobjup_read (&pci_bus_sem);list_del (&slot->list); +pci_bus_put (slot->bus);kfree (slot); }
@@ -260,7 +261,7 @@ placeholder: goto err; } - slot->bus = parent; + slot->bus =pci_bus_get (parent); slot->number = slot_nr; slot->kobj.kset = pci_slots_kset;
@@ -268,6 +269,7 @@ placeholder: slot_name =make_slot_name (name);if (!slot_name) { err = -ENOMEM ; +pci_bus_put (slot->bus);kfree (slot); goto err; }
Greg Kroah-Hartman
maintainerPATCH 313/565 fsnotify: fix sending inotify event with unexpected filename
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amir Goldstein <[email protected]>
commit aa52c54da40d9eee3ba87c05cdcb0cd07c04fa13 upstream.
We got a report that adding a fanotify filsystem watch prevents tail -f from receiving events.
Reproducer:
1. Create 3 windows / login sessions. Become root in each session.
2. Choose a mounted filesystem that is pretty quiet; I picked /boot.
3. In the first window, run: fsnotifywait -S -m /boot
4. In the second window, run: echo data >> /boot/foo
5. In the third window, run: tail -f /boot/foo
6. Go back to the second window and run: echo more data >> /boot/foo
7. Observe that the tail command doesn't show the new data.
8. In the first window, hit control-C to interrupt fsnotifywait.
9. In the second window, run: echo still more data >> /boot/foo
10. Observe that the tail command in the third window has now printed the missing data.
When stracing tail, we observed that when fanotify filesystem mark is set, tail does get the inotify event, but the event is receieved with the filename:
read(4, "\1\0\0\0\2\0\0\0\0\0\0\0\20\0\0\0foo\0\0\0\0\0\0\0\0\0\0\0\0\0",
50) = 32
This is unexpected, because tail is watching the file itself and not its parent and is inconsistent with the inotify event received by tail when fanotify filesystem mark is not set:
read(4, "\1\0\0\0\2\0\0\0\0\0\0\0\0\0\0\0", 50) = 16
The inteference between different fsnotify groups was caused by the fact that the mark on the sb requires the filename, so the filename is passed to fsnotify(). Later on, fsnotify_handle_event() tries to take care of not passing the filename to groups (such as inotify) that are interested in the filename only when the parent is watching.
But the logic was incorrect for the case that no group is watching the parent, some groups are watching the sb and some watching the inode.
--- fs/notify/fsnotify.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-)
fs/notify/fsnotify.c +13 -10
@@ -310,16 +310,19 @@ static int fsnotify_handle_event(structif (!inode_mark)return 0 ; -if (mask &FS_EVENT_ON_CHILD ) { -/* -* Some events can be sent on both parent dir and child marks -* (e.g. FS_ATTRIB). If both parent dir and child are -* watching, report the event once to parent dir with name (if -* interested) and once to child without name (if interested). -* The child watcher is expecting an event without a file name -* and without the FS_EVENT_ON_CHILD flag. -*/ - mask &= ~FS_EVENT_ON_CHILD ; +/* +* Some events can be sent on both parent dir and child marks (e.g. +* FS_ATTRIB). If both parent dir and child are watching, report the +* event once to parent dir with name (if interested) and once to child +* without name (if interested). +* +* In any case regardless whether the parent is watching or not, the +* child watcher is expecting an event without the FS_EVENT_ON_CHILD +* flag. The file name is expected if and only if this is a directory +* event. +*/ + mask &= ~FS_EVENT_ON_CHILD ; +if (!(mask &ALL_FSNOTIFY_DIRENT_EVENTS )) { dir =NULL ; name =NULL ; }
Greg Kroah-Hartman
maintainerPATCH 314/565 comedi: Flush partial mappings in error case
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jann Horn <[email protected]>
commit ce8f9fb651fac95dd41f69afe54d935420b945bd upstream.
If some remap_pfn_range() calls succeeded before one failed, we still have buffer pages mapped into the userspace page tables when we drop the buffer reference with comedi_buf_map_put(bm). The userspace mappings are only cleaned up later in the mmap error path.
Fix it by explicitly flushing all mappings in our VMA on the error path.
See commit 79a61cc3fc04 ("mm: avoid leaving partial pfn mappings around in error case").
--- drivers/comedi/comedi_fops.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
drivers/comedi/comedi_fops.c +12 -0
@@ -2402,6 +2402,18 @@ static int comedi_mmap(struct file *file start +=PAGE_SIZE ; } + +#ifdef CONFIG_MMU +/* +* Leaving behind a partial mapping of a buffer we're about to +* drop is unsafe, see remap_pfn_range_notrack(). +* We need to zap the range here ourselves instead of relying +* on the automatic zapping in remap_pfn_range() because we call +* remap_pfn_range() in a loop. +*/ +if (retval) +zap_vma_ptes (vma, vma->vm_start, size); +#endif }if (retval ==0 ) {
Greg Kroah-Hartman
maintainerPATCH 315/565 apparmor: test: Fix memory leak for aa_unpack_strdup()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
commit 7290f59231910ccba427d441a6e8b8c6f6112448 upstream.
The string allocated by kmemdup() in aa_unpack_strdup() is not freed and cause following memory leaks, free them to fix it.
unreferenced object 0xffffff80c6af8a50 (size 8): comm "kunit_try_catch", pid 225, jiffies 4294894407 hex dump (first 8 bytes): 74 65 73 74 69 6e 67 00 testing. backtrace (crc 5eab668b): [<0000000001e3714d>] kmemleak_alloc+0x34/0x40 [<000000006e6c7776>] __kmalloc_node_track_caller_noprof+0x300/0x3e0 [<000000006870467c>] kmemdup_noprof+0x34/0x60 [<000000001176bb03>] aa_unpack_strdup+0xd0/0x18c [<000000008ecde918>] policy_unpack_test_unpack_strdup_with_null_name+0xf8/0x3ec [<0000000032ef8f77>] kunit_try_run_case+0x13c/0x3ac [<00000000f3edea23>] kunit_generic_run_threadfn_adapter+0x80/0xec [<00000000adf936cf>] kthread+0x2e8/0x374 [<0000000041bb1628>] ret_from_fork+0x10/0x20 unreferenced object 0xffffff80c2a29090 (size 8): comm "kunit_try_catch", pid 227, jiffies 4294894409 hex dump (first 8 bytes): 74 65 73 74 69 6e 67 00 testing. backtrace (crc 5eab668b): [<0000000001e3714d>] kmemleak_alloc+0x34/0x40 [<000000006e6c7776>] __kmalloc_node_track_caller_noprof+0x300/0x3e0 [<000000006870467c>] kmemdup_noprof+0x34/0x60 [<000000001176bb03>] aa_unpack_strdup+0xd0/0x18c [<0000000046a45c1a>] policy_unpack_test_unpack_strdup_with_name+0xd0/0x3c4 [<0000000032ef8f77>] kunit_try_run_case+0x13c/0x3ac [<00000000f3edea23>] kunit_generic_run_threadfn_adapter+0x80/0xec [<00000000adf936cf>] kthread+0x2e8/0x374 [<0000000041bb1628>] ret_from_fork+0x10/0x20
--- security/apparmor/policy_unpack_test.c | 6 ++++++ 1 file changed, 6 insertions(+)
security/apparmor/policy_unpack_test.c +6 -0
@@ -283,6 +283,8 @@ static void policy_unpack_test_unpack_st ((uintptr_t )puf->e->start <= (uintptr_t )string) && ((uintptr_t)string <= (uintptr_t)puf->e->end));KUNIT_EXPECT_STREQ (test, string,TEST_STRING_DATA ); + +kfree (string); }static void policy_unpack_test_unpack_strdup_with_name (struct kunit *test)
@@ -298,6 +300,8 @@ static void policy_unpack_test_unpack_st ((uintptr_t )puf->e->start <= (uintptr_t )string) && ((uintptr_t)string <= (uintptr_t)puf->e->end));KUNIT_EXPECT_STREQ (test, string,TEST_STRING_DATA ); + +kfree (string); }static void policy_unpack_test_unpack_strdup_out_of_bounds (struct kunit *test)
@@ -315,6 +319,8 @@ static void policy_unpack_test_unpack_stKUNIT_EXPECT_EQ (test, size,0 );KUNIT_EXPECT_PTR_EQ (test, string, (char *)NULL );KUNIT_EXPECT_PTR_EQ (test, puf->e->pos, start); + +kfree (string); }static void policy_unpack_test_unpack_nameX_with_null_name (struct kunit *test)
Greg Kroah-Hartman
maintainerPATCH 316/565 tty: ldsic: fix tty_ldisc_autoload sysctls proc_handler
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicolas Bouchinet <[email protected]>
commit 635a9fca54f4f4148be1ae1c7c6bd37af80f5773 upstream.
Commit 7c0cca7c847e ("tty: ldisc: add sysctl to prevent autoloading of ldiscs") introduces the tty_ldisc_autoload sysctl with the wrong proc_handler. .extra1 and .extra2 parameters are set to avoid other values thant SYSCTL_ZERO or SYSCTL_ONE to be set but proc_dointvec do not uses them.
This commit fixes this by using proc_dointvec_minmax instead of proc_dointvec.
--- drivers/tty/tty_ldisc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/tty/tty_ldisc.c +1 -1
@@ -852,7 +852,7 @@ static struct ctl_table tty_table[] = { .data = &tty_ldisc_autoload, .maxlen = sizeof(tty_ldisc_autoload), .mode = 0644, - .proc_handler = proc_dointvec, + .proc_handler = proc_dointvec_minmax, .extra1 = SYSCTL_ZERO, .extra2 = SYSCTL_ONE, },
Greg Kroah-Hartman
maintainerPATCH 317/565 locking/lockdep: Avoid creating new name string literals in lockdep_set_subclass()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ahmed Ehab <[email protected]>
commit d7fe143cb115076fed0126ad8cf5ba6c3e575e43 upstream.
Syzbot reports a problem that a warning will be triggered while searching a lock class in look_up_lock_class().
The cause of the issue is that a new name is created and used by lockdep_set_subclass() instead of using the existing one. This results in a lock instance has a different name pointer than previous registered one stored in lock class, and WARN_ONCE() is triggered because of that in look_up_lock_class().
To fix this, change lockdep_set_subclass() to use the existing name instead of a new one. Hence, no new name will be created by lockdep_set_subclass(). Hence, the warning is avoided.
[boqun: Reword the commit log to state the correct issue]
--- include/linux/lockdep.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/lockdep.h +1 -1
@@ -233,7 +233,7 @@ static inline void lockdep_init_map(stru (lock)->dep_map.lock_type)#define lockdep_set_subclass (lock, sub) \ - lockdep_init_map_type(&(lock)->dep_map, #lock, (lock)->dep_map.key, sub,\ + lockdep_init_map_type(&(lock)->dep_map, (lock)->dep_map.name, (lock)->dep_map.key, sub,\ (lock)->dep_map.wait_type_inner, \ (lock)->dep_map.wait_type_outer, \ (lock)->dep_map.lock_type)
Greg Kroah-Hartman
maintainerPATCH 318/565 exfat: fix uninit-value in __exfat_get_dentry_set
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <[email protected]>
commit 02dffe9ab092fc4c8800aee68cb7eafd37a980c4 upstream.
There is no check if stream size and start_clu are invalid. If start_clu is EOF cluster and stream size is 4096, It will cause uninit value access. because ei->hint_femp.eidx could be 128(if cluster size is 4K) and wrong hint will allocate next cluster. and this cluster will be same with the cluster that is allocated by exfat_extend_valid_size(). The previous patch will check invalid start_clu, but for clarity, initialize hint_femp.eidx to zero.
--- fs/exfat/namei.c | 1 + 1 file changed, 1 insertion(+)
fs/exfat/namei.c +1 -0
@@ -356,6 +356,7 @@ static int exfat_find_empty_entry(structif (ei->start_clu ==EXFAT_EOF_CLUSTER ) { ei->start_clu = clu.dir; p_dir->dir = clu.dir; + hint_femp.eidx =0 ; }/* append to the FAT chain */
Greg Kroah-Hartman
maintainerPATCH 319/565 Bluetooth: Fix type of len in rfcomm_sock_getsockopt{,_old}()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrej Shadura <[email protected]>
commit 5fe6caa62b07fd39cd6a28acc8f92ba2955e11a6 upstream.
Commit 9bf4e919ccad worked around an issue introduced after an innocuous optimisation change in LLVM main:
Quoted 11 lines
len is defined as an 'int' because it is assigned from '
__userint *optlen'. However, it is clamped against the result ofsizeof(), which has a type of 'size_t' ('unsigned long' for 64-bit platforms). This is done withmin_t()becausemin()requires compatible types, which results in both len and the result ofsizeof()being casted to 'unsigned int', meaning len changes signs and the result ofsizeof()is truncated. From there, len is passed tocopy_to_user(), which has a third parameter type of 'unsigned long', so it is widened and changes signs again. This excessive casting in combination with the KCSAN instrumentation causes LLVM to fail to eliminate the__bad_copy_from()call, failing the build.
The same issue occurs in rfcomm in functions rfcomm_sock_getsockopt and rfcomm_sock_getsockopt_old.
Change the type of len to size_t in both rfcomm_sock_getsockopt and rfcomm_sock_getsockopt_old and replace min_t() with min().
Improves: 9bf4e919ccad ("Bluetooth: Fix type of len in {l2cap,sco}_sock_getsockopt_old()")
--- net/bluetooth/rfcomm/sock.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
net/bluetooth/rfcomm/sock.c +6 -4
@@ -740,7 +740,8 @@ static int rfcomm_sock_getsockopt_old(ststruct sock *l2cap_sk;struct l2cap_conn *conn;struct rfcomm_conninfo cinfo; -int len, err =0 ; +int err =0 ; +size_t len;u32 opt;BT_DBG ("sk %p" , sk);
@@ -794,7 +795,7 @@ static int rfcomm_sock_getsockopt_old(st cinfo.hci_handle = conn->hcon->handle;memcpy (cinfo.dev_class, conn->hcon->dev_class,3 ); - len = min_t(unsigned int, len, sizeof(cinfo)); + len =min (len,sizeof (cinfo));if (copy_to_user (optval, (char *) &cinfo, len)) err = -EFAULT ;
@@ -813,7 +814,8 @@ static int rfcomm_sock_getsockopt(struct {struct sock *sk = sock->sk;struct bt_security sec; -int len, err =0 ; +int err =0 ; +size_t len;BT_DBG ("sk %p" , sk);
@@ -838,7 +840,7 @@ static int rfcomm_sock_getsockopt(struct sec.level =rfcomm_pi (sk)->sec_level; sec.key_size =0 ; - len = min_t(unsigned int, len, sizeof(sec)); + len =min (len,sizeof (sec));if (copy_to_user (optval, (char *) &sec, len)) err = -EFAULT ;
Greg Kroah-Hartman
maintainerPATCH 320/565 usb: xhci: Fix TD invalidation under pending Set TR Dequeue
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Pecio <[email protected]>
commit 484c3bab2d5dfa13ff659a51a06e9a393141eefc upstream.
xhci_invalidate_cancelled_tds() may not work correctly if the hardware is modifying endpoint or stream contexts at the same time by executing a Set TR Dequeue command. And even if it worked, it would be unable to queue Set TR Dequeue for the next stream, failing to clear xHC cache.
On stream endpoints, a chain of Set TR Dequeue commands may take some time to execute and we may want to cancel more TDs during this time. Currently this leads to Stop Endpoint completion handler calling this function without testing for SET_DEQ_PENDING, which will trigger the aforementioned problems when it happens.
On all endpoints, a halt condition causes Reset Endpoint to be queued and an error status given to the class driver, which may unlink more URBs in response. Stop Endpoint is queued and its handler may execute concurrently with Set TR Dequeue queued by Reset Endpoint handler.
(Reset Endpoint handler calls this function too, but there seems to be no possibility of it running concurrently with Set TR Dequeue).
Fix xhci_invalidate_cancelled_tds() to work correctly under a pending Set TR Dequeue. Bail out of the function when SET_DEQ_PENDING is set, then make the completion handler call the function again and also call xhci_giveback_invalidated_tds(), which needs to be called next.
This seems to fix another potential bug, where the handler would call xhci_invalidate_cancelled_tds(), which may clear some deferred TDs if a sanity check fails, and the TDs wouldn't be given back promptly.
Said sanity check seems to be wrong and prone to false positives when the endpoint halts, but fixing it is beyond the scope of this change, besides ensuring that cleared TDs are given back properly.
--- drivers/usb/host/xhci-ring.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)
drivers/usb/host/xhci-ring.c +13 -5
@@ -961,6 +961,13 @@ static int xhci_invalidate_cancelled_tdsunsigned int slot_id = ep->vdev->slot_id;int err; +/* +* This is not going to work if the hardware is changing its dequeue +* pointers as we look at them. Completion handler will call us later. +*/ +if (ep->ep_state &SET_DEQ_PENDING ) +return 0 ; + xhci = ep->xhci;list_for_each_entry_safe (td, tmp_td, &ep->cancelled_td_list, cancelled_td_list) {
@@ -1386,7 +1393,6 @@ static void xhci_handle_cmd_set_deq(strustruct xhci_ep_ctx *ep_ctx;struct xhci_slot_ctx *slot_ctx;struct xhci_td *td, *tmp_td; -bool deferred = false; ep_index =TRB_TO_EP_INDEX (le32_to_cpu (trb->generic.field[3 ])); stream_id =TRB_TO_STREAM_ID (le32_to_cpu (trb->generic.field[2 ]));
@@ -1487,8 +1493,6 @@ static void xhci_handle_cmd_set_deq(struxhci_dbg (ep->xhci,"%s: Giveback cancelled URB %p TD\n" , __func__, td->urb);xhci_td_cleanup (ep->xhci, td, ep_ring, td->status); - }else if (td->cancel_status ==TD_CLEARING_CACHE_DEFERRED ) { - deferred = true; }else {xhci_dbg (ep->xhci,"%s: Keep cancelled URB %p TD as cancel_status is %d\n" , __func__, td->urb, td->cancel_status);
@@ -1499,11 +1503,15 @@ cleanup: ep->queued_deq_seg =NULL ; ep->queued_deq_ptr =NULL ; -if (deferred) { -/* We have more streams to clear */ +/* Check for deferred or newly cancelled TDs */ +if (!list_empty (&ep->cancelled_td_list)) {xhci_dbg (ep->xhci,"%s: Pending TDs to clear, continuing with invalidation\n" , __func__);xhci_invalidate_cancelled_tds (ep); +/* Try to restart the endpoint if all is done */ +ring_doorbell_for_active_rings (xhci, slot_id, ep_index); +/* Start giving back any TDs invalidated above */ +xhci_giveback_invalidated_tds (ep); }else {/* Restart any rings with pending URBs */ xhci_dbg (ep->xhci,"%s: All TDs cleared, ring doorbell\n" , __func__);
Greg Kroah-Hartman
maintainerPATCH 321/565 driver core: bus: Fix double free in driver API bus_register()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zijun Hu <[email protected]>
commit bfa54a793ba77ef696755b66f3ac4ed00c7d1248 upstream.
For bus_register(), any error which happens after kset_register() will cause that @priv are freed twice, fixed by setting @priv with NULL after the first free.
--- drivers/base/bus.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/base/bus.c +2 -0
@@ -853,6 +853,8 @@ bus_devices_fail:bus_remove_file (bus, &bus_attr_uevent); bus_uevent_fail:kset_unregister (&bus->p->subsys); +/* Above kset_unregister() will kfree @bus->p */ + bus->p =NULL ; out:kfree (bus->p); bus->p =NULL ;
Greg Kroah-Hartman
maintainerPATCH 322/565 Revert "usb: gadget: composite: fix OS descriptors w_value logic"
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Vrastil <[email protected]>
commit 51cdd69d6a857f527d6d0697a2e1f0fa8bca1005 upstream.
This reverts commit ec6ce7075ef879b91a8710829016005dc8170f17.
Fix installation of WinUSB driver using OS descriptors. Without the fix the drivers are not installed correctly and the property 'DeviceInterfaceGUID' is missing on host side.
The original change was based on the assumption that the interface number is in the high byte of wValue but it is in the low byte, instead. Unfortunately, the fix is based on MS documentation which is also wrong.
The actual USB request for OS descriptors (using USB analyzer) looks like:
Offset 0 1 2 3 4 5 6 7 0x000 C1 A1 02 00 05 00 0A 00
C1: bmRequestType (device to host, vendor, interface)
A1: nas magic number
0002: wValue (2: nas interface)
0005: wIndex (5: get extended property i.e. nas interface GUID) 008E: wLength (142)
The fix was tested on Windows 10 and Windows 11.
--- drivers/usb/gadget/composite.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
drivers/usb/gadget/composite.c +15 -3
@@ -2017,8 +2017,20 @@ unknown:memset (buf,0 , w_length); buf[5 ] =0x01 ;switch (ctrl->bRequestType &USB_RECIP_MASK ) { +/* +* The Microsoft CompatID OS Descriptor Spec(w_index = 0x4) and +* Extended Prop OS Desc Spec(w_index = 0x5) state that the +* HighByte of wValue is the InterfaceNumber and the LowByte is +* the PageNumber. This high/low byte ordering is incorrectly +* documented in the Spec. USB analyzer output on the below +* request packets show the high/low byte inverted i.e LowByte +* is the InterfaceNumber and the HighByte is the PageNumber. +* Since we dont support >64KB CompatID/ExtendedProp descriptors, +* PageNumber is set to 0. Hence verify that the HighByte is 0 +* for below two cases. +*/ case USB_RECIP_DEVICE : -if (w_index !=0x4 || (w_value &0xff )) +if (w_index !=0x4 || (w_value >>8 ))break ; buf[6 ] = w_index;/* Number of ext compat interfaces */
@@ -2034,9 +2046,9 @@ unknown: }break ;case USB_RECIP_INTERFACE : -if (w_index !=0x5 || (w_value &0xff )) +if (w_index !=0x5 || (w_value >>8 ))break ; - interface = w_value >>8 ; + interface = w_value &0xFF ;if (interface >=MAX_CONFIG_INTERFACES || !os_desc_cfg->interface[interface])break ;
Greg Kroah-Hartman
maintainerPATCH 323/565 serial: sh-sci: Clean sci_ports[0] after at earlycon exit
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Claudiu Beznea <[email protected]>
commit 3791ea69a4858b81e0277f695ca40f5aae40f312 upstream.
The early_console_setup() function initializes the sci_ports[0].port with an object of type struct uart_port obtained from the object of type struct earlycon_device received as argument by the early_console_setup().
It may happen that later, when the rest of the serial ports are probed, the serial port that was used as earlycon (e.g., port A) to be mapped to a different position in sci_ports[] and the slot 0 to be used by a different serial port (e.g., port B), as follows:
sci_ports[0] = port A
sci_ports[X] = port B
In this case, the new port mapped at index zero will have associated data that was used for earlycon.
In case this happens, after Linux boot, any access to the serial port that maps on sci_ports[0] (port A) will block the serial port that was used as earlycon (port B).
To fix this, add early_console_exit() that clean the sci_ports[0] at earlycon exit time.
--- drivers/tty/serial/sh-sci.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
drivers/tty/serial/sh-sci.c +28 -0
@@ -3433,6 +3433,32 @@ sh_early_platform_init_buffer("earlyprin#ifdef CONFIG_SERIAL_SH_SCI_EARLYCON static struct plat_sci_port port_cfg__initdata ; +static int early_console_exit (struct console *co) +{ +struct sci_port *sci_port = &sci_ports[0 ]; +struct uart_port *port = &sci_port->port; +unsigned long flags; +int locked =1 ; + +if (port->sysrq) + locked =0 ; +else if (oops_in_progress) + locked =uart_port_trylock_irqsave (port, &flags); +else +uart_port_lock_irqsave (port, &flags); + +/* +* Clean the slot used by earlycon. A new SCI device might +* map to this slot. +*/ +memset (sci_ports,0 ,sizeof (*sci_port)); + +if (locked) +uart_port_unlock_irqrestore (port, flags); + +return 0 ; +} +static int __init early_console_setup (struct earlycon_device *device,int type) {
@@ -3451,6 +3477,8 @@ static int __init early_console_setup(st SCSCR_RE | SCSCR_TE | port_cfg.scscr); device->con->write = serial_console_write; + device->con->exit = early_console_exit; +return 0 ; } static int __init sci_early_console_setup(struct earlycon_device *device,
Greg Kroah-Hartman
maintainerPATCH 324/565 Revert "serial: sh-sci: Clean sci_ports[0] after at earlycon exit"
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Greg Kroah-Hartman <[email protected]>
commit 718632467d88e98816fa01ab12681ef1c2aa56f8 upstream.
This reverts commit 3791ea69a4858b81e0277f695ca40f5aae40f312.
It was reported to cause boot-time issues, so revert it for now.
--- drivers/tty/serial/sh-sci.c | 28 ---------------------------- 1 file changed, 28 deletions(-)
drivers/tty/serial/sh-sci.c +0 -28
@@ -3433,32 +3433,6 @@ sh_early_platform_init_buffer("earlyprin#ifdef CONFIG_SERIAL_SH_SCI_EARLYCON static struct plat_sci_port port_cfg__initdata ; -static int early_console_exit (struct console *co) -{ -struct sci_port *sci_port = &sci_ports[0 ]; -struct uart_port *port = &sci_port->port; -unsigned long flags; -int locked =1 ; - -if (port->sysrq) - locked =0 ; -else if (oops_in_progress) - locked =uart_port_trylock_irqsave (port, &flags); -else -uart_port_lock_irqsave (port, &flags); - -/* -* Clean the slot used by earlycon. A new SCI device might -* map to this slot. -*/ -memset (sci_ports,0 ,sizeof (*sci_port)); - -if (locked) -uart_port_unlock_irqrestore (port, flags); - -return 0 ; -} -static int __init early_console_setup (struct earlycon_device *device,int type) {
@@ -3477,8 +3451,6 @@ static int __init early_console_setup(st SCSCR_RE | SCSCR_TE | port_cfg.scscr); device->con->write = serial_console_write; - device->con->exit = early_console_exit; -return 0 ; } static int __init sci_early_console_setup(struct earlycon_device *device,
Greg Kroah-Hartman
maintainerPATCH 325/565 gpio: exar: set value when external pull-up or pull-down is present
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sai Kumar Cholleti <[email protected]>
commit 72cef64180de04a7b055b4773c138d78f4ebdb77 upstream.
Setting GPIO direction = high, sometimes results in GPIO value = 0.
If a GPIO is pulled high, the following construction results in the value being 0 when the desired value is 1:
$ echo "high" > /sys/class/gpio/gpio336/direction $ cat /sys/class/gpio/gpio336/value 0
Before the GPIO direction is changed from an input to an output, exar_set_value() is called with value = 1, but since the GPIO is an input when exar_set_value() is called, _regmap_update_bits() reads a 1 due to an external pull-up. regmap_set_bits() sets force_write = false, so the value (1) is not written. When the direction is then changed, the GPIO becomes an output with the value of 0 (the hardware default).
regmap_write_bits() sets force_write = true, so the value is always written by exar_set_value() and an external pull-up doesn't affect the outcome of setting direction = high.
The same can happen when a GPIO is pulled low, but the scenario is a little more complicated.
$ echo high > /sys/class/gpio/gpio351/direction $ cat /sys/class/gpio/gpio351/value 1
$ echo in > /sys/class/gpio/gpio351/direction $ cat /sys/class/gpio/gpio351/value 0
$ echo low > /sys/class/gpio/gpio351/direction $ cat /sys/class/gpio/gpio351/value 1
--- drivers/gpio/gpio-exar.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/gpio/gpio-exar.c +6 -4
@@ -80,11 +80,13 @@ static void exar_set_value(struct gpio_cstruct exar_gpio_chip *exar_gpio =gpiochip_get_data (chip);unsigned int addr =exar_offset_to_lvl_addr (exar_gpio, offset);unsigned int bit =exar_offset_to_bit (exar_gpio, offset); +unsigned int bit_value = value ?BIT (bit) :0 ; -if (value) -regmap_set_bits (exar_gpio->regmap, addr,BIT (bit)); -else -regmap_clear_bits (exar_gpio->regmap, addr,BIT (bit)); +/* +* regmap_write_bits() forces value to be written when an external +* pull up/down might otherwise indicate value was already set. +*/ +regmap_write_bits (exar_gpio->regmap, addr,BIT (bit), bit_value); } static int exar_direction_output(struct gpio_chip *chip, unsigned int offset,
Greg Kroah-Hartman
maintainerPATCH 326/565 netfilter: ipset: add missing range check in bitmap_ip_uadt
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeongjun Park <[email protected]>
commit 35f56c554eb1b56b77b3cf197a6b00922d49033d upstream.
When tb[IPSET_ATTR_IP_TO] is not present but tb[IPSET_ATTR_CIDR] exists, the values of ip and ip_to are slightly swapped. Therefore, the range check for ip should be done later, but this part is missing and it seems that the vulnerability occurs.
So we should add missing range checks and remove unnecessary range checks.
--- net/netfilter/ipset/ip_set_bitmap_ip.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
net/netfilter/ipset/ip_set_bitmap_ip.c +2 -5
@@ -163,11 +163,8 @@ bitmap_ip_uadt(struct ip_set *set, struc ret =ip_set_get_hostipaddr4 (tb[IPSET_ATTR_IP_TO ], &ip_to);if (ret)return ret; -if (ip > ip_to) { +if (ip > ip_to)swap (ip, ip_to); -if (ip < map->first_ip) -return -IPSET_ERR_BITMAP_RANGE ; - } }else if (tb[IPSET_ATTR_CIDR ]) {u8 cidr =nla_get_u8 (tb[IPSET_ATTR_CIDR ]);
@@ -178,7 +175,7 @@ bitmap_ip_uadt(struct ip_set *set, struc ip_to = ip; } -if (ip_to > map->last_ip) +if (ip < map->first_ip || ip_to > map->last_ip)return -IPSET_ERR_BITMAP_RANGE ;for (; !before (ip_to, ip); ip += map->hosts) {
Greg Kroah-Hartman
maintainerPATCH 327/565 spi: Fix acpi deferred irq probe
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stanislaw Gruszka <[email protected]>
commit d24cfee7f63d6b44d45a67c5662bd1cc48e8b3ca upstream.
When probing spi device take care of deferred probe of ACPI irq gpio similar like for OF/DT case.
Quoted 1 line
From practical standpoint this fixes issue with vsc-tp driver on
Dell XP 9340 laptop, which try to request interrupt with spi->irq equal to -EPROBE_DEFER and fail to probe with the following error:
vsc-tp spi-INTC10D0:00: probe with driver vsc-tp failed with error -22
--- drivers/spi/spi.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
drivers/spi/spi.c +10 -3
@@ -400,6 +400,16 @@ static int spi_probe(struct device *dev) spi->irq =0 ; } +if (has_acpi_companion (dev) && spi->irq <0 ) { +struct acpi_device *adev =to_acpi_device_node (dev->fwnode); + + spi->irq =acpi_dev_gpio_irq_get (adev,0 ); +if (spi->irq == -EPROBE_DEFER ) +return -EPROBE_DEFER ; +if (spi->irq <0 ) + spi->irq =0 ; + } + ret =dev_pm_domain_attach (dev, true);if (ret)return ret;
@@ -2406,9 +2416,6 @@ static acpi_status acpi_register_spi_devacpi_set_modalias (adev,acpi_device_hid (adev), spi->modalias,sizeof (spi->modalias)); -if (spi->irq <0 ) - spi->irq =acpi_dev_gpio_irq_get (adev,0 ); -acpi_device_set_enumerated (adev); adev->power.flags.ignore_parent = true;
Greg Kroah-Hartman
maintainerPATCH 328/565 mtd: spi-nor: core: replace dummy buswidth from addr to data
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cheng Ming Lin <[email protected]>
commit 98d1fb94ce75f39febd456d6d3cbbe58b6678795 upstream.
The default dummy cycle for Macronix SPI NOR flash in Octal Output Read Mode(1-1-8) is 20.
Currently, the dummy buswidth is set according to the address bus width. In the 1-1-8 mode, this means the dummy buswidth is 1. When converting dummy cycles to bytes, this results in 20 x 1 / 8 = 2 bytes, causing the host to read data 4 cycles too early.
Since the protocol data buswidth is always greater than or equal to the address buswidth. Setting the dummy buswidth to match the data buswidth increases the likelihood that the dummy cycle-to-byte conversion will be divisible, preventing the host from reading data prematurely.
--- drivers/mtd/spi-nor/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mtd/spi-nor/core.c +1 -1
@@ -89,7 +89,7 @@ void spi_nor_spimem_setup_op(const struc op->addr.buswidth =spi_nor_get_protocol_addr_nbits (proto);if (op->dummy.nbytes) - op->dummy.buswidth =spi_nor_get_protocol_addr_nbits (proto); + op->dummy.buswidth =spi_nor_get_protocol_data_nbits (proto);if (op->data.nbytes) op->data.buswidth =spi_nor_get_protocol_data_nbits (proto);
Greg Kroah-Hartman
maintainerPATCH 329/565 cpufreq: mediatek-hw: Fix wrong return value in mtk_cpufreq_get_cpu_power()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
commit 172bf5ed04cb6c9e66d58de003938ed5c8756570 upstream.
mtk_cpufreq_get_cpu_power() return 0 if the policy is NULL. Then in em_create_perf_table(), the later zero check for power is not invalid as power is uninitialized. As Lukasz suggested, it must return -EINVAL when the 'policy' is not found. So return -EINVAL to fix it.
--- drivers/cpufreq/mediatek-cpufreq-hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/cpufreq/mediatek-cpufreq-hw.c +1 -1
@@ -60,7 +60,7 @@ mtk_cpufreq_get_cpu_power(unsigned long policy =cpufreq_cpu_get_raw (cpu_dev->id);if (!policy) -return 0 ; +return -EINVAL ; data = policy->driver_data;
Greg Kroah-Hartman
maintainerPATCH 330/565 platform/chrome: cros_ec_typec: fix missing fwnode reference decrement
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Javier Carrasco <[email protected]>
commit 9c41f371457bd9a24874e3c7934d9745e87fbc58 upstream.
The device_for_each_child_node() macro requires explicit calls to fwnode_handle_put() upon early exits (return, break, goto) to decrement the fwnode's refcount, and avoid levaing a node reference behind.
Add the missing fwnode_handle_put() after the common label for all error paths.
--- drivers/platform/chrome/cros_ec_typec.c | 1 + 1 file changed, 1 insertion(+)
drivers/platform/chrome/cros_ec_typec.c +1 -0
@@ -375,6 +375,7 @@ static int cros_typec_init_ports(structreturn 0 ; unregister_ports: +fwnode_handle_put (fwnode);cros_unregister_ports (typec);return ret; }
Greg Kroah-Hartman
maintainerPATCH 331/565 ubi: wl: Put source PEB into correct list if trying locking LEB failed
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhihao Cheng <[email protected]>
commit d610020f030bec819f42de327c2bd5437d2766b3 upstream.
During wear-leveing work, the source PEB will be moved into scrub list when source LEB cannot be locked in ubi_eba_copy_leb(), which is wrong for non-scrub type source PEB. The problem could bring extra and ineffective wear-leveing jobs, which makes more or less negative effects for the life time of flash. Specifically, the process is divided 2 steps:
1. wear_leveling_worker // generate false scrub type PEB ubi_eba_copy_leb // MOVE_RETRY is returned leb_write_trylock // trylock failed
scrubbing = 1;
e1 is put into ubi->scrub
2. wear_leveling_worker // schedule false scrub type PEB for wl scrubbing = 1
e1 = rb_entry(rb_first(&ubi->scrub))
The problem can be reproduced easily by running fsstress on a small UBIFS partition(<64M, simulated by nandsim) for 5~10mins (CONFIG_MTD_UBI_FASTMAP=y,CONFIG_MTD_UBI_WL_THRESHOLD=50). Following message is shown:
ubi0: scrubbed PEB 66 (LEB 0:10), data moved to PEB 165
Since scrub type source PEB has set variable scrubbing as '1', and variable scrubbing is checked before variable keep, so the problem can be fixed by setting keep variable as 1 directly if the source LEB cannot be locked.
--- drivers/mtd/ubi/wl.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/mtd/ubi/wl.c +8 -1
@@ -830,7 +830,14 @@ static int wear_leveling_worker(struct u goto out_not_moved; }if (err ==MOVE_RETRY ) { - scrubbing =1 ; +/* +* For source PEB: +* 1. The scrubbing is set for scrub type PEB, it will +* be put back into ubi->scrub list. +* 2. Non-scrub type PEB will be put back into ubi->used +* list. +*/ + keep =1 ; dst_leb_clean =1 ; goto out_not_moved; }
Greg Kroah-Hartman
maintainerPATCH 332/565 um: ubd: Do not use drvdata in release
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tiwei Bie <[email protected]>
commit 5bee35e5389f450a7eea7318deb9073e9414d3b1 upstream.
The drvdata is not available in release. Let's just use container_of() to get the ubd instance. Otherwise, removing a ubd device will result in a crash:
RIP: 0033:blk_mq_free_tag_set+0x1f/0xba RSP: 00000000e2083bf0 EFLAGS: 00010246 RAX: 000000006021463a RBX: 0000000000000348 RCX: 0000000062604d00 RDX: 0000000004208060 RSI: 00000000605241a0 RDI: 0000000000000348 RBP: 00000000e2083c10 R08: 0000000062414010 R09: 00000000601603f7 R10: 000000000000133a R11: 000000006038c4bd R12: 0000000000000000 R13: 0000000060213a5c R14: 0000000062405d20 R15: 00000000604f7aa0 Kernel panic - not syncing: Segfault with no mm CPU: 0 PID: 17 Comm: kworker/0:1 Not tainted 6.8.0-rc3-00107-gba3f67c11638 #1 Workqueue: events mc_work_proc Stack: 00000000 604f7ef0 62c5d000 62405d20 e2083c30 6002c776 6002c755 600e47ff e2083c60 6025ffe3 04208060 603d36e0 Call Trace: [<6002c776>] ubd_device_release+0x21/0x55 [<6002c755>] ? ubd_device_release+0x0/0x55 [<600e47ff>] ? kfree+0x0/0x100 [<6025ffe3>] device_release+0x70/0xba [<60381d6a>] kobject_put+0xb5/0xe2 [<6026027b>] put_device+0x19/0x1c [<6026a036>] platform_device_put+0x26/0x29 [<6026ac5a>] platform_device_unregister+0x2c/0x2e [<6002c52e>] ubd_remove+0xb8/0xd6 [<6002bb74>] ? mconsole_reply+0x0/0x50 [<6002b926>] mconsole_remove+0x160/0x1cc [<6002bbbc>] ? mconsole_reply+0x48/0x50 [<6003379c>] ? um_set_signals+0x3b/0x43 [<60061c55>] ? update_min_vruntime+0x14/0x70 [<6006251f>] ? dequeue_task_fair+0x164/0x235 [<600620aa>] ? update_cfs_group+0x0/0x40 [<603a0e77>] ? __schedule+0x0/0x3ed [<60033761>] ? um_set_signals+0x0/0x43 [<6002af6a>] mc_work_proc+0x77/0x91 [<600520b4>] process_scheduled_works+0x1af/0x2c3 [<6004ede3>] ? assign_work+0x0/0x58 [<600527a1>] worker_thread+0x2f7/0x37a [<6004ee3b>] ? set_pf_worker+0x0/0x64 [<6005765d>] ? arch_local_irq_save+0x0/0x2d [<60058e07>] ? kthread_exit+0x0/0x3a [<600524aa>] ? worker_thread+0x0/0x37a [<60058f9f>] kthread+0x130/0x135 [<6002068e>] new_thread_handler+0x85/0xb6
--- arch/um/drivers/ubd_kern.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/um/drivers/ubd_kern.c +1 -1
@@ -814,7 +814,7 @@ static int ubd_open_dev(struct ubd *ubd_static void ubd_device_release (struct device *dev) { -struct ubd *ubd_dev =dev_get_drvdata (dev); + struct ubd *ubd_dev = container_of(dev, struct ubd, pdev.dev);blk_mq_free_tag_set (&ubd_dev->tag_set); *ubd_dev = ((struct ubd )DEFAULT_UBD );
Greg Kroah-Hartman
maintainerPATCH 333/565 um: net: Do not use drvdata in release
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tiwei Bie <[email protected]>
commit d1db692a9be3b4bd3473b64fcae996afaffe8438 upstream.
The drvdata is not available in release. Let's just use container_of() to get the uml_net instance. Otherwise, removing a network device will result in a crash:
RIP: 0033:net_device_release+0x10/0x6f RSP: 00000000e20c7c40 EFLAGS: 00010206 RAX: 000000006002e4e7 RBX: 00000000600f1baf RCX: 00000000624074e0 RDX: 0000000062778000 RSI: 0000000060551c80 RDI: 00000000627af028 RBP: 00000000e20c7c50 R08: 00000000603ad594 R09: 00000000e20c7b70 R10: 000000000000135a R11: 00000000603ad422 R12: 0000000000000000 R13: 0000000062c7af00 R14: 0000000062406d60 R15: 00000000627700b6 Kernel panic - not syncing: Segfault with no mm CPU: 0 UID: 0 PID: 29 Comm: kworker/0:2 Not tainted 6.12.0-rc6-g59b723cd2adb #1 Workqueue: events mc_work_proc Stack: 627af028 62c7af00 e20c7c80 60276fcd 62778000 603f5820 627af028 00000000 e20c7cb0 603a2bcd 627af000 62770010 Call Trace: [<60276fcd>] device_release+0x70/0xba [<603a2bcd>] kobject_put+0xba/0xe7 [<60277265>] put_device+0x19/0x1c [<60281266>] platform_device_put+0x26/0x29 [<60281e5f>] platform_device_unregister+0x2c/0x2e [<6002ec9c>] net_remove+0x63/0x69 [<60031316>] ? mconsole_reply+0x0/0x50 [<600310c8>] mconsole_remove+0x160/0x1cc [<60087d40>] ? __remove_hrtimer+0x38/0x74 [<60087ff8>] ? hrtimer_try_to_cancel+0x8c/0x98 [<6006b3cf>] ? dl_server_stop+0x3f/0x48 [<6006b390>] ? dl_server_stop+0x0/0x48 [<600672e8>] ? dequeue_entities+0x327/0x390 [<60038fa6>] ? um_set_signals+0x0/0x43 [<6003070c>] mc_work_proc+0x77/0x91 [<60057664>] process_scheduled_works+0x1b3/0x2dd [<60055f32>] ? assign_work+0x0/0x58 [<60057f0a>] worker_thread+0x1e9/0x293 [<6005406f>] ? set_pf_worker+0x0/0x64 [<6005d65d>] ? arch_local_irq_save+0x0/0x2d [<6005d748>] ? kthread_exit+0x0/0x3a [<60057d21>] ? worker_thread+0x0/0x293 [<6005dbf1>] kthread+0x126/0x12b [<600219c5>] new_thread_handler+0x85/0xb6
--- arch/um/drivers/net_kern.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/um/drivers/net_kern.c +1 -1
@@ -335,7 +335,7 @@ static struct platform_driver uml_net_drstatic void net_device_release (struct device *dev) { -struct uml_net *device =dev_get_drvdata (dev); + struct uml_net *device = container_of(dev, struct uml_net, pdev.dev);struct net_device *netdev = device->dev;struct uml_net_private *lp =netdev_priv (netdev);
Greg Kroah-Hartman
maintainerPATCH 334/565 serial: 8250: omap: Move pm_runtime_get_sync
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bin Liu <[email protected]>
commit bcc7ba668818dcadd2f1db66b39ed860a63ecf97 upstream.
Currently in omap_8250_shutdown, the dma->rx_running flag is set to zero in omap_8250_rx_dma_flush. Next pm_runtime_get_sync is called, which is a runtime resume call stack which can re-set the flag. When the call omap_8250_shutdown returns, the flag is expected to be UN-SET, but this is not the case. This is causing issues the next time UART is re-opened and omap_8250_rx_dma is called. Fix by moving pm_runtime_get_sync before the omap_8250_rx_dma_flush.
--- drivers/tty/serial/8250/8250_omap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/tty/serial/8250/8250_omap.c +2 -2
@@ -763,12 +763,12 @@ static void omap_8250_shutdown(struct uastruct uart_8250_port *up =up_to_u8250p (port);struct omap8250_priv *priv = port->private_data; +pm_runtime_get_sync (port->dev); +flush_work (&priv->qos_work);if (up->dma)omap_8250_rx_dma_flush (up); -pm_runtime_get_sync (port->dev); -serial_out (up,UART_OMAP_WER ,0 );if (priv->habit &UART_HAS_EFR2 )serial_out (up,UART_OMAP_EFR2 ,0x0 );
Greg Kroah-Hartman
maintainerPATCH 335/565 um: vector: Do not use drvdata in release
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tiwei Bie <[email protected]>
commit 51b39d741970742a5c41136241a9c48ac607cf82 upstream.
The drvdata is not available in release. Let's just use container_of() to get the vector_device instance. Otherwise, removing a vector device will result in a crash:
RIP: 0033:vector_device_release+0xf/0x50 RSP: 00000000e187bc40 EFLAGS: 00010202 RAX: 0000000060028f61 RBX: 00000000600f1baf RCX: 00000000620074e0 RDX: 000000006220b9c0 RSI: 0000000060551c80 RDI: 0000000000000000 RBP: 00000000e187bc50 R08: 00000000603ad594 R09: 00000000e187bb70 R10: 000000000000135a R11: 00000000603ad422 R12: 00000000623ae028 R13: 000000006287a200 R14: 0000000062006d30 R15: 00000000623700b6 Kernel panic - not syncing: Segfault with no mm CPU: 0 UID: 0 PID: 16 Comm: kworker/0:1 Not tainted 6.12.0-rc6-g59b723cd2adb #1 Workqueue: events mc_work_proc Stack: 60028f61 623ae028 e187bc80 60276fcd 6220b9c0 603f5820 623ae028 00000000 e187bcb0 603a2bcd 623ae000 62370010 Call Trace: [<60028f61>] ? vector_device_release+0x0/0x50 [<60276fcd>] device_release+0x70/0xba [<603a2bcd>] kobject_put+0xba/0xe7 [<60277265>] put_device+0x19/0x1c [<60281266>] platform_device_put+0x26/0x29 [<60281e5f>] platform_device_unregister+0x2c/0x2e [<60029422>] vector_remove+0x52/0x58 [<60031316>] ? mconsole_reply+0x0/0x50 [<600310c8>] mconsole_remove+0x160/0x1cc [<603b19f4>] ? strlen+0x0/0x15 [<60066611>] ? __dequeue_entity+0x1a9/0x206 [<600666a7>] ? set_next_entity+0x39/0x63 [<6006666e>] ? set_next_entity+0x0/0x63 [<60038fa6>] ? um_set_signals+0x0/0x43 [<6003070c>] mc_work_proc+0x77/0x91 [<60057664>] process_scheduled_works+0x1b3/0x2dd [<60055f32>] ? assign_work+0x0/0x58 [<60057f0a>] worker_thread+0x1e9/0x293 [<6005406f>] ? set_pf_worker+0x0/0x64 [<6005d65d>] ? arch_local_irq_save+0x0/0x2d [<6005d748>] ? kthread_exit+0x0/0x3a [<60057d21>] ? worker_thread+0x0/0x293 [<6005dbf1>] kthread+0x126/0x12b [<600219c5>] new_thread_handler+0x85/0xb6
--- arch/um/drivers/vector_kern.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/um/drivers/vector_kern.c +2 -1
@@ -826,7 +826,8 @@ static struct platform_driver uml_net_drstatic void vector_device_release (struct device *dev) { -struct vector_device *device =dev_get_drvdata (dev); +struct vector_device *device = + container_of(dev, struct vector_device, pdev.dev);struct net_device *netdev = device->dev;list_del (&device->list);
Greg Kroah-Hartman
maintainerPATCH 336/565 sh: cpuinfo: Fix a warning for CONFIG_CPUMASK_OFFSTACK
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huacai Chen <[email protected]>
commit 3c891f7c6a4e90bb1199497552f24b26e46383bc upstream.
When CONFIG_CPUMASK_OFFSTACK and CONFIG_DEBUG_PER_CPU_MAPS are selected, cpu_max_bits_warn() generates a runtime warning similar as below when showing /proc/cpuinfo. Fix this by using nr_cpu_ids (the runtime limit) instead of NR_CPUS to iterate CPUs.
[ 3.052463] ------------[ cut here ]------------ [ 3.059679] WARNING: CPU: 3 PID: 1 at include/linux/cpumask.h:108 show_cpuinfo+0x5e8/0x5f0 [ 3.070072] Modules linked in: efivarfs autofs4 [ 3.076257] CPU: 0 PID: 1 Comm: systemd Not tainted 5.19-rc5+ #1052 [ 3.099465] Stack : 9000000100157b08 9000000000f18530 9000000000cf846c 9000000100154000 [ 3.109127] 9000000100157a50 0000000000000000 9000000100157a58 9000000000ef7430 [ 3.118774] 90000001001578e8 0000000000000040 0000000000000020 ffffffffffffffff [ 3.128412] 0000000000aaaaaa 1ab25f00eec96a37 900000010021de80 900000000101c890 [ 3.138056] 0000000000000000 0000000000000000 0000000000000000 0000000000aaaaaa [ 3.147711] ffff8000339dc220 0000000000000001 0000000006ab4000 0000000000000000 [ 3.157364] 900000000101c998 0000000000000004 9000000000ef7430 0000000000000000 [ 3.167012] 0000000000000009 000000000000006c 0000000000000000 0000000000000000 [ 3.176641] 9000000000d3de08 9000000001639390 90000000002086d8 00007ffff0080286 [ 3.186260] 00000000000000b0 0000000000000004 0000000000000000 0000000000071c1c [ 3.195868] ... [ 3.199917] Call Trace: [ 3.203941] [<90000000002086d8>] show_stack+0x38/0x14c [ 3.210666] [<9000000000cf846c>] dump_stack_lvl+0x60/0x88 [ 3.217625] [<900000000023d268>] __warn+0xd0/0x100 [ 3.223958] [<9000000000cf3c90>] warn_slowpath_fmt+0x7c/0xcc [ 3.231150] [<9000000000210220>] show_cpuinfo+0x5e8/0x5f0 [ 3.238080] [<90000000004f578c>] seq_read_iter+0x354/0x4b4 [ 3.245098] [<90000000004c2e90>] new_sync_read+0x17c/0x1c4 [ 3.252114] [<90000000004c5174>] vfs_read+0x138/0x1d0 [ 3.258694] [<90000000004c55f8>] ksys_read+0x70/0x100 [ 3.265265] [<9000000000cfde9c>] do_syscall+0x7c/0x94 [ 3.271820] [<9000000000202fe4>] handle_syscall+0xc4/0x160 [ 3.281824] ---[ end trace 8b484262b4b8c24c ]---
--- arch/sh/kernel/cpu/proc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/sh/kernel/cpu/proc.c +1 -1
@@ -132,7 +132,7 @@ static int show_cpuinfo(struct seq_filestatic void *c_start (struct seq_file *m,loff_t *pos) { -return *pos <NR_CPUS ? cpu_data + *pos :NULL ; +return *pos < nr_cpu_ids ? cpu_data + *pos :NULL ; }static void *c_next (struct seq_file *m,void *v,loff_t *pos) {
Greg Kroah-Hartman
maintainerPATCH 337/565 arm64: tls: Fix context-switching of tpidrro_el0 when kpti is enabled
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Will Deacon <[email protected]>
commit 67ab51cbdfee02ef07fb9d7d14cc0bf6cb5a5e5c upstream.
Commit 18011eac28c7 ("arm64: tls: Avoid unconditional zeroing of tpidrro_el0 for native tasks") tried to optimise the context switching of tpidrro_el0 by eliding the clearing of the register when switching to a native task with kpti enabled, on the erroneous assumption that the kpti trampoline entry code would already have taken care of the write.
Although the kpti trampoline does zero the register on entry from a native task, the check in tls_thread_switch() is on the *next* task and so we can end up leaving a stale, non-zero value in the register if the previous task was 32-bit.
Drop the broken optimisation and zero tpidrro_el0 unconditionally when switching to a native 64-bit task.
--- arch/arm64/kernel/process.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/kernel/process.c +1 -1
@@ -394,7 +394,7 @@ static void tls_thread_switch(struct tasif (is_compat_thread (task_thread_info (next)))write_sysreg (next->thread.uw.tp_value, tpidrro_el0); -else if (!arm64_kernel_unmapped_at_el0 ()) +else write_sysreg (0 , tpidrro_el0);write_sysreg (*task_user_tls (next), tpidr_el0);
Greg Kroah-Hartman
maintainerPATCH 338/565 block: fix ordering between checking BLK_MQ_S_STOPPED request adding
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Muchun Song <[email protected]>
commit 96a9fe64bfd486ebeeacf1e6011801ffe89dae18 upstream.
Supposing first scenario with a virtio_blk driver.
CPU0 CPU1
blk_mq_try_issue_directly()
__blk_mq_issue_directly()
q->mq_ops->queue_rq()
virtio_queue_rq()
blk_mq_stop_hw_queue()
virtblk_done()
blk_mq_request_bypass_insert() 1) store
blk_mq_start_stopped_hw_queue()
clear_bit(BLK_MQ_S_STOPPED) 3) store
blk_mq_run_hw_queue()
if (!blk_mq_hctx_has_pending()) 4) load
return
blk_mq_sched_dispatch_requests()
blk_mq_run_hw_queue()
if (!blk_mq_hctx_has_pending())
return
blk_mq_sched_dispatch_requests()
if (blk_mq_hctx_stopped()) 2) load
return
__blk_mq_sched_dispatch_requests()Supposing another scenario.
CPU0 CPU1
blk_mq_requeue_work()
blk_mq_insert_request() 1) store
virtblk_done()
blk_mq_start_stopped_hw_queue()
blk_mq_run_hw_queues() clear_bit(BLK_MQ_S_STOPPED) 3) store
blk_mq_run_hw_queue()
if (!blk_mq_hctx_has_pending()) 4) load
return
blk_mq_sched_dispatch_requests()
if (blk_mq_hctx_stopped()) 2) load
continue
blk_mq_run_hw_queue()Both scenarios are similar, the full memory barrier should be inserted between 1) and 2), as well as between 3) and 4) to make sure that either CPU0 sees BLK_MQ_S_STOPPED is cleared or CPU1 sees dispatch list. Otherwise, either CPU will not rerun the hardware queue causing starvation of the request.
The easy way to fix it is to add the essential full memory barrier into helper of blk_mq_hctx_stopped(). In order to not affect the fast path (hardware queue is not stopped most of the time), we only insert the barrier into the slow path. Actually, only slow path needs to care about missing of dispatching the request to the low-level device driver.
--- block/blk-mq.c | 6 ++++++ block/blk-mq.h | 13 +++++++++++++ 2 files changed, 19 insertions(+)
block/blk-mq.c +6 -0
@@ -1813,6 +1813,12 @@ void blk_mq_start_stopped_hw_queue(strucreturn ;clear_bit (BLK_MQ_S_STOPPED , &hctx->state); +/* +* Pairs with the smp_mb() in blk_mq_hctx_stopped() to order the +* clearing of BLK_MQ_S_STOPPED above and the checking of dispatch +* list in the subsequent routine. +*/ +smp_mb__after_atomic ();blk_mq_run_hw_queue (hctx, async); }EXPORT_SYMBOL_GPL (blk_mq_start_stopped_hw_queue);
block/blk-mq.h +13 -0
@@ -177,6 +177,19 @@ static inline struct blk_mq_tags *blk_mqstatic inline bool blk_mq_hctx_stopped (struct blk_mq_hw_ctx *hctx) { +/* Fast path: hardware queue is not stopped most of the time. */ +if (likely (!test_bit (BLK_MQ_S_STOPPED , &hctx->state))) +return false; + +/* +* This barrier is used to order adding of dispatch list before and +* the test of BLK_MQ_S_STOPPED below. Pairs with the memory barrier +* in blk_mq_start_stopped_hw_queue() so that dispatch code could +* either see BLK_MQ_S_STOPPED is cleared or dispatch list is not +* empty to avoid missing dispatching requests. +*/ +smp_mb (); +return test_bit (BLK_MQ_S_STOPPED , &hctx->state); }
Greg Kroah-Hartman
maintainerPATCH 339/565 HID: wacom: Interpret tilt data from Intuos Pro BT as signed values
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Gerecke <[email protected]>
commit 49a397ad24ee5e2c53a59dada2780d7e71bd3f77 upstream.
The tilt data contained in the Bluetooth packets of an Intuos Pro are supposed to be interpreted as signed values. Simply casting the values to type char is not guaranteed to work since it is implementation- defined whether it is signed or unsigned. At least one user has noticed the data being reported incorrectly on their system. To ensure that the data is interpreted properly, we specifically cast to signed char instead.
--- drivers/hid/wacom_wac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/hid/wacom_wac.c +2 -2
@@ -1401,9 +1401,9 @@ static void wacom_intuos_pro2_bt_pen(str rotation -=1800 ;input_report_abs (pen_input,ABS_TILT_X , - (char )frame[7 ]); + (signed char )frame[7 ]);input_report_abs (pen_input,ABS_TILT_Y , - (char )frame[8 ]); + (signed char )frame[8 ]);input_report_abs (pen_input,ABS_Z , rotation);input_report_abs (pen_input,ABS_WHEEL ,get_unaligned_le16 (&frame[11 ]));
Greg Kroah-Hartman
maintainerPATCH 340/565 media: wl128x: Fix atomicity violation in fmc_send_cmd()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qiu-ji Chen <[email protected]>
commit ca59f9956d4519ab18ab2270be47c6b8c6ced091 upstream.
Atomicity violation occurs when the fmc_send_cmd() function is executed simultaneously with the modification of the fmdev->resp_skb value. Consider a scenario where, after passing the validity check within the function, a non-null fmdev->resp_skb variable is assigned a null value. This results in an invalid fmdev->resp_skb variable passing the validity check. As seen in the later part of the function, skb = fmdev->resp_skb; when the invalid fmdev->resp_skb passes the check, a null pointer dereference error may occur at line 478, evt_hdr = (void *)skb->data;
To address this issue, it is recommended to include the validity check of fmdev->resp_skb within the locked section of the function. This modification ensures that the value of fmdev->resp_skb does not change during the validation process, thereby maintaining its validity.
This possible bug is found by an experimental static analysis tool developed by our team. This tool analyzes the locking APIs to extract function pairs that can be concurrently executed, and then analyzes the instructions in the paired functions to identify possible concurrency bugs including data races and atomicity violations.
--- drivers/media/radio/wl128x/fmdrv_common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/media/radio/wl128x/fmdrv_common.c +2 -1
@@ -465,11 +465,12 @@ int fmc_send_cmd(struct fmdev *fmdev, u8 jiffies_to_msecs(FM_DRV_TX_TIMEOUT) / 1000);return -ETIMEDOUT ; } +spin_lock_irqsave (&fmdev->resp_skb_lock, flags);if (!fmdev->resp_skb) { +spin_unlock_irqrestore (&fmdev->resp_skb_lock, flags);fmerr ("Response SKB is missing\n" );return -EFAULT ; } -spin_lock_irqsave (&fmdev->resp_skb_lock, flags); skb = fmdev->resp_skb; fmdev->resp_skb =NULL ;spin_unlock_irqrestore (&fmdev->resp_skb_lock, flags);
Greg Kroah-Hartman
maintainerPATCH 341/565 soc: fsl: rcpm: fix missing of_node_put() in copy_ippdexpcr1_setting()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Javier Carrasco <[email protected]>
commit c9f1efabf8e3b3ff886a42669f7093789dbeca94 upstream.
of_find_compatible_node() requires a call to of_node_put() when the pointer to the node is not required anymore to decrement its refcount and avoid leaking memory.
Add the missing call to of_node_put() after the node has been used.
--- drivers/soc/fsl/rcpm.c | 1 + 1 file changed, 1 insertion(+)
drivers/soc/fsl/rcpm.c +1 -0
@@ -36,6 +36,7 @@ static void copy_ippdexpcr1_setting(u32return ; regs =of_iomap (np,0 ); +of_node_put (np);if (!regs)return ;
Greg Kroah-Hartman
maintainerPATCH 342/565 media: v4l2-core: v4l2-dv-timings: check cvt/gtf result
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans Verkuil <[email protected]>
commit 9f070b1862f3411b8bcdfd51a8eaad25286f9deb upstream.
The v4l2_detect_cvt/gtf functions should check the result against the timing capabilities: these functions calculate the timings, so if they are out of bounds, they should be rejected.
To do this, add the struct v4l2_dv_timings_cap as argument to those functions.
This required updates to the adv7604 and adv7842 drivers since the prototype of these functions has now changed. The timings struct that is passed to v4l2_detect_cvt/gtf in those two drivers is filled with the timings detected by the hardware.
The vivid driver was also updated, but an additional check was added:
the width and height specified by VIDIOC_S_DV_TIMINGS has to match the calculated result, otherwise something went wrong. Note that vivid *emulates* hardware, so all the values passed to the v4l2_detect_cvt/gtf functions came from the timings struct that was filled by userspace and passed on to the driver via VIDIOC_S_DV_TIMINGS. So these fields can contain random data. Both the constraints check via struct v4l2_dv_timings_cap and the additional width/height check ensure that the resulting timings are sane and not messed up by the v4l2_detect_cvt/gtf calculations.
--- drivers/media/i2c/adv7604.c | 5 drivers/media/i2c/adv7842.c | 13 +- drivers/media/test-drivers/vivid/vivid-vid-cap.c | 15 ++ drivers/media/v4l2-core/v4l2-dv-timings.c | 132 ++++++++++++----------- include/media/v4l2-dv-timings.h | 18 ++- 5 files changed, 107 insertions(+), 76 deletions(-)
drivers/media/i2c/adv7604.c +3 -2
@@ -1405,12 +1405,13 @@ static int stdi2dv_timings(struct v4l2_sif (v4l2_detect_cvt (stdi->lcf +1 , hfreq, stdi->lcvs,0 , (stdi->hs_pol =='+' ?V4L2_DV_HSYNC_POS_POL :0 ) | (stdi->vs_pol =='+' ?V4L2_DV_VSYNC_POS_POL :0 ), - false, timings)) + false,adv76xx_get_dv_timings_cap (sd,-1 ), timings))return 0 ;if (v4l2_detect_gtf (stdi->lcf +1 , hfreq, stdi->lcvs, (stdi->hs_pol =='+' ?V4L2_DV_HSYNC_POS_POL :0 ) | (stdi->vs_pol =='+' ?V4L2_DV_VSYNC_POS_POL :0 ), - false, state->aspect_ratio, timings)) + false, state->aspect_ratio, +adv76xx_get_dv_timings_cap (sd,-1 ), timings))return 0 ; v4l2_dbg(2, debug, sd,
drivers/media/i2c/adv7842.c +7 -6
@@ -1441,14 +1441,15 @@ static int stdi2dv_timings(struct v4l2_s }if (v4l2_detect_cvt (stdi->lcf +1 , hfreq, stdi->lcvs,0 , - (stdi->hs_pol =='+' ?V4L2_DV_HSYNC_POS_POL :0 ) | - (stdi->vs_pol =='+' ?V4L2_DV_VSYNC_POS_POL :0 ), - false, timings)) + (stdi->hs_pol =='+' ?V4L2_DV_HSYNC_POS_POL :0 ) | + (stdi->vs_pol =='+' ?V4L2_DV_VSYNC_POS_POL :0 ), + false,adv7842_get_dv_timings_cap (sd), timings))return 0 ;if (v4l2_detect_gtf (stdi->lcf +1 , hfreq, stdi->lcvs, - (stdi->hs_pol =='+' ?V4L2_DV_HSYNC_POS_POL :0 ) | - (stdi->vs_pol =='+' ?V4L2_DV_VSYNC_POS_POL :0 ), - false, state->aspect_ratio, timings)) + (stdi->hs_pol =='+' ?V4L2_DV_HSYNC_POS_POL :0 ) | + (stdi->vs_pol =='+' ?V4L2_DV_VSYNC_POS_POL :0 ), + false, state->aspect_ratio, +adv7842_get_dv_timings_cap (sd), timings))return 0 ; v4l2_dbg(2, debug, sd,
drivers/media/test-drivers/vivid/vivid-vid-cap.c +13 -2
@@ -1707,12 +1707,19 @@ static bool valid_cvt_gtf_timings(struct h_freq = (u32 )bt->pixelclock / total_h_pixel;if (bt->standards ==0 || (bt->standards &V4L2_DV_BT_STD_CVT )) { +struct v4l2_dv_timings cvt = {}; +if (v4l2_detect_cvt (total_v_lines, h_freq, bt->vsync, bt->width, - bt->polarities, bt->interlaced, timings)) + bt->polarities, bt->interlaced, + &vivid_dv_timings_cap, &cvt) && + cvt.bt.width == bt->width && cvt.bt.height == bt->height) { + *timings = cvt;return true; + } }if (bt->standards ==0 || (bt->standards &V4L2_DV_BT_STD_GTF )) { +struct v4l2_dv_timings gtf = {};struct v4l2_fract aspect_ratio; find_aspect_ratio(bt->width, bt->height,
@@ -1720,8 +1727,12 @@ static bool valid_cvt_gtf_timings(struct &aspect_ratio.denominator);if (v4l2_detect_gtf (total_v_lines, h_freq, bt->vsync, bt->polarities, bt->interlaced, - aspect_ratio, timings)) + aspect_ratio, &vivid_dv_timings_cap, + >f) && + gtf.bt.width == bt->width && gtf.bt.height == bt->height) { + *timings = gtf;return true; + } }return false; }
drivers/media/v4l2-core/v4l2-dv-timings.c +72 -60
191 lines not on this page · raw message
include/media/v4l2-dv-timings.h +12 -6
@@ -146,15 +146,18 @@ void v4l2_print_dv_timings(const char *d* @polarities: the horizontal and vertical polarities (same as struct * v4l2_bt_timings polarities). * @interlaced: if this flag is true, it indicates interlaced format +* @cap: the v4l2_dv_timings_cap capabilities. * @fmt: the resulting timings. * * This function will attempt to detect if the given values correspond to a * valid CVT format. If so, then it will return true, and fmt will be filled * in with the found CVT timings. */ -bool v4l2_detect_cvt (unsigned frame_height,unsigned hfreq,unsigned vsync, -unsigned active_width,u32 polarities,bool interlaced, -struct v4l2_dv_timings *fmt); +bool v4l2_detect_cvt (unsigned int frame_height,unsigned int hfreq, +unsigned int vsync,unsigned int active_width, +u32 polarities,bool interlaced, +const struct v4l2_dv_timings_cap *cap, +struct v4l2_dv_timings *fmt);/** * v4l2_detect_gtf - detect if the given timings follow the GTF standard
@@ -170,15 +173,18 @@ bool v4l2_detect_cvt(unsigned frame_heig* image height, so it has to be passed explicitly. Usually * the native screen aspect ratio is used for this. If it * is not filled in correctly, then 16:9 will be assumed. +* @cap: the v4l2_dv_timings_cap capabilities. * @fmt: the resulting timings. * * This function will attempt to detect if the given values correspond to a * valid GTF format. If so, then it will return true, and fmt will be filled * in with the found GTF timings. */ -bool v4l2_detect_gtf (unsigned frame_height,unsigned hfreq,unsigned vsync, -u32 polarities,bool interlaced,struct v4l2_fract aspect, -struct v4l2_dv_timings *fmt); +bool v4l2_detect_gtf (unsigned int frame_height,unsigned int hfreq, +unsigned int vsync,u32 polarities,bool interlaced, +struct v4l2_fract aspect, +const struct v4l2_dv_timings_cap *cap, +struct v4l2_dv_timings *fmt);/** * v4l2_calc_aspect_ratio - calculate the aspect ratio based on bytes
Greg Kroah-Hartman
maintainerPATCH 343/565 ALSA: pcm: Add sanity NULL check for the default mmap fault handler
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit d2913a07d9037fe7aed4b7e680684163eaed6bc4 upstream.
A driver might allow the mmap access before initializing its runtime->dma_area properly. Add a proper NULL check before passing to virt_to_page() for avoiding a panic.
--- sound/core/pcm_native.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
sound/core/pcm_native.c +4 -2
@@ -3757,9 +3757,11 @@ static vm_fault_t snd_pcm_mmap_data_faulreturn VM_FAULT_SIGBUS ;if (substream->ops->page) page = substream->ops->page (substream, offset); -else if (!snd_pcm_get_dma_buf (substream)) +else if (!snd_pcm_get_dma_buf (substream)) { +if (WARN_ON_ONCE (!runtime->dma_area)) +return VM_FAULT_SIGBUS ; page =virt_to_page (runtime->dma_area + offset); -else + }else page =snd_sgbuf_get_page (snd_pcm_get_dma_buf (substream), offset);if (!page)return VM_FAULT_SIGBUS ;
Greg Kroah-Hartman
maintainerPATCH 344/565 ALSA: hda/realtek: Update ALC225 depop procedure
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kailang Yang <[email protected]>
commit 1fd50509fe14a9adc9329e0454b986157a4c155a upstream.
Old procedure has a chance to meet Headphone no output.
--- sound/pci/hda/patch_realtek.c | 95 +++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 52 deletions(-)
sound/pci/hda/patch_realtek.c +43 -52
@@ -3748,33 +3748,28 @@ static void alc225_init(struct hda_codec hp1_pin_sense =snd_hda_jack_detect (codec, hp_pin); hp2_pin_sense =snd_hda_jack_detect (codec,0x16 ); -if (hp1_pin_sense || hp2_pin_sense) +if (hp1_pin_sense || hp2_pin_sense) {msleep (2 ); +alc_update_coefex_idx (codec,0x57 ,0x04 ,0x0007 ,0x1 );/* Low power */ -alc_update_coefex_idx (codec,0x57 ,0x04 ,0x0007 ,0x1 );/* Low power */ +if (hp1_pin_sense) +snd_hda_codec_write (codec, hp_pin,0 , +AC_VERB_SET_PIN_WIDGET_CONTROL ,PIN_OUT ); +if (hp2_pin_sense) +snd_hda_codec_write (codec,0x16 ,0 , +AC_VERB_SET_PIN_WIDGET_CONTROL ,PIN_OUT ); +msleep (75 ); + +if (hp1_pin_sense) +snd_hda_codec_write (codec, hp_pin,0 , +AC_VERB_SET_AMP_GAIN_MUTE ,AMP_OUT_UNMUTE ); +if (hp2_pin_sense) +snd_hda_codec_write (codec,0x16 ,0 , +AC_VERB_SET_AMP_GAIN_MUTE ,AMP_OUT_UNMUTE ); -if (hp1_pin_sense || spec->ultra_low_power) -snd_hda_codec_write (codec, hp_pin,0 , -AC_VERB_SET_AMP_GAIN_MUTE ,AMP_OUT_MUTE ); -if (hp2_pin_sense) -snd_hda_codec_write (codec,0x16 ,0 , -AC_VERB_SET_AMP_GAIN_MUTE ,AMP_OUT_MUTE ); - -if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power) -msleep (85 ); - -if (hp1_pin_sense || spec->ultra_low_power) -snd_hda_codec_write (codec, hp_pin,0 , -AC_VERB_SET_PIN_WIDGET_CONTROL ,PIN_OUT ); -if (hp2_pin_sense) -snd_hda_codec_write (codec,0x16 ,0 , -AC_VERB_SET_PIN_WIDGET_CONTROL ,PIN_OUT ); - -if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power) -msleep (100 ); - -alc_update_coef_idx (codec,0x4a ,3 <<10 ,0 ); -alc_update_coefex_idx (codec,0x57 ,0x04 ,0x0007 ,0x4 );/* Hight power */ +msleep (75 ); +alc_update_coefex_idx (codec,0x57 ,0x04 ,0x0007 ,0x4 );/* Hight power */ + } }static void alc225_shutup (struct hda_codec *codec)
@@ -3786,36 +3781,35 @@ static void alc225_shutup(struct hda_codif (!hp_pin) hp_pin =0x21 ; -alc_disable_headset_jack_key (codec); -/* 3k pull low control for Headset jack. */ -alc_update_coef_idx (codec,0x4a ,0 ,3 <<10 ); - hp1_pin_sense =snd_hda_jack_detect (codec, hp_pin); hp2_pin_sense =snd_hda_jack_detect (codec,0x16 ); -if (hp1_pin_sense || hp2_pin_sense) +if (hp1_pin_sense || hp2_pin_sense) { +alc_disable_headset_jack_key (codec); +/* 3k pull low control for Headset jack. */ +alc_update_coef_idx (codec,0x4a ,0 ,3 <<10 );msleep (2 ); -if (hp1_pin_sense || spec->ultra_low_power) -snd_hda_codec_write (codec, hp_pin,0 , -AC_VERB_SET_AMP_GAIN_MUTE ,AMP_OUT_MUTE ); -if (hp2_pin_sense) -snd_hda_codec_write (codec,0x16 ,0 , -AC_VERB_SET_AMP_GAIN_MUTE ,AMP_OUT_MUTE ); - -if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power) -msleep (85 ); - -if (hp1_pin_sense || spec->ultra_low_power) -snd_hda_codec_write (codec, hp_pin,0 , -AC_VERB_SET_PIN_WIDGET_CONTROL ,0x0 ); -if (hp2_pin_sense) -snd_hda_codec_write (codec,0x16 ,0 , -AC_VERB_SET_PIN_WIDGET_CONTROL ,0x0 ); - -if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power) -msleep (100 ); - +if (hp1_pin_sense) +snd_hda_codec_write (codec, hp_pin,0 , +AC_VERB_SET_AMP_GAIN_MUTE ,AMP_OUT_MUTE ); +if (hp2_pin_sense) +snd_hda_codec_write (codec,0x16 ,0 , +AC_VERB_SET_AMP_GAIN_MUTE ,AMP_OUT_MUTE ); + +msleep (75 ); + +if (hp1_pin_sense) +snd_hda_codec_write (codec, hp_pin,0 , +AC_VERB_SET_PIN_WIDGET_CONTROL ,0x0 ); +if (hp2_pin_sense) +snd_hda_codec_write (codec,0x16 ,0 , +AC_VERB_SET_PIN_WIDGET_CONTROL ,0x0 ); + +msleep (75 ); +alc_update_coef_idx (codec,0x4a ,3 <<10 ,0 ); +alc_enable_headset_jack_key (codec); + }alc_auto_setup_eapd (codec, false);alc_shutup_pins (codec);if (spec->ultra_low_power) {
@@ -3826,9 +3820,6 @@ static void alc225_shutup(struct hda_codalc_update_coef_idx (codec,0x4a ,3 <<4 ,2 <<4 );msleep (30 ); } - -alc_update_coef_idx (codec,0x4a ,3 <<10 ,0 ); -alc_enable_headset_jack_key (codec); }static void alc_default_init (struct hda_codec *codec)
Greg Kroah-Hartman
maintainerPATCH 345/565 ALSA: hda/realtek: Set PCBeep to default value for ALC274
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kailang Yang <[email protected]>
commit 155699ccab7c78cbba69798242b68bc8ac66d5d2 upstream.
BIOS Enable PC beep path cause pop noise via speaker during boot time. Set to default value from driver will solve the issue.
--- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+)
sound/pci/hda/patch_realtek.c +2 -0
@@ -463,6 +463,8 @@ static void alc_fill_eapd_coef(struct hdbreak ;case 0x10ec0234 :case 0x10ec0274 : +alc_write_coef_idx (codec,0x6e ,0x0c25 ); + fallthrough;case 0x10ec0294 :case 0x10ec0700 :case 0x10ec0701 :
Greg Kroah-Hartman
maintainerPATCH 346/565 ALSA: hda/realtek: Fix Internal Speaker and Mic boost of Infinix Y4 Max
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dinesh Kumar <[email protected]>
commit 5ebe792a5139f1ce6e4aed22bef12e7e2660df96 upstream.
Internal Speaker of Infinix Y4 Max remains muted due to incorrect Pin configuration, and the Internal Mic records high noise. This patch corrects the Pin configuration for the Internal Speaker and limits the Internal Mic boost.
HW Probe for device: https://linux-hardware.org/?probe=6d4386c347
Test: Internal Speaker works fine, Mic has low noise.
--- sound/pci/hda/patch_realtek.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
sound/pci/hda/patch_realtek.c +11 -0
@@ -6925,6 +6925,7 @@ enum {ALC269_FIXUP_THINKPAD_ACPI ,ALC269_FIXUP_DMIC_THINKPAD_ACPI ,ALC269VB_FIXUP_INFINIX_ZERO_BOOK_13 , +ALC269VC_FIXUP_INFINIX_Y4_MAX ,ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO ,ALC255_FIXUP_ACER_MIC_NO_PRESENCE , ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
@@ -7237,6 +7238,15 @@ static const struct hda_fixup alc269_fix .chained = true, .chain_id =ALC269_FIXUP_LIMIT_INT_MIC_BOOST }, + [ALC269VC_FIXUP_INFINIX_Y4_MAX] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl []) { + {0x1b ,0x90170150 },/* use as internal speaker */ + { } + }, + .chained = true, + .chain_id =ALC269_FIXUP_LIMIT_INT_MIC_BOOST + }, [ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO] = { .type = HDA_FIXUP_PINS, .v.pins = (const struct hda_pintbl []) {
@@ -9535,6 +9545,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x2782 ,0x0214 ,"VAIO VJFE-CL" ,ALC269_FIXUP_LIMIT_INT_MIC_BOOST ),SND_PCI_QUIRK (0x2782 ,0x0228 ,"Infinix ZERO BOOK 13" ,ALC269VB_FIXUP_INFINIX_ZERO_BOOK_13 ),SND_PCI_QUIRK (0x2782 ,0x0232 ,"CHUWI CoreBook XPro" ,ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO ), +SND_PCI_QUIRK (0x2782 ,0x1701 ,"Infinix Y4 Max" ,ALC269VC_FIXUP_INFINIX_Y4_MAX ),SND_PCI_QUIRK (0x2782 ,0x1707 ,"Vaio VJFE-ADL" ,ALC298_FIXUP_SPK_VOLUME ),SND_PCI_QUIRK (0x8086 ,0x2074 ,"Intel NUC 8" ,ALC233_FIXUP_INTEL_NUC8_DMIC ), SND_PCI_QUIRK(0x8086, 0x2080, "Intel NUC 8 Rugged", ALC256_FIXUP_INTEL_NUC8_RUGGED),
Greg Kroah-Hartman
maintainerPATCH 347/565 ALSA: hda/realtek: Apply quirk for Medion E15433
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit ca0f79f0286046f6a91c099dc941cf7afae198d6 upstream.
Medion E15433 laptop wich ALC269VC (SSID 2782:1705) needs the same workaround for the missing speaker as another model.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -9546,6 +9546,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x2782 ,0x0228 ,"Infinix ZERO BOOK 13" ,ALC269VB_FIXUP_INFINIX_ZERO_BOOK_13 ),SND_PCI_QUIRK (0x2782 ,0x0232 ,"CHUWI CoreBook XPro" ,ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO ),SND_PCI_QUIRK (0x2782 ,0x1701 ,"Infinix Y4 Max" ,ALC269VC_FIXUP_INFINIX_Y4_MAX ), +SND_PCI_QUIRK (0x2782 ,0x1705 ,"MEDION E15433" ,ALC269VC_FIXUP_INFINIX_Y4_MAX ),SND_PCI_QUIRK (0x2782 ,0x1707 ,"Vaio VJFE-ADL" ,ALC298_FIXUP_SPK_VOLUME ),SND_PCI_QUIRK (0x8086 ,0x2074 ,"Intel NUC 8" ,ALC233_FIXUP_INTEL_NUC8_DMIC ), SND_PCI_QUIRK(0x8086, 0x2080, "Intel NUC 8 Rugged", ALC256_FIXUP_INTEL_NUC8_RUGGED),
Greg Kroah-Hartman
maintainerPATCH 348/565 usb: dwc3: gadget: Fix checking for number of TRBs left
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thinh Nguyen <[email protected]>
commit 02a6982b0ccfcdc39e20016f5fc9a1b7826a6ee7 upstream.
The check whether the TRB ring is full or empty in dwc3_calc_trbs_left() is insufficient. It assumes there are active TRBs if there's any request in the started_list. However, that's not the case for requests with a large SG list.
That is, if we have a single usb request that requires more TRBs than the total TRBs in the TRB ring, the queued TRBs will be available when all the TRBs in the ring are completed. But the request is only partially completed and remains in the started_list. With the current logic, the TRB ring is empty, but dwc3_calc_trbs_left() returns 0.
Fix this by additionally checking for the request->num_trbs for active TRB count.
--- drivers/usb/dwc3/gadget.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/usb/dwc3/gadget.c +6 -3
@@ -1168,11 +1168,14 @@ static u32 dwc3_calc_trbs_left(struct dw* pending to be processed by the driver. */ if (dep->trb_enqueue == dep->trb_dequeue) { +struct dwc3_request *req; +/* -* If there is any request remained in the started_list at -* this point, that means there is no TRB available. +* If there is any request remained in the started_list with +* active TRBs at this point, then there is no TRB available. */ -if (!list_empty (&dep->started_list)) + req =next_request (&dep->started_list); +if (req && req->num_trbs)return 0 ;return DWC3_TRB_NUM -1 ;
Greg Kroah-Hartman
maintainerPATCH 349/565 usb: dwc3: gadget: Fix looping of queued SG entries
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thinh Nguyen <[email protected]>
commit b7fc65f5141c24785dc8c19249ca4efcf71b3524 upstream.
The dwc3_request->num_queued_sgs is decremented on completion. If a partially completed request is handled, then the dwc3_request->num_queued_sgs no longer reflects the total number of num_queued_sgs (it would be cleared).
Correctly check the number of request SG entries remained to be prepare and queued. Failure to do this may cause null pointer dereference when accessing non-existent SG entry.
--- drivers/usb/dwc3/gadget.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/usb/dwc3/gadget.c +3 -3
@@ -1403,8 +1403,8 @@ static int dwc3_prepare_trbs_sg(struct dstruct scatterlist *s;int i;unsigned int length = req->request.length; -unsigned int remaining = req->request.num_mapped_sgs - - req->num_queued_sgs; +unsigned int remaining = req->num_pending_sgs; +unsigned int num_queued_sgs = req->request.num_mapped_sgs - remaining;unsigned int num_trbs = req->num_trbs;bool needs_extra_trb =dwc3_needs_extra_trb (dep, req);
@@ -1412,7 +1412,7 @@ static int dwc3_prepare_trbs_sg(struct d* If we resume preparing the request, then get the remaining length of * the request and resume where we left off. */ -for_each_sg (req->request.sg, s, req->num_queued_sgs, i) +for_each_sg (req->request.sg, s, num_queued_sgs, i) length -=sg_dma_len (s);for_each_sg (sg, s, remaining, i) {
Greg Kroah-Hartman
maintainerPATCH 350/565 lib: string_helpers: silence snprintf() output truncation warning
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bartosz Golaszewski <[email protected]>
commit a508ef4b1dcc82227edc594ffae583874dd425d7 upstream.
The output of ".%03u" with the unsigned int in range [0, 4294966295] may get truncated if the target buffer is not 12 bytes. This can't really happen here as the 'remainder' variable cannot exceed 999 but the compiler doesn't know it. To make it happy just increase the buffer to where the warning goes away.
--- lib/string_helpers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
lib/string_helpers.c +1 -1
@@ -51,7 +51,7 @@ void string_get_size(u64 size, u64 blk_sstatic const unsigned int rounding[] = {500 ,50 ,5 };int i =0 , j;u32 remainder =0 , sf_cap; -char tmp[8 ]; +char tmp[12 ];const char *unit; tmp[0 ] ='\0' ;
Greg Kroah-Hartman
maintainerPATCH 351/565 NFSD: Prevent a potential integer overflow
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
commit 7f33b92e5b18e904a481e6e208486da43e4dc841 upstream.
If the tag length is >= U32_MAX - 3 then the "length + 4" addition can result in an integer overflow. Address this by splitting the decoding into several steps so that decode_cb_compound4res() does not have to perform arithmetic on the unsafe length value.
--- fs/nfsd/nfs4callback.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
fs/nfsd/nfs4callback.c +7 -7
@@ -297,17 +297,17 @@ static int decode_cb_compound4res(structu32 length;__be32 *p; - p =xdr_inline_decode (xdr,4 +4 ); + p =xdr_inline_decode (xdr,XDR_UNIT );if (unlikely (p ==NULL )) goto out_overflow; - hdr->status =be32_to_cpup (p++); + hdr->status =be32_to_cpup (p);/* Ignore the tag */ - length =be32_to_cpup (p++); - p =xdr_inline_decode (xdr, length +4 ); -if (unlikely (p ==NULL )) +if (xdr_stream_decode_u32 (xdr, &length) <0 ) + goto out_overflow; +if (xdr_inline_decode (xdr, length) ==NULL ) + goto out_overflow; +if (xdr_stream_decode_u32 (xdr, &hdr->nops) <0 ) goto out_overflow; - p +=XDR_QUADLEN (length); - hdr->nops =be32_to_cpup (p);return 0 ; out_overflow:return -EIO ;
Greg Kroah-Hartman
maintainerPATCH 352/565 SUNRPC: make sure cache entry active before cache_show
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Erkun <[email protected]>
commit 2862eee078a4d2d1f584e7f24fa50dddfa5f3471 upstream.
The function c_show was called with protection from RCU. This only ensures that cp will not be freed. Therefore, the reference count for cp can drop to zero, which will trigger a refcount use-after-free warning when cache_get is called. To resolve this issue, use cache_get_rcu to ensure that cp remains active.
------------[ cut here ]------------ refcount_t: addition on 0; use-after-free. WARNING: CPU: 7 PID: 822 at lib/refcount.c:25 refcount_warn_saturate+0xb1/0x120 CPU: 7 UID: 0 PID: 822 Comm: cat Not tainted 6.12.0-rc3+ #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.1-2.fc37 04/01/2014 RIP: 0010:refcount_warn_saturate+0xb1/0x120 Call Trace: <TASK> c_show+0x2fc/0x380 [sunrpc] seq_read_iter+0x589/0x770 seq_read+0x1e5/0x270 proc_reg_read+0xe1/0x140 vfs_read+0x125/0x530 ksys_read+0xc1/0x160 do_syscall_64+0x5f/0x170 entry_SYSCALL_64_after_hwframe+0x76/0x7e
--- net/sunrpc/cache.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/sunrpc/cache.c +3 -1
@@ -1415,7 +1415,9 @@ static int c_show(struct seq_file *m, voseq_printf (m,"# expiry=%lld refcnt=%d flags=%lx\n" ,convert_to_wallclock (cp->expiry_time),kref_read (&cp->ref), cp->flags); -cache_get (cp); +if (!cache_get_rcu (cp)) +return 0 ; +if (cache_check (cd, cp,NULL ))/* cache_check does a cache_put on failure */ seq_puts (m,"# " );
Greg Kroah-Hartman
maintainerPATCH 353/565 rpmsg: glink: Propagate TX failures in intentless mode as well
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bjorn Andersson <[email protected]>
commit 7a68f9fa97357a0f2073c9c31ed4101da4fce93e upstream.
As support for splitting transmission over several messages using TX_DATA_CONT was introduced it does not immediately return the return value of qcom_glink_tx().
The result is that in the intentless case (i.e. intent == NULL), the code will continue to send all additional chunks. This is wasteful, and it's possible that the send operation could incorrectly indicate success, if the last chunk fits in the TX fifo.
Fix the condition.
--- drivers/rpmsg/qcom_glink_native.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/rpmsg/qcom_glink_native.c +6 -4
@@ -1355,8 +1355,9 @@ static int __qcom_glink_send(struct glin ret =qcom_glink_tx (glink, &req,sizeof (req), data, chunk_size, wait);/* Mark intent available if we failed */ -if (ret && intent) { - intent->in_use = false; +if (ret) { +if (intent) + intent->in_use = false;return ret; }
@@ -1377,8 +1378,9 @@ static int __qcom_glink_send(struct glin chunk_size, wait);/* Mark intent available if we failed */ -if (ret && intent) { - intent->in_use = false; +if (ret) { +if (intent) + intent->in_use = false;break ; } }
Greg Kroah-Hartman
maintainerPATCH 354/565 um: Fix potential integer overflow during physmem setup
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tiwei Bie <[email protected]>
[ Upstream commit a98b7761f697e590ed5d610d87fa12be66f23419 ]
This issue happens when the real map size is greater than LONG_MAX, which can be easily triggered on UML/i386.
--- arch/um/kernel/physmem.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/um/kernel/physmem.c +3 -3
@@ -80,10 +80,10 @@ void __init setup_physmem(unsigned long start, unsigned long reserve_end, unsigned long len, unsigned long long highmem) {unsigned long reserve = reserve_end - start; -long map_size = len - reserve; +unsigned long map_size = len - reserve;int err; -if (map_size <=0 ) { +if (len <= reserve) {os_warn ("Too few physical memory! Needed=%lu, given=%lu\n" , reserve, len);exit (1 );
@@ -94,7 +94,7 @@ void __init setup_physmem(unsigned long start, unsigned long reserve_end, err =os_map_memory ((void *) reserve_end, physmem_fd, reserve, map_size,1 ,1 ,1 );if (err <0 ) { -os_warn ("setup_physmem - mapping %ld bytes of memory at 0x%p " +os_warn ("setup_physmem - mapping %lu bytes of memory at 0x%p " "failed - errno = %d\n" , map_size, (void *) reserve_end, err);exit (1 );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 355/565 um: Fix the return value of elf_core_copy_task_fpregs
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tiwei Bie <[email protected]>
[ Upstream commit 865e3845eeaa21e9a62abc1361644e67124f1ec0 ]
This function is expected to return a boolean value, which should be true on success and false on failure.
--- arch/um/kernel/process.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/um/kernel/process.c +1 -1
@@ -403,6 +403,6 @@ int elf_core_copy_fpregs(struct task_struct *t, elf_fpregset_t *fpu) {int cpu =current_thread_info ()->cpu; -return save_i387_registers (userspace_pid[cpu], (unsigned long *) fpu); +return save_i387_registers (userspace_pid[cpu], (unsigned long *) fpu) ==0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 356/565 um: Always dump trace for specified task in show_stack
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tiwei Bie <[email protected]>
[ Upstream commit 0f659ff362eac69777c4c191b7e5ccb19d76c67d ]
Currently, show_stack() always dumps the trace of the current task. However, it should dump the trace of the specified task if one is provided. Otherwise, things like running "echo t > sysrq-trigger" won't work as expected.
--- arch/um/kernel/sysrq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/um/kernel/sysrq.c +1 -1
@@ -52,5 +52,5 @@ void show_stack(struct task_struct *task, unsigned long *stack, }printk ("%sCall Trace:\n" , loglvl); -dump_trace (current, &stackops, (void *)loglvl); +dump_trace (task ?: current, &stackops, (void *)loglvl); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 357/565 NFSv4.0: Fix a use-after-free problem in the asynchronous open()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
[ Upstream commit 2fdb05dc0931250574f0cb0ebeb5ed8e20f4a889 ]
Yang Erkun reports that when two threads are opening files at the same time, and are forced to abort before a reply is seen, then the call to nfs_release_seqid() in nfs4_opendata_free() can result in a use-after-free of the pointer to the defunct rpc task of the other thread.
The fix is to ensure that if the RPC call is aborted before the call to nfs_wait_on_sequence() is complete, then we must call nfs_release_seqid() in nfs4_open_release() before the rpc_task is freed.
--- fs/nfs/nfs4proc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
fs/nfs/nfs4proc.c +5 -3
@@ -2537,12 +2537,14 @@ static void nfs4_open_release(void *calldata)struct nfs4_opendata *data = calldata;struct nfs4_state *state =NULL ; +/* In case of error, no cleanup! */ +if (data->rpc_status !=0 || !data->rpc_done) { +nfs_release_seqid (data->o_arg.seqid); + goto out_free; + }/* If this request hasn't been cancelled, do nothing */ if (!data->cancelled) goto out_free; -/* In case of error, no cleanup! */ -if (data->rpc_status !=0 || !data->rpc_done) - goto out_free;/* In case we need an open_confirm, no cleanup! */ if (data->o_res.rflags &NFS4_OPEN_RESULT_CONFIRM ) goto out_free;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 358/565 rtc: st-lpc: Use IRQF_NO_AUTOEN flag in request_irq()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
[ Upstream commit b6cd7adec0cf03f0aefc55676e71dd721cbc71a8 ]
If request_irq() fails in st_rtc_probe(), there is no need to enable the irq, and if it succeeds, disable_irq() after request_irq() still has a time gap in which interrupts can come.
request_irq() with IRQF_NO_AUTOEN flag will disable IRQ auto-enable when request IRQ.
--- drivers/rtc/rtc-st-lpc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/rtc/rtc-st-lpc.c +2 -3
@@ -218,15 +218,14 @@ static int st_rtc_probe(struct platform_device *pdev)return -EINVAL ; } - ret =devm_request_irq (&pdev->dev, rtc->irq, st_rtc_handler,0 , - pdev->name, rtc); + ret =devm_request_irq (&pdev->dev, rtc->irq, st_rtc_handler, +IRQF_NO_AUTOEN , pdev->name, rtc);if (ret) {dev_err (&pdev->dev,"Failed to request irq %i\n" , rtc->irq);return ret; }enable_irq_wake (rtc->irq); -disable_irq (rtc->irq); rtc->clk =devm_clk_get (&pdev->dev,NULL );if (IS_ERR (rtc->clk)) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 359/565 rtc: abx80x: Fix WDT bit position of the status register
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nobuhiro Iwamatsu <[email protected]>
[ Upstream commit 10e078b273ee7a2b8b4f05a64ac458f5e652d18d ]
The WDT bit in the status register is 5, not 6. This fixes from 6 to 5.
--- drivers/rtc/rtc-abx80x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/rtc/rtc-abx80x.c +1 -1
@@ -37,7 +37,7 @@#define ABX8XX_REG_STATUS 0x0f#define ABX8XX_STATUS_AF BIT(2)#define ABX8XX_STATUS_BLF BIT(4) -#define ABX8XX_STATUS_WDT BIT(6) +#define ABX8XX_STATUS_WDT BIT(5)#define ABX8XX_REG_CTRL1 0x10#define ABX8XX_CTRL_WRITE BIT(0)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 360/565 rtc: check if __rtc_read_time was successful in rtc_timer_do_work()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yongliang Gao <[email protected]>
[ Upstream commit e8ba8a2bc4f60a1065f23d6a0e7cbea945a0f40d ]
If the __rtc_read_time call fails,, the struct rtc_time tm; may contain uninitialized data, or an illegal date/time read from the RTC hardware.
When calling rtc_tm_to_ktime later, the result may be a very large value (possibly KTIME_MAX). If there are periodic timers in rtc->timerqueue, they will continually expire, may causing kernel softlockup.
--- drivers/rtc/interface.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/rtc/interface.c +6 -1
@@ -893,13 +893,18 @@ void rtc_timer_do_work(struct work_struct *work)struct timerqueue_node *next;ktime_t now;struct rtc_time tm; +int err;struct rtc_device *rtc = container_of(work, struct rtc_device, irqwork);mutex_lock (&rtc->ops_lock); again: -__rtc_read_time (rtc, &tm); + err =__rtc_read_time (rtc, &tm); +if (err) { +mutex_unlock (&rtc->ops_lock); +return ; + } now =rtc_tm_to_ktime (tm);while ((next =timerqueue_getnext (&rtc->timerqueue))) {if (next->expires > now)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 361/565 ubifs: Correct the total block count by deducting journal reservation
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhihao Cheng <[email protected]>
[ Upstream commit 84a2bee9c49769310efa19601157ef50a1df1267 ]
Since commit e874dcde1cbf ("ubifs: Reserve one leb for each journal head while doing budget"), available space is calulated by deducting reservation for all journal heads. However, the total block count ( which is only used by statfs) is not updated yet, which will cause the wrong displaying for used space(total - available). Fix it by deducting reservation for all journal heads from total block count.
--- fs/ubifs/super.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
fs/ubifs/super.c +3 -3
@@ -777,10 +777,10 @@ static void init_constants_master(struct ubifs_info *c)* necessary to report something for the 'statfs()' call. * * Subtract the LEB reserved for GC, the LEB which is reserved for -* deletions, minimum LEBs for the index, and assume only one journal -* head is available. +* deletions, minimum LEBs for the index, the LEBs which are reserved +* for each journal head. */ - tmp64 = c->main_lebs -1 -1 -MIN_INDEX_LEBS - c->jhead_cnt +1 ; + tmp64 = c->main_lebs -1 -1 -MIN_INDEX_LEBS - c->jhead_cnt; tmp64 *= (long long )c->leb_size - c->leb_overhead; tmp64 =ubifs_reported_space (c, tmp64); c->block_cnt = tmp64 >>UBIFS_BLOCK_SHIFT ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 362/565 ubi: fastmap: Fix duplicate slab cache names while attaching
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhihao Cheng <[email protected]>
[ Upstream commit bcddf52b7a17adcebc768d26f4e27cf79adb424c ]
Since commit 4c39529663b9 ("slab: Warn on duplicate cache names when DEBUG_VM=y"), the duplicate slab cache names can be detected and a kernel WARNING is thrown out.
In UBI fast attaching process, alloc_ai() could be invoked twice with the same slab cache name 'ubi_aeb_slab_cache', which will trigger following warning messages:
kmem_cache of name 'ubi_aeb_slab_cache' already exists
WARNING: CPU: 0 PID: 7519 at mm/slab_common.c:107
__kmem_cache_create_args+0x100/0x5f0
Modules linked in: ubi(+) nandsim [last unloaded: nandsim]
CPU: 0 UID: 0 PID: 7519 Comm: modprobe Tainted: G 6.12.0-rc2
RIP: 0010:__kmem_cache_create_args+0x100/0x5f0
Call Trace:
__kmem_cache_create_args+0x100/0x5f0
alloc_ai+0x295/0x3f0 [ubi]
ubi_attach+0x3c3/0xcc0 [ubi]
ubi_attach_mtd_dev+0x17cf/0x3fa0 [ubi]
ubi_init+0x3fb/0x800 [ubi]
do_init_module+0x265/0x7d0
__x64_sys_finit_module+0x7a/0xc0The problem could be easily reproduced by loading UBI device by fastmap with CONFIG_DEBUG_VM=y.
Fix it by using different slab names for alloc_ai() callers.
--- drivers/mtd/ubi/attach.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/mtd/ubi/attach.c +6 -6
@@ -1447,7 +1447,7 @@ static int scan_all(struct ubi_device *ubi, struct ubi_attach_info *ai,return err; } -static struct ubi_attach_info *alloc_ai (void ) +static struct ubi_attach_info *alloc_ai (const char *slab_name) {struct ubi_attach_info *ai;
@@ -1461,7 +1461,7 @@ static struct ubi_attach_info *alloc_ai(void)INIT_LIST_HEAD (&ai->alien);INIT_LIST_HEAD (&ai->fastmap); ai->volumes =RB_ROOT ; - ai->aeb_slab_cache =kmem_cache_create ("ubi_aeb_slab_cache" , + ai->aeb_slab_cache =kmem_cache_create (slab_name,sizeof (struct ubi_ainf_peb ),0 ,0 ,NULL );if (!ai->aeb_slab_cache) {
@@ -1491,7 +1491,7 @@ static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info **ai) err = -ENOMEM ; - scan_ai =alloc_ai (); + scan_ai =alloc_ai ("ubi_aeb_slab_cache_fastmap" );if (!scan_ai) goto out;
@@ -1557,7 +1557,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan)int err;struct ubi_attach_info *ai; - ai =alloc_ai (); + ai =alloc_ai ("ubi_aeb_slab_cache" );if (!ai)return -ENOMEM ;
@@ -1575,7 +1575,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan)if (err >0 ||mtd_is_eccerr (err)) {if (err !=UBI_NO_FASTMAP ) {destroy_ai (ai); - ai =alloc_ai (); + ai =alloc_ai ("ubi_aeb_slab_cache" );if (!ai)return -ENOMEM ;
@@ -1614,7 +1614,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan)if (ubi->fm &&ubi_dbg_chk_fastmap (ubi)) {struct ubi_attach_info *scan_ai; - scan_ai =alloc_ai (); + scan_ai =alloc_ai ("ubi_aeb_slab_cache_dbg_chk_fastmap" );if (!scan_ai) { err = -ENOMEM ; goto out_wl;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 363/565 ubifs: authentication: Fix use-after-free in ubifs_tnc_end_commit
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Waqar Hameed <[email protected]>
[ Upstream commit 4617fb8fc15effe8eda4dd898d4e33eb537a7140 ]
After an insertion in TNC, the tree might split and cause a node to change its znode->parent. A further deletion of other nodes in the tree (which also could free the nodes), the aforementioned node's znode->cparent could still point to a freed node. This znode->cparent may not be updated when getting nodes to commit in ubifs_tnc_start_commit(). This could then trigger a use-after-free when accessing the znode->cparent in write_index() in ubifs_tnc_end_commit().
This can be triggered by running
rm -f /etc/test-file.bin
dd if=/dev/urandom of=/etc/test-file.bin bs=1M count=60 conv=fsync
in a loop, and with CONFIG_UBIFS_FS_AUTHENTICATION. KASAN then reports:
BUG: KASAN: use-after-free in ubifs_tnc_end_commit+0xa5c/0x1950 Write of size 32 at addr ffffff800a3af86c by task ubifs_bgt0_20/153 Call trace: dump_backtrace+0x0/0x340 show_stack+0x18/0x24 dump_stack_lvl+0x9c/0xbc print_address_description.constprop.0+0x74/0x2b0 kasan_report+0x1d8/0x1f0 kasan_check_range+0xf8/0x1a0 memcpy+0x84/0xf4 ubifs_tnc_end_commit+0xa5c/0x1950 do_commit+0x4e0/0x1340 ubifs_bg_thread+0x234/0x2e0 kthread+0x36c/0x410 ret_from_fork+0x10/0x20 Allocated by task 401: kasan_save_stack+0x38/0x70 __kasan_kmalloc+0x8c/0xd0 __kmalloc+0x34c/0x5bc tnc_insert+0x140/0x16a4 ubifs_tnc_add+0x370/0x52c ubifs_jnl_write_data+0x5d8/0x870 do_writepage+0x36c/0x510 ubifs_writepage+0x190/0x4dc __writepage+0x58/0x154 write_cache_pages+0x394/0x830 do_writepages+0x1f0/0x5b0 filemap_fdatawrite_wbc+0x170/0x25c file_write_and_wait_range+0x140/0x190 ubifs_fsync+0xe8/0x290 vfs_fsync_range+0xc0/0x1e4 do_fsync+0x40/0x90 __arm64_sys_fsync+0x34/0x50 invoke_syscall.constprop.0+0xa8/0x260 do_el0_svc+0xc8/0x1f0 el0_svc+0x34/0x70 el0t_64_sync_handler+0x108/0x114 el0t_64_sync+0x1a4/0x1a8 Freed by task 403: kasan_save_stack+0x38/0x70 kasan_set_track+0x28/0x40 kasan_set_free_info+0x28/0x4c __kasan_slab_free+0xd4/0x13c kfree+0xc4/0x3a0 tnc_delete+0x3f4/0xe40 ubifs_tnc_remove_range+0x368/0x73c ubifs_tnc_remove_ino+0x29c/0x2e0 ubifs_jnl_delete_inode+0x150/0x260 ubifs_evict_inode+0x1d4/0x2e4 evict+0x1c8/0x450 iput+0x2a0/0x3c4 do_unlinkat+0x2cc/0x490 __arm64_sys_unlinkat+0x90/0x100 invoke_syscall.constprop.0+0xa8/0x260 do_el0_svc+0xc8/0x1f0 el0_svc+0x34/0x70 el0t_64_sync_handler+0x108/0x114 el0t_64_sync+0x1a4/0x1a8
The offending memcpy() in ubifs_copy_hash() has a use-after-free when a node becomes root in TNC but still has a cparent to an already freed node. More specifically, consider the following TNC:
zroot
/
/
zp1
/
/
znInserting a new node zn_new with a key smaller then zn will trigger a split in tnc_insert() if zp1 is full:
zroot
/ \
/ \
zp1 zp2
/ \
/ \ zn_new zn
zn->parent has now been moved to zp2, *but* zn->cparent still points to zp1.
Now, consider a removal of all the nodes _except_ zn. Just when tnc_delete() is about to delete zroot and zp2:
zroot
\
\
zp2
\
\
znzroot and zp2 get freed and the tree collapses:
zn
zn now becomes the new zroot.
get_znodes_to_commit() will now only find zn, the new zroot, and write_index() will check its znode->cparent that wrongly points to the already freed zp1. ubifs_copy_hash() thus gets wrongly called with znode->cparent->zbranch[znode->iip].hash that triggers the use-after-free!
Fix this by explicitly setting znode->cparent to NULL in get_znodes_to_commit() for the root node. The search for the dirty nodes is bottom-up in the tree. Thus, when find_next_dirty(znode) returns NULL, the current znode _is_ the root node. Add an assert for this.
--- fs/ubifs/tnc_commit.c | 2 ++ 1 file changed, 2 insertions(+)
fs/ubifs/tnc_commit.c +2 -0
@@ -657,6 +657,8 @@ static int get_znodes_to_commit(struct ubifs_info *c) znode->alt =0 ; cnext =find_next_dirty (znode);if (!cnext) { +ubifs_assert (c, !znode->parent); + znode->cparent =NULL ; znode->cnext = c->cnext;break ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 364/565 jffs2: fix use of uninitialized variable
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qingfang Deng <[email protected]>
[ Upstream commit 3ba44ee966bc3c41dd8a944f963466c8fcc60dc8 ]
When building the kernel with -Wmaybe-uninitialized, the compiler reports this warning:
In function 'jffs2_mark_erased_block',
inlined from 'jffs2_erase_pending_blocks' at fs/jffs2/erase.c:116:4:fs/jffs2/erase.c:474:9: warning: 'bad_offset' may be used uninitialized [-Wmaybe-uninitialized]
474 | jffs2_erase_failed(c, jeb, bad_offset);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fs/jffs2/erase.c: In function 'jffs2_erase_pending_blocks':
fs/jffs2/erase.c:402:18: note: 'bad_offset' was declared here
402 | uint32_t bad_offset;
| ^~~~~~~~~~When mtd->point() is used, jffs2_erase_pending_blocks can return -EIO without initializing bad_offset, which is later used at the filebad label in jffs2_mark_erased_block.
Fix it by initializing this variable.
--- fs/jffs2/erase.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
fs/jffs2/erase.c +3 -4
@@ -340,10 +340,9 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl }while (--retlen);mtd_unpoint (c->mtd, jeb->offset, c->sector_size);if (retlen) { -pr_warn ("Newly-erased block contained word 0x%lx at offset 0x%08tx\n" , - *wordebuf, - jeb->offset + - c->sector_size-retlen *sizeof (*wordebuf)); + *bad_offset = jeb->offset + c->sector_size - retlen *sizeof (*wordebuf); +pr_warn ("Newly-erased block contained word 0x%lx at offset 0x%08x\n" , + *wordebuf, *bad_offset);return -EIO ; }return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 365/565 block: return unsigned int from bdev_io_min
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <[email protected]>
[ Upstream commit 46fd48ab3ea3eb3bb215684bd66ea3d260b091a9 ]
The underlying limit is defined as an unsigned int, so return that from bdev_io_min as well.
--- include/linux/blkdev.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/blkdev.h +1 -1
@@ -1429,7 +1429,7 @@ static inline unsigned int queue_io_min(const struct request_queue *q)return q->limits.io_min; } -static inline int bdev_io_min (struct block_device *bdev) +static inline unsigned int bdev_io_min (struct block_device *bdev) {return queue_io_min (bdev_get_queue (bdev)); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 366/565 9p/xen: fix init sequence
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Zenla <[email protected]>
[ Upstream commit 7ef3ae82a6ebbf4750967d1ce43bcdb7e44ff74b ]
Large amount of mount hangs observed during hotplugging of 9pfs devices. The 9pfs Xen driver attempts to initialize itself more than once, causing the frontend and backend to disagree: the backend listens on a channel that the frontend does not send on, resulting in stalled processing.
Only allow initialization of 9p frontend once.
Message-ID: <[email protected]>
--- net/9p/trans_xen.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
net/9p/trans_xen.c +5 -2
@@ -487,6 +487,7 @@ static int xen_9pfs_front_init(struct xenbus_device *dev) goto error; } +xenbus_switch_state (dev, XenbusStateInitialised);return 0 ; error_xenbus:
@@ -534,8 +535,10 @@ static void xen_9pfs_front_changed(struct xenbus_device *dev,break ;case XenbusStateInitWait: -if (!xen_9pfs_front_init (dev)) -xenbus_switch_state (dev, XenbusStateInitialised); +if (dev->state != XenbusStateInitialising) +break ; + +xen_9pfs_front_init (dev);break ;case XenbusStateConnected:
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 367/565 9p/xen: fix release of IRQ
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Zenla <[email protected]>
[ Upstream commit e43c608f40c065b30964f0a806348062991b802d ]
Kernel logs indicate an IRQ was double-freed.
Pass correct device ID during IRQ release.
Message-ID: <[email protected]>
--- net/9p/trans_xen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/9p/trans_xen.c +1 -1
@@ -307,7 +307,7 @@ static void xen_9pfs_front_free(struct xen_9pfs_front_priv *priv)if (!priv->rings[i].intf)break ;if (priv->rings[i].irq >0 ) -unbind_from_irqhandler (priv->rings[i].irq, priv->dev); +unbind_from_irqhandler (priv->rings[i].irq, ring);if (priv->rings[i].data.in) { for (j = 0; j < (1 << priv->rings[i].intf->ring_order);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 368/565 rtc: ab-eoz9: dont fail temperature reads on undervoltage notification
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maxime Chevallier <[email protected]>
[ Upstream commit e0779a0dcf41a6452ac0a169cd96863feb5787c7 ]
The undervoltage flags reported by the RTC are useful to know if the time and date are reliable after a reboot. Although the threshold VLOW1 indicates that the thermometer has been shutdown and time compensation is off, it doesn't mean that the temperature readout is currently impossible.
As the system is running, the RTC voltage is now fully established and we can read the temperature.
--- drivers/rtc/rtc-ab-eoz9.c | 7 ------- 1 file changed, 7 deletions(-)
drivers/rtc/rtc-ab-eoz9.c +0 -7
@@ -396,13 +396,6 @@ static int abeoz9z3_temp_read(struct device *dev,if (ret <0 )return ret; -if ((val &ABEOZ9_REG_CTRL_STATUS_V1F ) || - (val &ABEOZ9_REG_CTRL_STATUS_V2F )) { -dev_err (dev, -"thermometer might be disabled due to low voltage\n" ); -return -EINVAL ; - } -switch (attr) {case hwmon_temp_input: ret =regmap_read (regmap,ABEOZ9_REG_REG_TEMP , &val);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 369/565 modpost: remove incorrect code in do_eisa_entry()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masahiro Yamada <[email protected]>
[ Upstream commit 0c3e091319e4748cb36ac9a50848903dc6f54054 ]
This function contains multiple bugs after the following commits:
- ac551828993e ("modpost: i2c aliases need no trailing wildcard")
- 6543becf26ff ("mod/file2alias: make modalias generation safe for cross compiling")
Commit ac551828993e inserted the following code to do_eisa_entry():
else
strcat(alias, "*");
This is incorrect because 'alias' is uninitialized. If it is not NULL-terminated, strcat() could cause a buffer overrun.
Even if 'alias' happens to be zero-filled, it would output:
MODULE_ALIAS("*");This would match anything. As a result, the module could be loaded by any unrelated uevent from an unrelated subsystem.
Commit ac551828993e introduced another bug.
Prior to that commit, the conditional check was:
if (eisa->sig[0])
This checked if the first character of eisa_device_id::sig was not '\0'.
However, commit ac551828993e changed it as follows:
if (sig[0])
sig[0] is NOT the first character of the eisa_device_id::sig. The type of 'sig' is 'char (*)[8]', meaning that the type of 'sig[0]' is 'char [8]' instead of 'char'. 'sig[0]' and 'symval' refer to the same address, which never becomes NULL.
The correct conversion would have been:
if ((*sig)[0])
However, this if-conditional was meaningless because the earlier change in commit ac551828993e was incorrect.
This commit removes the entire incorrect code, which should never have been executed.
--- scripts/mod/file2alias.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
scripts/mod/file2alias.c +1 -4
@@ -799,10 +799,7 @@ static int do_eisa_entry(const char *filename, void *symval, char *alias) {DEF_FIELD_ADDR (symval, eisa_device_id, sig); -if (sig[0 ]) -sprintf (alias,EISA_DEVICE_MODALIAS_FMT "*" , *sig); -else -strcat (alias,"*" ); +sprintf (alias,EISA_DEVICE_MODALIAS_FMT "*" , *sig);return 1 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 370/565 nfs: ignore SB_RDONLY when mounting nfs
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Lingfeng <[email protected]>
[ Upstream commit 52cb7f8f177878b4f22397b9c4d2c8f743766be3 ]
When exporting only one file system with fsid=0 on the server side, the client alternately uses the ro/rw mount options to perform the mount operation, and a new vfsmount is generated each time.
It can be reproduced as follows:
[root@localhost ~]# mount /dev/sda /mnt2
[root@localhost ~]# echo "/mnt2 *(rw,no_root_squash,fsid=0)" >/etc/exports [root@localhost ~]# systemctl restart nfs-server [root@localhost ~]# mount -t nfs -o ro,vers=4 127.0.0.1:/ /mnt/sdaa [root@localhost ~]# mount -t nfs -o rw,vers=4 127.0.0.1:/ /mnt/sdaa [root@localhost ~]# mount -t nfs -o ro,vers=4 127.0.0.1:/ /mnt/sdaa [root@localhost ~]# mount -t nfs -o rw,vers=4 127.0.0.1:/ /mnt/sdaa [root@localhost ~]# mount | grep nfs4
127.0.0.1:/ on /mnt/sdaa type nfs4 (ro,relatime,vers=4.2,rsize=1048576,... 127.0.0.1:/ on /mnt/sdaa type nfs4 (rw,relatime,vers=4.2,rsize=1048576,... 127.0.0.1:/ on /mnt/sdaa type nfs4 (ro,relatime,vers=4.2,rsize=1048576,... 127.0.0.1:/ on /mnt/sdaa type nfs4 (rw,relatime,vers=4.2,rsize=1048576,... [root@localhost ~]#
We expected that after mounting with the ro option, using the rw option to mount again would return EBUSY, but the actual situation was not the case.
As shown above, when mounting for the first time, a superblock with the ro flag will be generated, and at the same time, in do_new_mount_fc --> do_add_mount, it detects that the superblock corresponding to the current target directory is inconsistent with the currently generated one (path->mnt->mnt_sb != newmnt->mnt.mnt_sb), and a new vfsmount will be generated.
When mounting with the rw option for the second time, since no matching superblock can be found in the fs_supers list, a new superblock with the rw flag will be generated again. The superblock in use (ro) is different from the newly generated superblock (rw), and a new vfsmount will be generated again.
When mounting with the ro option for the third time, the superblock (ro) is found in fs_supers, the superblock in use (rw) is different from the found superblock (ro), and a new vfsmount will be generated again.
We can switch between ro/rw through remount, and only one superblock needs to be generated, thus avoiding the problem of repeated generation of vfsmount caused by switching superblocks.
Furthermore, This can also resolve the issue described in the link.
--- fs/nfs/internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfs/internal.h +1 -1
@@ -11,7 +11,7 @@#include <linux/nfs_page.h> #include <linux/wait_bit.h> -#define NFS_SB_MASK (SB_RDONLY|SB_NOSUID|SB_NODEV|SB_NOEXEC|SB_SYNCHRONOUS) +#define NFS_SB_MASK (SB_NOSUID|SB_NODEV|SB_NOEXEC|SB_SYNCHRONOUS)extern const struct export_operations nfs_export_ops;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 371/565 sunrpc: remove unnecessary test in rpc_task_set_client()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thiago Rafael Becker <[email protected]>
[ Upstream commit 023859ce6f88f7cfc223752fb56ec453a147b852 ]
In rpc_task_set_client(), testing for a NULL clnt is not necessary, as clnt should always be a valid pointer to a rpc_client.
Stable-dep-of: 4db9ad82a6c8 ("sunrpc: clear XPRT_SOCK_UPD_TIMEOUT when reset transport")
--- net/sunrpc/clnt.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-)
net/sunrpc/clnt.c +15 -18
@@ -1096,24 +1096,21 @@ void rpc_task_set_transport(struct rpc_task *task, struct rpc_clnt *clnt)static void rpc_task_set_client (struct rpc_task *task,struct rpc_clnt *clnt) { - -if (clnt !=NULL ) { -rpc_task_set_transport (task, clnt); - task->tk_client = clnt; -refcount_inc (&clnt->cl_count); -if (clnt->cl_softrtry) - task->tk_flags |=RPC_TASK_SOFT ; -if (clnt->cl_softerr) - task->tk_flags |=RPC_TASK_TIMEOUT ; -if (clnt->cl_noretranstimeo) - task->tk_flags |=RPC_TASK_NO_RETRANS_TIMEOUT ; -if (atomic_read (&clnt->cl_swapper)) - task->tk_flags |=RPC_TASK_SWAPPER ; -/* Add to the client's list of all tasks */ -spin_lock (&clnt->cl_lock); -list_add_tail (&task->tk_task, &clnt->cl_tasks); -spin_unlock (&clnt->cl_lock); - } +rpc_task_set_transport (task, clnt); + task->tk_client = clnt; +refcount_inc (&clnt->cl_count); +if (clnt->cl_softrtry) + task->tk_flags |=RPC_TASK_SOFT ; +if (clnt->cl_softerr) + task->tk_flags |=RPC_TASK_TIMEOUT ; +if (clnt->cl_noretranstimeo) + task->tk_flags |=RPC_TASK_NO_RETRANS_TIMEOUT ; +if (atomic_read (&clnt->cl_swapper)) + task->tk_flags |=RPC_TASK_SWAPPER ; +/* Add to the client's list of all tasks */ +spin_lock (&clnt->cl_lock); +list_add_tail (&task->tk_task, &clnt->cl_tasks); +spin_unlock (&clnt->cl_lock); } static void
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 372/565 SUNRPC: Replace internal use of SOCKWQ_ASYNC_NOSPACE
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
[ Upstream commit 2790a624d43084de590884934969e19c7a82316a ]
The socket's SOCKWQ_ASYNC_NOSPACE can be cleared by various actors in the socket layer, so replace it with our own flag in the transport sock_state field.
Stable-dep-of: 4db9ad82a6c8 ("sunrpc: clear XPRT_SOCK_UPD_TIMEOUT when reset transport")
--- include/linux/sunrpc/xprtsock.h | 1 + net/sunrpc/xprtsock.c | 22 ++++------------------ 2 files changed, 5 insertions(+), 18 deletions(-)
include/linux/sunrpc/xprtsock.h +1 -0
@@ -90,5 +90,6 @@ struct sock_xprt {#define XPRT_SOCK_WAKE_PENDING (6)#define XPRT_SOCK_WAKE_DISCONNECT (7)#define XPRT_SOCK_CONNECT_SENT (8) +#define XPRT_SOCK_NOSPACE (9)#endif /* _LINUX_SUNRPC_XPRTSOCK_H */
net/sunrpc/xprtsock.c +4 -18
@@ -779,14 +779,8 @@ static int xs_nospace(struct rpc_rqst *req, struct sock_xprt *transport)/* Don't race with disconnect */ if (xprt_connected (xprt)) { -struct socket_wq *wq; - -rcu_read_lock (); - wq =rcu_dereference (sk->sk_wq); -set_bit (SOCKWQ_ASYNC_NOSPACE , &wq->flags); -rcu_read_unlock (); -/* wait for more buffer space */ +set_bit (XPRT_SOCK_NOSPACE , &transport->sock_state);set_bit (SOCK_NOSPACE , &sk->sk_socket->flags); sk->sk_write_pending++;xprt_wait_for_buffer_space (xprt);
@@ -1148,6 +1142,7 @@ static void xs_sock_reset_state_flags(struct rpc_xprt *xprt)clear_bit (XPRT_SOCK_WAKE_ERROR , &transport->sock_state);clear_bit (XPRT_SOCK_WAKE_WRITE , &transport->sock_state);clear_bit (XPRT_SOCK_WAKE_DISCONNECT , &transport->sock_state); +clear_bit (XPRT_SOCK_NOSPACE , &transport->sock_state); }static void xs_run_error_worker (struct sock_xprt *transport,unsigned int nr)
@@ -1511,7 +1506,6 @@ static void xs_tcp_state_change(struct sock *sk)static void xs_write_space (struct sock *sk) { -struct socket_wq *wq;struct sock_xprt *transport;struct rpc_xprt *xprt;
@@ -1522,15 +1516,10 @@ static void xs_write_space(struct sock *sk)if (unlikely (!(xprt =xprt_from_sock (sk))))return ; transport = container_of(xprt, struct sock_xprt, xprt); -rcu_read_lock (); - wq =rcu_dereference (sk->sk_wq); -if (!wq ||test_and_clear_bit (SOCKWQ_ASYNC_NOSPACE , &wq->flags) ==0 ) - goto out; - +if (!test_and_clear_bit (XPRT_SOCK_NOSPACE , &transport->sock_state)) +return ;xs_run_error_worker (transport,XPRT_SOCK_WAKE_WRITE ); sk->sk_write_pending--; -out: -rcu_read_unlock (); }/**
@@ -1874,7 +1863,6 @@ static int xs_local_finish_connecting(struct rpc_xprt *xprt, sk->sk_user_data = xprt; sk->sk_data_ready = xs_data_ready; sk->sk_write_space = xs_udp_write_space; -sock_set_flag (sk,SOCK_FASYNC ); sk->sk_error_report = xs_error_report;xprt_clear_connected (xprt);
@@ -2072,7 +2060,6 @@ static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) sk->sk_user_data = xprt; sk->sk_data_ready = xs_data_ready; sk->sk_write_space = xs_udp_write_space; -sock_set_flag (sk,SOCK_FASYNC );xprt_set_connected (xprt);
@@ -2237,7 +2224,6 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) sk->sk_data_ready = xs_data_ready; sk->sk_state_change = xs_tcp_state_change; sk->sk_write_space = xs_tcp_write_space; -sock_set_flag (sk,SOCK_FASYNC ); sk->sk_error_report = xs_error_report;/* socket options */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 373/565 sunrpc: clear XPRT_SOCK_UPD_TIMEOUT when reset transport
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liu Jian <[email protected]>
[ Upstream commit 4db9ad82a6c823094da27de4825af693a3475d51 ]
Since transport->sock has been set to NULL during reset transport, XPRT_SOCK_UPD_TIMEOUT also needs to be cleared. Otherwise, the xs_tcp_set_socket_timeouts() may be triggered in xs_tcp_send_request() to dereference the transport->sock that has been set to NULL.
--- net/sunrpc/xprtsock.c | 1 + 1 file changed, 1 insertion(+)
net/sunrpc/xprtsock.c +1 -0
@@ -1143,6 +1143,7 @@ static void xs_sock_reset_state_flags(struct rpc_xprt *xprt)clear_bit (XPRT_SOCK_WAKE_WRITE , &transport->sock_state);clear_bit (XPRT_SOCK_WAKE_DISCONNECT , &transport->sock_state);clear_bit (XPRT_SOCK_NOSPACE , &transport->sock_state); +clear_bit (XPRT_SOCK_UPD_TIMEOUT , &transport->sock_state); }static void xs_run_error_worker (struct sock_xprt *transport,unsigned int nr)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 374/565 sh: intc: Fix use-after-free bug in register_intc_controller()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit 63e72e551942642c48456a4134975136cdcb9b3c ]
In the error handling for this function, d is freed without ever removing it from intc_list which would lead to a use after free. To fix this, let's only add it to the list after everything has succeeded.
--- drivers/sh/intc/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/sh/intc/core.c +1 -1
@@ -209,7 +209,6 @@ int __init register_intc_controller(struct intc_desc *desc) goto err0;INIT_LIST_HEAD (&d->list); -list_add_tail (&d->list, &intc_list);raw_spin_lock_init (&d->lock);INIT_RADIX_TREE (&d->tree,GFP_ATOMIC );
@@ -369,6 +368,7 @@ int __init register_intc_controller(struct intc_desc *desc) d->skip_suspend = desc->skip_syscore_suspend; +list_add_tail (&d->list, &intc_list); nr_intc_controllers++;return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 375/565 ASoC: fsl_micfil: fix the naming style for mask definition
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengjiu Wang <[email protected]>
commit 101b096bc2549618f18bc08ae3a0e364b3c8fff1 upstream.
Remove the _SHIFT for the mask definition.
--- sound/soc/fsl/fsl_micfil.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
sound/soc/fsl/fsl_micfil.h +4 -4
@@ -75,9 +75,9 @@#define MICFIL_FIFO_STAT_FIFOX_UNDER (ch) BIT((ch) + 8)/* MICFIL HWVAD0 Control 1 Register -- REG_MICFIL_VAD0_CTRL1*/ -#define MICFIL_VAD0_CTRL1_CHSEL_SHIFT GENMASK(26, 24) -#define MICFIL_VAD0_CTRL1_CICOSR_SHIFT GENMASK(19, 16) -#define MICFIL_VAD0_CTRL1_INITT_SHIFT GENMASK(12, 8) +#define MICFIL_VAD0_CTRL1_CHSEL GENMASK(26, 24) +#define MICFIL_VAD0_CTRL1_CICOSR GENMASK(19, 16) +#define MICFIL_VAD0_CTRL1_INITT GENMASK(12, 8)#define MICFIL_VAD0_CTRL1_ST10 BIT(4)#define MICFIL_VAD0_CTRL1_ERIE BIT(3)#define MICFIL_VAD0_CTRL1_IE BIT(2)
@@ -107,7 +107,7 @@/* MICFIL HWVAD0 Zero-Crossing Detector - REG_MICFIL_VAD0_ZCD */ #define MICFIL_VAD0_ZCD_ZCDTH GENMASK(25, 16) -#define MICFIL_VAD0_ZCD_ZCDADJ_SHIFT GENMASK(11, 8) +#define MICFIL_VAD0_ZCD_ZCDADJ GENMASK(11, 8)#define MICFIL_VAD0_ZCD_ZCDAND BIT(4)#define MICFIL_VAD0_ZCD_ZCDAUT BIT(2)#define MICFIL_VAD0_ZCD_ZCDEN BIT(0)
Greg Kroah-Hartman
maintainerPATCH 376/565 xfs: fix log recovery when unknown rocompat bits are set
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <[email protected]>
[ Upstream commit 74ad4693b6473950e971b3dc525b5ee7570e05d0 ]
Log recovery has always run on read only mounts, even where the primary superblock advertises unknown rocompat bits. Due to a misunderstanding between Eric and Darrick back in 2018, we accidentally changed the superblock write verifier to shutdown the fs over that exact scenario. As a result, the log cleaning that occurs at the end of the mounting process fails if there are unknown rocompat bits set.
As we now allow writing of the superblock if there are unknown rocompat bits set on a RO mount, we no longer want to turn off RO state to allow log recovery to succeed on a RO mount. Hence we also remove all the (now unnecessary) RO state toggling from the log recovery path.
Stable-dep-of: 652f03db897b ("xfs: remove unknown compat feature check in superblock write validation")
--- fs/xfs/libxfs/xfs_sb.c | 3 ++- fs/xfs/xfs_log.c | 17 ----------------- 2 files changed, 2 insertions(+), 18 deletions(-)
fs/xfs/libxfs/xfs_sb.c +2 -1
@@ -263,7 +263,8 @@ xfs_validate_sb_write(return -EFSCORRUPTED ; } -if (xfs_sb_has_ro_compat_feature (sbp,XFS_SB_FEAT_RO_COMPAT_UNKNOWN )) { +if (!xfs_is_readonly (mp) && +xfs_sb_has_ro_compat_feature (sbp,XFS_SB_FEAT_RO_COMPAT_UNKNOWN )) { xfs_alert(mp, "Corruption detected in superblock read-only compatible features (0x%x)!", (sbp->sb_features_ro_compat &
fs/xfs/xfs_log.c +0 -17
@@ -707,15 +707,7 @@ xfs_log_mount(* just worked. */ if (!xfs_has_norecovery (mp)) { -/* -* log recovery ignores readonly state and so we need to clear -* mount-based read only state so it can write to disk. -*/ -bool readonly =test_and_clear_bit (XFS_OPSTATE_READONLY , - &mp->m_opstate); error =xlog_recover (log); -if (readonly) -set_bit (XFS_OPSTATE_READONLY , &mp->m_opstate);if (error) {xfs_warn (mp,"log mount/recovery failed: error %d" , error);
@@ -764,7 +756,6 @@ xfs_log_mount_finish( struct xfs_mount *mp) {struct xlog *log = mp->m_log; -bool readonly;int error =0 ;if (xfs_has_norecovery (mp)) {
@@ -772,12 +763,6 @@ xfs_log_mount_finish(return 0 ; } -/* -* log recovery ignores readonly state and so we need to clear -* mount-based read only state so it can write to disk. -*/ - readonly =test_and_clear_bit (XFS_OPSTATE_READONLY , &mp->m_opstate); -/* * During the second phase of log recovery, we need iget and * iput to behave like they do for an active filesystem.
@@ -828,8 +813,6 @@ xfs_log_mount_finish(xfs_buftarg_drain (mp->m_ddev_targp);clear_bit (XLOG_RECOVERY_NEEDED , &log->l_opstate); -if (readonly) -set_bit (XFS_OPSTATE_READONLY , &mp->m_opstate);/* Make sure the log is dead if we're returning failure. */ ASSERT (!error ||xlog_is_shutdown (log));
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 377/565 xfs: remove unknown compat feature check in superblock write validation
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Long Li <[email protected]>
[ Upstream commit 652f03db897ba24f9c4b269e254ccc6cc01ff1b7 ]
Compat features are new features that older kernels can safely ignore, allowing read-write mounts without issues. The current sb write validation implementation returns -EFSCORRUPTED for unknown compat features, preventing filesystem write operations and contradicting the feature's definition.
Additionally, if the mounted image is unclean, the log recovery may need to write to the superblock. Returning an error for unknown compat features during sb write validation can cause mount failures.
Although XFS currently does not use compat feature flags, this issue affects current kernels' ability to mount images that may use compat feature flags in the future.
Since superblock read validation already warns about unknown compat features, it's unnecessary to repeat this warning during write validation. Therefore, the relevant code in write validation is being removed.
--- fs/xfs/libxfs/xfs_sb.c | 7 ------- 1 file changed, 7 deletions(-)
fs/xfs/libxfs/xfs_sb.c +0 -7
@@ -256,13 +256,6 @@ xfs_validate_sb_write(* the kernel cannot support since we checked for unsupported bits in * the read verifier, which means that memory is corrupt. */ -if (xfs_sb_has_compat_feature (sbp,XFS_SB_FEAT_COMPAT_UNKNOWN )) { -xfs_warn (mp, -"Corruption detected in superblock compatible features (0x%x)!" , - (sbp->sb_features_compat &XFS_SB_FEAT_COMPAT_UNKNOWN )); -return -EFSCORRUPTED ; - } -if (!xfs_is_readonly (mp) &&xfs_sb_has_ro_compat_feature (sbp,XFS_SB_FEAT_RO_COMPAT_UNKNOWN )) { xfs_alert(mp,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 378/565 quota: flush quota_release_work upon quota writeback
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ojaswin Mujoo <[email protected]>
[ Upstream commit ac6f420291b3fee1113f21d612fa88b628afab5b ]
One of the paths quota writeback is called from is:
freeze_super()
sync_filesystem()
ext4_sync_fs()
dquot_writeback_dquots()Since we currently don't always flush the quota_release_work queue in this path, we can end up with the following race:
1. dquot are added to releasing_dquots list during regular operations.
2. FS Freeze starts, however, this does not flush the quota_release_work queue.
3. Freeze completes.
4. Kernel eventually tries to flush the workqueue while FS is frozen which hits a WARN_ON since transaction gets started during frozen state:
ext4_journal_check_start+0x28/0x110 [ext4] (unreliable) __ext4_journal_start_sb+0x64/0x1c0 [ext4] ext4_release_dquot+0x90/0x1d0 [ext4] quota_release_workfn+0x43c/0x4d0
Which is the following line:
WARN_ON(sb->s_writers.frozen == SB_FREEZE_COMPLETE);
Which ultimately results in generic/390 failing due to dmesg noise. This was detected on powerpc machine 15 cores.
To avoid this, make sure to flush the workqueue during dquot_writeback_dquots() so we dont have any pending workitems after freeze.
--- fs/quota/dquot.c | 2 ++ 1 file changed, 2 insertions(+)
fs/quota/dquot.c +2 -0
@@ -690,6 +690,8 @@ int dquot_writeback_dquots(struct super_block *sb, int type)WARN_ON_ONCE (!rwsem_is_locked (&sb->s_umount)); +flush_delayed_work ("a_release_work); +for (cnt =0 ; cnt <MAXQUOTAS ; cnt++) {if (type !=-1 && cnt != type)continue ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 379/565 btrfs: add might_sleep() annotations
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: ChenXiaoSong <[email protected]>
[ Upstream commit a4c853af0c511d7e0f7cb306bbc8a4f1dbdb64ca ]
Add annotations to functions that might sleep due to allocations or IO and could be called from various contexts. In case of btrfs_search_slot it's not obvious why it would sleep:
btrfs_search_slot
setup_nodes_for_search
reada_for_balance
btrfs_readahead_node_child
btrfs_readahead_tree_block
btrfs_find_create_tree_block
alloc_extent_buffer
kmem_cache_zalloc
/* allocate memory non-atomically, might sleep */
kmem_cache_alloc(GFP_NOFS|__GFP_NOFAIL|__GFP_ZERO)
read_extent_buffer_pages
submit_extent_page
/* disk IO, might sleep */
submit_one_bioOther examples where the sleeping could happen is in 3 places might sleep in update_qgroup_limit_item(), as shown below:
update_qgroup_limit_item
btrfs_alloc_path
/* allocate memory non-atomically, might sleep */
kmem_cache_zalloc(btrfs_path_cachep, GFP_NOFS)Stable-dep-of: 3ed51857a50f ("btrfs: add a sanity check for btrfs root in btrfs_search_slot()")
--- fs/btrfs/ctree.c | 4 ++++ 1 file changed, 4 insertions(+)
fs/btrfs/ctree.c +4 -0
@@ -76,6 +76,8 @@ size_t __attribute_const__ btrfs_get_num_csums(void)struct btrfs_path *btrfs_alloc_path (void ) { +might_sleep (); +return kmem_cache_zalloc (btrfs_path_cachep,GFP_NOFS ); }
@@ -1774,6 +1776,8 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root,int min_write_lock_level;int prev_cmp; +might_sleep (); + lowest_level = p->lowest_level;WARN_ON (lowest_level && ins_len >0 );WARN_ON (p->nodes[0 ] !=NULL );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 380/565 btrfs: add a sanity check for btrfs root in btrfs_search_slot()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lizhi Xu <[email protected]>
[ Upstream commit 3ed51857a50f530ac7a1482e069dfbd1298558d4 ]
Syzbot reports a null-ptr-deref in btrfs_search_slot().
The reproducer is using rescue=ibadroots, and the extent tree root is corrupted thus the extent tree is NULL.
When scrub tries to search the extent tree to gather the needed extent info, btrfs_search_slot() doesn't check if the target root is NULL or not, resulting the null-ptr-deref.
Add sanity check for btrfs root before using it in btrfs_search_slot().
--- fs/btrfs/ctree.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
fs/btrfs/ctree.c +5 -1
@@ -1763,7 +1763,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root, const struct btrfs_key *key, struct btrfs_path *p, int ins_len, int cow) { - struct btrfs_fs_info *fs_info = root->fs_info; + struct btrfs_fs_info *fs_info;struct extent_buffer *b;int slot;int ret;
@@ -1776,6 +1776,10 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root,int min_write_lock_level;int prev_cmp; +if (!root) +return -EINVAL ; + + fs_info = root->fs_info;might_sleep (); lowest_level = p->lowest_level;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 381/565 btrfs: ref-verify: fix use-after-free after invalid ref action
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit 7c4e39f9d2af4abaf82ca0e315d1fd340456620f ]
At btrfs_ref_tree_mod() after we successfully inserted the new ref entry (local variable 'ref') into the respective block entry's rbtree (local variable 'be'), if we find an unexpected action of BTRFS_DROP_DELAYED_REF, we error out and free the ref entry without removing it from the block entry's rbtree. Then in the error path of btrfs_ref_tree_mod() we call btrfs_free_ref_cache(), which iterates over all block entries and then calls free_block_entry() for each one, and there we will trigger a use-after-free when we are called against the block entry to which we added the freed ref entry to its rbtree, since the rbtree still points to the block entry, as we didn't remove it from the rbtree before freeing it in the error path at btrfs_ref_tree_mod(). Fix this by removing the new ref entry from the rbtree before freeing it.
Syzbot report this with the following stack traces:
BTRFS error (device loop0 state EA): Ref action 2, root 5, ref_root 0, parent 8564736, owner 0, offset 0, num_refs 18446744073709551615
__btrfs_mod_ref+0x7dd/0xac0 fs/btrfs/extent-tree.c:2523
update_ref_for_cow+0x9cd/0x11f0 fs/btrfs/ctree.c:512
btrfs_force_cow_block+0x9f6/0x1da0 fs/btrfs/ctree.c:594
btrfs_cow_block+0x35e/0xa40 fs/btrfs/ctree.c:754
btrfs_search_slot+0xbdd/0x30d0 fs/btrfs/ctree.c:2116
btrfs_insert_empty_items+0x9c/0x1a0 fs/btrfs/ctree.c:4314
btrfs_insert_empty_item fs/btrfs/ctree.h:669 [inline]
btrfs_insert_orphan_item+0x1f1/0x320 fs/btrfs/orphan.c:23
btrfs_orphan_add+0x6d/0x1a0 fs/btrfs/inode.c:3482
btrfs_unlink+0x267/0x350 fs/btrfs/inode.c:4293
vfs_unlink+0x365/0x650 fs/namei.c:4469
do_unlinkat+0x4ae/0x830 fs/namei.c:4533
__do_sys_unlinkat fs/namei.c:4576 [inline]
__se_sys_unlinkat fs/namei.c:4569 [inline]
__x64_sys_unlinkat+0xcc/0xf0 fs/namei.c:4569
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x77/0x7f
BTRFS error (device loop0 state EA): Ref action 1, root 5, ref_root 5, parent 0, owner 260, offset 0, num_refs 1
__btrfs_mod_ref+0x76b/0xac0 fs/btrfs/extent-tree.c:2521
update_ref_for_cow+0x96a/0x11f0
btrfs_force_cow_block+0x9f6/0x1da0 fs/btrfs/ctree.c:594
btrfs_cow_block+0x35e/0xa40 fs/btrfs/ctree.c:754
btrfs_search_slot+0xbdd/0x30d0 fs/btrfs/ctree.c:2116
btrfs_lookup_inode+0xdc/0x480 fs/btrfs/inode-item.c:411
__btrfs_update_delayed_inode+0x1e7/0xb90 fs/btrfs/delayed-inode.c:1030
btrfs_update_delayed_inode fs/btrfs/delayed-inode.c:1114 [inline]
__btrfs_commit_inode_delayed_items+0x2318/0x24a0 fs/btrfs/delayed-inode.c:1137
__btrfs_run_delayed_items+0x213/0x490 fs/btrfs/delayed-inode.c:1171
btrfs_commit_transaction+0x8a8/0x3740 fs/btrfs/transaction.c:2313
prepare_to_relocate+0x3c4/0x4c0 fs/btrfs/relocation.c:3586
relocate_block_group+0x16c/0xd40 fs/btrfs/relocation.c:3611
btrfs_relocate_block_group+0x77d/0xd90 fs/btrfs/relocation.c:4081
btrfs_relocate_chunk+0x12c/0x3b0 fs/btrfs/volumes.c:3377
__btrfs_balance+0x1b0f/0x26b0 fs/btrfs/volumes.c:4161
btrfs_balance+0xbdc/0x10c0 fs/btrfs/volumes.c:4538
BTRFS error (device loop0 state EA): Ref action 2, root 5, ref_root 0, parent 8564736, owner 0, offset 0, num_refs 18446744073709551615
__btrfs_mod_ref+0x7dd/0xac0 fs/btrfs/extent-tree.c:2523
update_ref_for_cow+0x9cd/0x11f0 fs/btrfs/ctree.c:512
btrfs_force_cow_block+0x9f6/0x1da0 fs/btrfs/ctree.c:594
btrfs_cow_block+0x35e/0xa40 fs/btrfs/ctree.c:754
btrfs_search_slot+0xbdd/0x30d0 fs/btrfs/ctree.c:2116
btrfs_lookup_inode+0xdc/0x480 fs/btrfs/inode-item.c:411
__btrfs_update_delayed_inode+0x1e7/0xb90 fs/btrfs/delayed-inode.c:1030
btrfs_update_delayed_inode fs/btrfs/delayed-inode.c:1114 [inline]
__btrfs_commit_inode_delayed_items+0x2318/0x24a0 fs/btrfs/delayed-inode.c:1137
__btrfs_run_delayed_items+0x213/0x490 fs/btrfs/delayed-inode.c:1171
btrfs_commit_transaction+0x8a8/0x3740 fs/btrfs/transaction.c:2313
prepare_to_relocate+0x3c4/0x4c0 fs/btrfs/relocation.c:3586
relocate_block_group+0x16c/0xd40 fs/btrfs/relocation.c:3611
btrfs_relocate_block_group+0x77d/0xd90 fs/btrfs/relocation.c:4081
btrfs_relocate_chunk+0x12c/0x3b0 fs/btrfs/volumes.c:3377
__btrfs_balance+0x1b0f/0x26b0 fs/btrfs/volumes.c:4161
btrfs_balance+0xbdc/0x10c0 fs/btrfs/volumes.c:4538
==================================================================
BUG: KASAN: slab-use-after-free in rb_first+0x69/0x70 lib/rbtree.c:473
Read of size 8 at addr ffff888042d1af38 by task syz.0.0/5329
CPU: 0 UID: 0 PID: 5329 Comm: syz.0.0 Not tainted 6.12.0-rc7-syzkaller #0
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:94 [inline]
dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120
print_address_description mm/kasan/report.c:377 [inline]
print_report+0x169/0x550 mm/kasan/report.c:488
kasan_report+0x143/0x180 mm/kasan/report.c:601
rb_first+0x69/0x70 lib/rbtree.c:473
free_block_entry+0x78/0x230 fs/btrfs/ref-verify.c:248
btrfs_free_ref_cache+0xa3/0x100 fs/btrfs/ref-verify.c:917
btrfs_ref_tree_mod+0x139f/0x15e0 fs/btrfs/ref-verify.c:898
btrfs_free_extent+0x33c/0x380 fs/btrfs/extent-tree.c:3544
__btrfs_mod_ref+0x7dd/0xac0 fs/btrfs/extent-tree.c:2523
update_ref_for_cow+0x9cd/0x11f0 fs/btrfs/ctree.c:512
btrfs_force_cow_block+0x9f6/0x1da0 fs/btrfs/ctree.c:594
btrfs_cow_block+0x35e/0xa40 fs/btrfs/ctree.c:754
btrfs_search_slot+0xbdd/0x30d0 fs/btrfs/ctree.c:2116
btrfs_lookup_inode+0xdc/0x480 fs/btrfs/inode-item.c:411
__btrfs_update_delayed_inode+0x1e7/0xb90 fs/btrfs/delayed-inode.c:1030
btrfs_update_delayed_inode fs/btrfs/delayed-inode.c:1114 [inline]
__btrfs_commit_inode_delayed_items+0x2318/0x24a0 fs/btrfs/delayed-inode.c:1137
__btrfs_run_delayed_items+0x213/0x490 fs/btrfs/delayed-inode.c:1171
btrfs_commit_transaction+0x8a8/0x3740 fs/btrfs/transaction.c:2313
prepare_to_relocate+0x3c4/0x4c0 fs/btrfs/relocation.c:3586
relocate_block_group+0x16c/0xd40 fs/btrfs/relocation.c:3611
btrfs_relocate_block_group+0x77d/0xd90 fs/btrfs/relocation.c:4081
btrfs_relocate_chunk+0x12c/0x3b0 fs/btrfs/volumes.c:3377
__btrfs_balance+0x1b0f/0x26b0 fs/btrfs/volumes.c:4161
btrfs_balance+0xbdc/0x10c0 fs/btrfs/volumes.c:4538
btrfs_ioctl_balance+0x493/0x7c0 fs/btrfs/ioctl.c:3673
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:907 [inline]
__se_sys_ioctl+0xf9/0x170 fs/ioctl.c:893
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f996df7e719
RSP: 002b:00007f996ede7038 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00007f996e135f80 RCX: 00007f996df7e719
RDX: 0000000020000180 RSI: 00000000c4009420 RDI: 0000000000000004
RBP: 00007f996dff139e R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 0000000000000000 R14: 00007f996e135f80 R15: 00007fff79f32e68
</TASK>
Allocated by task 5329:
kasan_save_stack mm/kasan/common.c:47 [inline]
kasan_save_track+0x3f/0x80 mm/kasan/common.c:68
poison_kmalloc_redzone mm/kasan/common.c:377 [inline]
__kasan_kmalloc+0x98/0xb0 mm/kasan/common.c:394
kasan_kmalloc include/linux/kasan.h:257 [inline]
__kmalloc_cache_noprof+0x19c/0x2c0 mm/slub.c:4295
kmalloc_noprof include/linux/slab.h:878 [inline]
kzalloc_noprof include/linux/slab.h:1014 [inline]
btrfs_ref_tree_mod+0x264/0x15e0 fs/btrfs/ref-verify.c:701
btrfs_free_extent+0x33c/0x380 fs/btrfs/extent-tree.c:3544
__btrfs_mod_ref+0x7dd/0xac0 fs/btrfs/extent-tree.c:2523
update_ref_for_cow+0x9cd/0x11f0 fs/btrfs/ctree.c:512
btrfs_force_cow_block+0x9f6/0x1da0 fs/btrfs/ctree.c:594
btrfs_cow_block+0x35e/0xa40 fs/btrfs/ctree.c:754
btrfs_search_slot+0xbdd/0x30d0 fs/btrfs/ctree.c:2116
btrfs_lookup_inode+0xdc/0x480 fs/btrfs/inode-item.c:411
__btrfs_update_delayed_inode+0x1e7/0xb90 fs/btrfs/delayed-inode.c:1030
btrfs_update_delayed_inode fs/btrfs/delayed-inode.c:1114 [inline]
__btrfs_commit_inode_delayed_items+0x2318/0x24a0 fs/btrfs/delayed-inode.c:1137
__btrfs_run_delayed_items+0x213/0x490 fs/btrfs/delayed-inode.c:1171
btrfs_commit_transaction+0x8a8/0x3740 fs/btrfs/transaction.c:2313
prepare_to_relocate+0x3c4/0x4c0 fs/btrfs/relocation.c:3586
relocate_block_group+0x16c/0xd40 fs/btrfs/relocation.c:3611
btrfs_relocate_block_group+0x77d/0xd90 fs/btrfs/relocation.c:4081
btrfs_relocate_chunk+0x12c/0x3b0 fs/btrfs/volumes.c:3377
__btrfs_balance+0x1b0f/0x26b0 fs/btrfs/volumes.c:4161
btrfs_balance+0xbdc/0x10c0 fs/btrfs/volumes.c:4538
btrfs_ioctl_balance+0x493/0x7c0 fs/btrfs/ioctl.c:3673
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:907 [inline]
__se_sys_ioctl+0xf9/0x170 fs/ioctl.c:893
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Freed by task 5329:
kasan_save_stack mm/kasan/common.c:47 [inline]
kasan_save_track+0x3f/0x80 mm/kasan/common.c:68
kasan_save_free_info+0x40/0x50 mm/kasan/generic.c:579
poison_slab_object mm/kasan/common.c:247 [inline]
__kasan_slab_free+0x59/0x70 mm/kasan/common.c:264
kasan_slab_free include/linux/kasan.h:230 [inline]
slab_free_hook mm/slub.c:2342 [inline]
slab_free mm/slub.c:4579 [inline]
kfree+0x1a0/0x440 mm/slub.c:4727
btrfs_ref_tree_mod+0x136c/0x15e0
btrfs_free_extent+0x33c/0x380 fs/btrfs/extent-tree.c:3544
__btrfs_mod_ref+0x7dd/0xac0 fs/btrfs/extent-tree.c:2523
update_ref_for_cow+0x9cd/0x11f0 fs/btrfs/ctree.c:512
btrfs_force_cow_block+0x9f6/0x1da0 fs/btrfs/ctree.c:594
btrfs_cow_block+0x35e/0xa40 fs/btrfs/ctree.c:754
btrfs_search_slot+0xbdd/0x30d0 fs/btrfs/ctree.c:2116
btrfs_lookup_inode+0xdc/0x480 fs/btrfs/inode-item.c:411
__btrfs_update_delayed_inode+0x1e7/0xb90 fs/btrfs/delayed-inode.c:1030
btrfs_update_delayed_inode fs/btrfs/delayed-inode.c:1114 [inline]
__btrfs_commit_inode_delayed_items+0x2318/0x24a0 fs/btrfs/delayed-inode.c:1137
__btrfs_run_delayed_items+0x213/0x490 fs/btrfs/delayed-inode.c:1171
btrfs_commit_transaction+0x8a8/0x3740 fs/btrfs/transaction.c:2313
prepare_to_relocate+0x3c4/0x4c0 fs/btrfs/relocation.c:3586
relocate_block_group+0x16c/0xd40 fs/btrfs/relocation.c:3611
btrfs_relocate_block_group+0x77d/0xd90 fs/btrfs/relocation.c:4081
btrfs_relocate_chunk+0x12c/0x3b0 fs/btrfs/volumes.c:3377
__btrfs_balance+0x1b0f/0x26b0 fs/btrfs/volumes.c:4161
btrfs_balance+0xbdc/0x10c0 fs/btrfs/volumes.c:4538
btrfs_ioctl_balance+0x493/0x7c0 fs/btrfs/ioctl.c:3673
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:907 [inline]
__se_sys_ioctl+0xf9/0x170 fs/ioctl.c:893
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x77/0x7f
The buggy address belongs to the object at ffff888042d1af00
which belongs to the cache kmalloc-64 of size 64
The buggy address is located 56 bytes inside of
freed 64-byte region [ffff888042d1af00, ffff888042d1af40)
The buggy address belongs to the physical page:
page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x42d1a
anon flags: 0x4fff00000000000(node=1|zone=1|lastcpupid=0x7ff)
page_type: f5(slab)
raw: 04fff00000000000 ffff88801ac418c0 0000000000000000 dead000000000001
raw: 0000000000000000 0000000000200020 00000001f5000000 0000000000000000
page dumped because: kasan: bad access detected
page_owner tracks the page as allocated
page last allocated via order 0, migratetype Unmovable, gfp_mask 0x52c40(GFP_NOFS|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP), pid 5055, tgid 5055 (dhcpcd-run-hook), ts 40377240074, free_ts 40376848335
set_page_owner include/linux/page_owner.h:32 [inline]
post_alloc_hook+0x1f3/0x230 mm/page_alloc.c:1541
prep_new_page mm/page_alloc.c:1549 [inline]
get_page_from_freelist+0x3649/0x3790 mm/page_alloc.c:3459
__alloc_pages_noprof+0x292/0x710 mm/page_alloc.c:4735
alloc_pages_mpol_noprof+0x3e8/0x680 mm/mempolicy.c:2265
alloc_slab_page+0x6a/0x140 mm/slub.c:2412
allocate_slab+0x5a/0x2f0 mm/slub.c:2578
new_slab mm/slub.c:2631 [inline]
___slab_alloc+0xcd1/0x14b0 mm/slub.c:3818
__slab_alloc+0x58/0xa0 mm/slub.c:3908
__slab_alloc_node mm/slub.c:3961 [inline]
slab_alloc_node mm/slub.c:4122 [inline]
__do_kmalloc_node mm/slub.c:4263 [inline]
__kmalloc_noprof+0x25a/0x400 mm/slub.c:4276
kmalloc_noprof include/linux/slab.h:882 [inline]
kzalloc_noprof include/linux/slab.h:1014 [inline]
tomoyo_encode2 security/tomoyo/realpath.c:45 [inline]
tomoyo_encode+0x26f/0x540 security/tomoyo/realpath.c:80
tomoyo_realpath_from_path+0x59e/0x5e0 security/tomoyo/realpath.c:283
tomoyo_get_realpath security/tomoyo/file.c:151 [inline]
tomoyo_check_open_permission+0x255/0x500 security/tomoyo/file.c:771
security_file_open+0x777/0x990 security/security.c:3109
do_dentry_open+0x369/0x1460 fs/open.c:945
vfs_open+0x3e/0x330 fs/open.c:1088
do_open fs/namei.c:3774 [inline]
path_openat+0x2c84/0x3590 fs/namei.c:3933
page last free pid 5055 tgid 5055 stack trace:
reset_page_owner include/linux/page_owner.h:25 [inline]
free_pages_prepare mm/page_alloc.c:1112 [inline]
free_unref_page+0xcfb/0xf20 mm/page_alloc.c:2642
free_pipe_info+0x300/0x390 fs/pipe.c:860
put_pipe_info fs/pipe.c:719 [inline]
pipe_release+0x245/0x320 fs/pipe.c:742
__fput+0x23f/0x880 fs/file_table.c:431
__do_sys_close fs/open.c:1567 [inline]
__se_sys_close fs/open.c:1552 [inline]
__x64_sys_close+0x7f/0x110 fs/open.c:1552
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Memory state around the buggy address:
ffff888042d1ae00: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
ffff888042d1ae80: 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc fc
>ffff888042d1af00: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
^
ffff888042d1af80: 00 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc
ffff888042d1b000: 00 00 00 00 00 fc fc 00 00 00 00 00 fc fc 00 00--- fs/btrfs/ref-verify.c | 1 + 1 file changed, 1 insertion(+)
fs/btrfs/ref-verify.c +1 -0
@@ -846,6 +846,7 @@ int btrfs_ref_tree_mod(struct btrfs_fs_info *fs_info, "dropping a ref for a root that doesn't have a ref on the block");dump_block_entry (fs_info, be);dump_ref_action (fs_info, ra); +rb_erase (&ref->node, &be->refs);kfree (ref);kfree (ra); goto out_unlock;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 382/565 ad7780: fix division by zero in ad7780_write_raw()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zicheng Qu <[email protected]>
commit c174b53e95adf2eece2afc56cd9798374919f99a upstream.
In the ad7780_write_raw() , val2 can be zero, which might lead to a division by zero error in DIV_ROUND_CLOSEST(). The ad7780_write_raw() is based on iio_info's write_raw. While val is explicitly declared that can be zero (in read mode), val2 is not specified to be non-zero.
--- drivers/iio/adc/ad7780.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/adc/ad7780.c +1 -1
@@ -152,7 +152,7 @@ static int ad7780_write_raw(struct iio_dswitch (m) {case IIO_CHAN_INFO_SCALE : -if (val !=0 ) +if (val !=0 || val2 ==0 )return -EINVAL ; vref = st->int_vref_mv *1000000LL ;
Greg Kroah-Hartman
maintainerPATCH 383/565 s390/entry: Mark IRQ entries to fix stack depot warnings
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vasily Gorbik <[email protected]>
commit 45c9f2b856a075a34873d00788d2e8a250c1effd upstream.
The stack depot filters out everything outside of the top interrupt context as an uninteresting or irrelevant part of the stack traces. This helps with stack trace de-duplication, avoiding an explosion of saved stack traces that share the same IRQ context code path but originate from different randomly interrupted points, eventually exhausting the stack depot.
Filtering uses in_irqentry_text() to identify functions within the .irqentry.text and .softirqentry.text sections, which then become the last stack trace entries being saved.
While __do_softirq() is placed into the .softirqentry.text section by common code, populating .irqentry.text is architecture-specific.
Currently, the .irqentry.text section on s390 is empty, which prevents stack depot filtering and de-duplication and could result in warnings like:
Stack depot reached limit capacity
WARNING: CPU: 0 PID: 286113 at lib/stackdepot.c:252 depot_alloc_stack+0x39a/0x3c8
with PREEMPT and KASAN enabled.
Fix this by moving the IO/EXT interrupt handlers from .kprobes.text into the .irqentry.text section and updating the kprobes blacklist to include the .irqentry.text section.
This is done only for asynchronous interrupts and explicitly not for program checks, which are synchronous and where the context beyond the program check is important to preserve. Despite machine checks being somewhat in between, they are extremely rare, and preserving context when possible is also of value.
SVCs and Restart Interrupts are not relevant, one being always at the boundary to user space and the other being a one-time thing.
IRQ entries filtering is also optionally used in ftrace function graph, where the same logic applies.
--- arch/s390/kernel/entry.S | 4 ++++ arch/s390/kernel/kprobes.c | 6 ++++++ 2 files changed, 10 insertions(+)
arch/s390/kernel/entry.S +4 -0
@@ -474,9 +474,13 @@ ENTRY(\name) ENDPROC(\name) .endm + .section .irqentry.text, "ax" + INT_HANDLER ext_int_handler,__LC_EXT_OLD_PSW,do_ext_irq INT_HANDLER io_int_handler,__LC_IO_OLD_PSW,do_io_irq + .section .kprobes.text, "ax" + /* * Load idle PSW. */
arch/s390/kernel/kprobes.c +6 -0
@@ -518,6 +518,12 @@ int __init arch_init_kprobes(void)return register_kprobe (&trampoline); } +int __init arch_populate_kprobe_blacklist (void ) +{ +return kprobe_add_area_blacklist ((unsigned long )__irqentry_text_start, + (unsigned long )__irqentry_text_end); +} +int arch_trampoline_kprobe (struct kprobe *p) {return p->addr == (kprobe_opcode_t *) &kretprobe_trampoline;
Greg Kroah-Hartman
maintainerPATCH 384/565 util_macros.h: fix/rework find_closest() macros
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexandru Ardelean <[email protected]>
commit bc73b4186736341ab5cd2c199da82db6e1134e13 upstream.
A bug was found in the find_closest() (find_closest_descending() is also affected after some testing), where for certain values with small progressions, the rounding (done by averaging 2 values) causes an incorrect index to be returned. The rounding issues occur for progressions of 1, 2 and 3. It goes away when the progression/interval between two values is 4 or larger.
It's particularly bad for progressions of 1. For example if there's an array of 'a = { 1, 2, 3 }', using 'find_closest(2, a ...)' would return 0 (the index of '1'), rather than returning 1 (the index of '2'). This means that for exact values (with a progression of 1), find_closest() will misbehave and return the index of the value smaller than the one we're searching for.
For progressions of 2 and 3, the exact values are obtained correctly; but values aren't approximated correctly (as one would expect). Starting with progressions of 4, all seems to be good (one gets what one would expect).
While one could argue that 'find_closest()' should not be used for arrays with progressions of 1 (i.e. '{1, 2, 3, ...}', the macro should still behave correctly.
The bug was found while testing the 'drivers/iio/adc/ad7606.c', specifically the oversampling feature.
For reference, the oversampling values are listed as:
static const unsigned int ad7606_oversampling_avail[7] = {
1, 2, 4, 8, 16, 32, 64,};
When doing:
1. $ echo 1 > /sys/bus/iio/devices/iio\:device0/oversampling_ratio
$ cat /sys/bus/iio/devices/iio\:device0/oversampling_ratio
1 # this is fine
2. $ echo 2 > /sys/bus/iio/devices/iio\:device0/oversampling_ratio
$ cat /sys/bus/iio/devices/iio\:device0/oversampling_ratio
1 # this is wrong; 2 should be returned here
3. $ echo 3 > /sys/bus/iio/devices/iio\:device0/oversampling_ratio
$ cat /sys/bus/iio/devices/iio\:device0/oversampling_ratio
2 # this is fine
4. $ echo 4 > /sys/bus/iio/devices/iio\:device0/oversampling_ratio
$ cat /sys/bus/iio/devices/iio\:device0/oversampling_ratio
4 # this is fine
And from here-on, the values are as correct (one gets what one would
expect.)While writing a kunit test for this bug, a peculiar issue was found for the array in the 'drivers/hwmon/ina2xx.c' & 'drivers/iio/adc/ina2xx-adc.c' drivers. While running the kunit test (for 'ina226_avg_tab' from these drivers):
* idx = find_closest([-1 to 2], ina226_avg_tab, ARRAY_SIZE(ina226_avg_tab));
This returns idx == 0, so value. * idx = find_closest(3, ina226_avg_tab, ARRAY_SIZE(ina226_avg_tab)); This returns idx == 0, value 1; and now one could argue whether 3 is closer to 4 or to 1. This quirk only appears for value '3' in this array, but it seems to be a another rounding issue.
* And from 4 onwards the 'find_closest'() works fine (one gets what one would expect).
This change reworks the find_closest() macros to also check the difference between the left and right elements when 'x'. If the distance to the right is smaller (than the distance to the left), the index is incremented by 1. This also makes redundant the need for using the DIV_ROUND_CLOSEST() macro.
In order to accommodate for any mix of negative + positive values, the internal variables '__fc_x', '__fc_mid_x', '__fc_left' & '__fc_right' are forced to 'long' type. This also addresses any potential bugs/issues with 'x' being of an unsigned type. In those situations any comparison between signed & unsigned would be promoted to a comparison between 2 unsigned numbers; this is especially annoying when '__fc_left' & '__fc_right' underflow.
The find_closest_descending() macro was also reworked and duplicated from the find_closest(), and it is being iterated in reverse. The main reason for this is to get the same indices as 'find_closest()' (but in reverse). The comparison for '__fc_right < __fc_left' favors going the array in ascending order.
For example for array '{ 1024, 512, 256, 128, 64, 16, 4, 1 }' and x = 3, we get:
__fc_mid_x = 2
__fc_left = -1
__fc_right = -2
Then '__fc_right < __fc_left' evaluates to true and '__fc_i++' becomes 7
which is not quite incorrect, but 3 is closer to 4 than to 1.This change has been validated with the kunit from the next patch.
--- include/linux/util_macros.h | 56 +++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 16 deletions(-)
include/linux/util_macros.h +40 -16
@@ -2,19 +2,6 @@#ifndef _LINUX_HELPER_MACROS_H_#define _LINUX_HELPER_MACROS_H_ -#define __find_closest (x, a, as, op) \ -({ \ - typeof(as) __fc_i, __fc_as = (as) - 1; \ - typeof(x) __fc_x = (x); \ - typeof(*a) const *__fc_a = (a); \ - for (__fc_i = 0; __fc_i < __fc_as; __fc_i++) { \ - if (__fc_x op DIV_ROUND_CLOSEST(__fc_a[__fc_i] + \ - __fc_a[__fc_i + 1], 2)) \ - break; \ - } \ - (__fc_i); \ -}) -/** * find_closest - locate the closest element in a sorted array * @x: The reference value.
@@ -23,8 +10,27 @@* @as: Size of 'a'. * * Returns the index of the element closest to 'x'. +* Note: If using an array of negative numbers (or mixed positive numbers), +* then be sure that 'x' is of a signed-type to get good results. */ -#define find_closest (x, a, as) __find_closest(x, a, as, <=) +#define find_closest (x, a, as) \ +({ \ + typeof(as) __fc_i, __fc_as = (as) - 1; \ + long __fc_mid_x, __fc_x = (x); \ + long __fc_left, __fc_right; \ + typeof(*a) const *__fc_a = (a); \ + for (__fc_i = 0; __fc_i < __fc_as; __fc_i++) { \ + __fc_mid_x = (__fc_a[__fc_i] + __fc_a[__fc_i + 1]) / 2; \ + if (__fc_x <= __fc_mid_x) { \ + __fc_left = __fc_x - __fc_a[__fc_i]; \ + __fc_right = __fc_a[__fc_i + 1] - __fc_x; \ + if (__fc_right < __fc_left) \ + __fc_i++; \ + break; \ + } \ + } \ + (__fc_i); \ +})/** * find_closest_descending - locate the closest element in a sorted array
@@ -34,9 +40,27 @@* @as: Size of 'a'. * * Similar to find_closest() but 'a' is expected to be sorted in descending -* order. +* order. The iteration is done in reverse order, so that the comparison +* of '__fc_right' & '__fc_left' also works for unsigned numbers. */ -#define find_closest_descending (x, a, as) __find_closest(x, a, as, >=) +#define find_closest_descending (x, a, as) \ +({ \ + typeof(as) __fc_i, __fc_as = (as) - 1; \ + long __fc_mid_x, __fc_x = (x); \ + long __fc_left, __fc_right; \ + typeof(*a) const *__fc_a = (a); \ + for (__fc_i = __fc_as; __fc_i >= 1; __fc_i--) { \ + __fc_mid_x = (__fc_a[__fc_i] + __fc_a[__fc_i - 1]) / 2; \ + if (__fc_x <= __fc_mid_x) { \ + __fc_left = __fc_x - __fc_a[__fc_i]; \ + __fc_right = __fc_a[__fc_i - 1] - __fc_x; \ + if (__fc_right < __fc_left) \ + __fc_i--; \ + break; \ + } \ + } \ + (__fc_i); \ +})/** * is_insidevar - check if the @ptr points inside the @var memory range.
Greg Kroah-Hartman
maintainerPATCH 385/565 scsi: ufs: exynos: Fix hibern8 notify callbacks
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Griffin <[email protected]>
commit ceef938bbf8b93ba3a218b4adc244cde94b582aa upstream.
v1 of the patch which introduced the ufshcd_vops_hibern8_notify() callback used a bool instead of an enum. In v2 this was updated to an enum based on the review feedback in [1].
ufs-exynos hibernate calls have always been broken upstream as it follows the v1 bool implementation.
--- drivers/scsi/ufs/ufs-exynos.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/scsi/ufs/ufs-exynos.c +8 -8
@@ -1038,12 +1038,12 @@ static void exynos_ufs_dev_hw_reset(struhci_writel (ufs,1 <<0 ,HCI_GPIO_OUT ); } -static void exynos_ufs_pre_hibern8 (struct ufs_hba *hba,u8 enter) +static void exynos_ufs_pre_hibern8 (struct ufs_hba *hba,enum uic_cmd_dme cmd) {struct exynos_ufs *ufs =ufshcd_get_variant (hba);struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr; -if (!enter) { +if (cmd ==UIC_CMD_DME_HIBER_EXIT ) {if (ufs->opts &EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL )exynos_ufs_disable_auto_ctrl_hcc (ufs);exynos_ufs_ungate_clks (ufs);
@@ -1071,11 +1071,11 @@ static void exynos_ufs_pre_hibern8(struc } } -static void exynos_ufs_post_hibern8 (struct ufs_hba *hba,u8 enter) +static void exynos_ufs_post_hibern8 (struct ufs_hba *hba,enum uic_cmd_dme cmd) {struct exynos_ufs *ufs =ufshcd_get_variant (hba); -if (!enter) { +if (cmd ==UIC_CMD_DME_HIBER_EXIT ) {u32 cur_mode =0 ;u32 pwrmode;
@@ -1094,7 +1094,7 @@ static void exynos_ufs_post_hibern8(struif (!(ufs->opts &EXYNOS_UFS_OPT_SKIP_CONNECTION_ESTAB ))exynos_ufs_establish_connt (ufs); - }else { + }else if (cmd ==UIC_CMD_DME_HIBER_ENTER ) { ufs->entry_hibern8_t =ktime_get ();exynos_ufs_gate_clks (ufs);if (ufs->opts &EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL )
@@ -1163,15 +1163,15 @@ static int exynos_ufs_pwr_change_notify( }static void exynos_ufs_hibern8_notify (struct ufs_hba *hba, -enum uic_cmd_dme enter, +enum uic_cmd_dme cmd,enum ufs_notify_change_status notify) {switch ((u8 )notify) {case PRE_CHANGE : -exynos_ufs_pre_hibern8 (hba, enter); +exynos_ufs_pre_hibern8 (hba, cmd);break ;case POST_CHANGE : -exynos_ufs_post_hibern8 (hba, enter); +exynos_ufs_post_hibern8 (hba, cmd);break ; } }
Greg Kroah-Hartman
maintainerPATCH 386/565 i3c: master: Fix miss free init_dyn_addr at i3c_master_put_i3c_addrs()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Li <[email protected]>
commit 3082990592f7c6d7510a9133afa46e31bbe26533 upstream.
if (dev->boardinfo && dev->boardinfo->init_dyn_addr)
^^^ here check "init_dyn_addr" i3c_bus_set_addr_slot_status(&master->bus, dev->info.dyn_addr, ...) ^^^^ free "dyn_addr"
Fix copy/paste error "dyn_addr" by replacing it with "init_dyn_addr".
--- drivers/i3c/master.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/i3c/master.c +1 -1
@@ -1282,7 +1282,7 @@ static void i3c_master_put_i3c_addrs(str I3C_ADDR_SLOT_FREE);if (dev->boardinfo && dev->boardinfo->init_dyn_addr) -i3c_bus_set_addr_slot_status (&master->bus, dev->info.dyn_addr, +i3c_bus_set_addr_slot_status (&master->bus, dev->boardinfo->init_dyn_addr,I3C_ADDR_SLOT_FREE ); }
Greg Kroah-Hartman
maintainerPATCH 387/565 PCI: keystone: Add link up check to ks_pcie_other_map_bus()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kishon Vijay Abraham I <[email protected]>
commit 9e9ec8d8692a6f64d81ef67d4fb6255af6be684b upstream.
K2G forwards the error triggered by a link-down state (e.g., no connected endpoint device) on the system bus for PCI configuration transactions; these errors are reported as an SError at system level, which is fatal and hangs the system.
So, apply fix similar to how it was done in the DesignWare Core driver commit 15b23906347c ("PCI: dwc: Add link up check in dw_child_pcie_ops.map_bus()").
--- drivers/pci/controller/dwc/pci-keystone.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/pci/controller/dwc/pci-keystone.c +11 -0
@@ -440,6 +440,17 @@ static void __iomem *ks_pcie_other_map_bstruct keystone_pcie *ks_pcie =to_keystone_pcie (pci);u32 reg; +/* +* Checking whether the link is up here is a last line of defense +* against platforms that forward errors on the system bus as +* SError upon PCI configuration transactions issued when the link +* is down. This check is racy by definition and does not stop +* the system from triggering an SError if the link goes down +* after this check is performed. +*/ +if (!dw_pcie_link_up (pci)) +return NULL ; + reg =CFG_BUS (bus->number) |CFG_DEVICE (PCI_SLOT (devfn)) |CFG_FUNC (PCI_FUNC (devfn));if (!pci_is_root_bus (bus->parent))
Greg Kroah-Hartman
maintainerPATCH 388/565 ovl: properly handle large files in ovl_security_fileattr
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleksandr Tymoshenko <[email protected]>
commit 3b6b99ef15ea37635604992ede9ebcccef38a239 upstream.
dentry_open in ovl_security_fileattr fails for any file larger than 2GB if open method of the underlying filesystem calls generic_file_open (e.g. fusefs).
The issue can be reproduce using the following script:
(passthrough_ll is an example app from libfuse).
$ D=/opt/test/mnt
$ mkdir -p ${D}/{source,base,top/uppr,top/work,ovlfs}
$ dd if=/dev/zero of=${D}/source/zero.bin bs=1G count=2
$ passthrough_ll -o source=${D}/source ${D}/base
$ mount -t overlay overlay \
-olowerdir=${D}/base,upperdir=${D}/top/uppr,workdir=${D}/top/work \
${D}/ovlfs
$ chmod 0777 ${D}/mnt/ovlfs/zero.binRunning this script results in "Value too large for defined data type" error message from chmod.
--- fs/overlayfs/inode.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
fs/overlayfs/inode.c +6 -1
@@ -519,8 +519,13 @@ static int ovl_security_fileattr(structstruct file *file;unsigned int cmd;int err; +unsigned int flags; - file =dentry_open (realpath,O_RDONLY ,current_cred ()); + flags =O_RDONLY ; +if (force_o_largefile ()) + flags |=O_LARGEFILE ; + + file =dentry_open (realpath, flags,current_cred ());if (IS_ERR (file))return PTR_ERR (file);
Greg Kroah-Hartman
maintainerPATCH 389/565 dm thin: Add missing destroy_work_on_stack()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuan Can <[email protected]>
commit e74fa2447bf9ed03d085b6d91f0256cc1b53f1a8 upstream.
This commit add missed destroy_work_on_stack() operations for pw->worker in pool_work_wait().
--- drivers/md/dm-thin.c | 1 + 1 file changed, 1 insertion(+)
drivers/md/dm-thin.c +1 -0
@@ -2468,6 +2468,7 @@ static void pool_work_wait(struct pool_winit_completion (&pw->complete);queue_work (pool->wq, &pw->worker);wait_for_completion (&pw->complete); +destroy_work_on_stack (&pw->worker); }/*----------------------------------------------------------------*/
Greg Kroah-Hartman
maintainerPATCH 390/565 PCI: rockchip-ep: Fix address translation unit programming
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Damien Le Moal <[email protected]>
commit 64f093c4d99d797b68b407a9d8767aadc3e3ea7a upstream.
The Rockchip PCIe endpoint controller handles PCIe transfers addresses by masking the lower bits of the programmed PCI address and using the same number of lower bits masked from the CPU address space used for the mapping. For a PCI mapping of <size> bytes starting from <pci_addr>, the number of bits masked is the number of address bits changing in the address range [pci_addr..pci_addr + size - 1].
However, rockchip_pcie_prog_ep_ob_atu() calculates num_pass_bits only using the size of the mapping, resulting in an incorrect number of mask bits depending on the value of the PCI address to map.
Fix this by introducing the helper function rockchip_pcie_ep_ob_atu_num_bits() to correctly calculate the number of mask bits to use to program the address translation unit. The number of mask bits is calculated depending on both the PCI address and size of the mapping, and clamped between 8 and 20 using the macros ROCKCHIP_PCIE_AT_MIN_NUM_BITS and ROCKCHIP_PCIE_AT_MAX_NUM_BITS. As defined in the Rockchip RK3399 TRM V1.3 Part2, Sections 17.5.5.1.1 and 17.6.8.2.1, this clamping is necessary because:
1) The lower 8 bits of the PCI address to be mapped by the outbound region are ignored. So a minimum of 8 address bits are needed and imply that the PCI address must be aligned to 256.
2) The outbound memory regions are 1MB in size. So while we can specify up to 63-bits for the PCI address (num_bits filed uses bits 0 to 5 of the outbound address region 0 register), we must limit the number of valid address bits to 20 to match the memory window maximum size (1 << 20 = 1MB).
--- drivers/pci/controller/pcie-rockchip-ep.c | 16 +++++++++++++--- drivers/pci/controller/pcie-rockchip.h | 4 ++++ 2 files changed, 17 insertions(+), 3 deletions(-)
drivers/pci/controller/pcie-rockchip-ep.c +13 -3
@@ -63,15 +63,25 @@ static void rockchip_pcie_clear_ep_ob_at ROCKCHIP_PCIE_AT_OB_REGION_DESC1(region)); } +static int rockchip_pcie_ep_ob_atu_num_bits (struct rockchip_pcie *rockchip, +u64 pci_addr,size_t size) +{ +int num_pass_bits =fls64 (pci_addr ^ (pci_addr + size -1 )); + +return clamp (num_pass_bits, +ROCKCHIP_PCIE_AT_MIN_NUM_BITS , +ROCKCHIP_PCIE_AT_MAX_NUM_BITS ); +} +static void rockchip_pcie_prog_ep_ob_atu (struct rockchip_pcie *rockchip,u8 fn,u32 r,u64 cpu_addr,u64 pci_addr,size_t size) { -int num_pass_bits =fls64 (size -1 ); +int num_pass_bits;u32 addr0, addr1, desc0; -if (num_pass_bits <8 ) - num_pass_bits =8 ; + num_pass_bits =rockchip_pcie_ep_ob_atu_num_bits (rockchip, + pci_addr, size); addr0 = ((num_pass_bits -1 ) &PCIE_CORE_OB_REGION_ADDR0_NUM_BITS ) | (lower_32_bits (pci_addr) &PCIE_CORE_OB_REGION_ADDR0_LO_ADDR );
drivers/pci/controller/pcie-rockchip.h +4 -0
@@ -246,6 +246,10 @@ (PCIE_EP_PF_CONFIG_REGS_BASE + (((fn) << 12) & GENMASK(19, 12)))#define ROCKCHIP_PCIE_EP_VIRT_FUNC_BASE (fn) \ (PCIE_EP_PF_CONFIG_REGS_BASE + 0x10000 + (((fn) << 12) & GENMASK(19, 12))) + +#define ROCKCHIP_PCIE_AT_MIN_NUM_BITS 8 +#define ROCKCHIP_PCIE_AT_MAX_NUM_BITS 20 +#define ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR0 (fn, bar) \ (PCIE_CORE_AXI_CONF_BASE + 0x0828 + (fn) * 0x0040 + (bar) * 0x0008)#define ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR1 (fn, bar) \
Greg Kroah-Hartman
maintainerPATCH 391/565 nfsd: make sure exp active before svc_export_show
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Erkun <[email protected]>
commit be8f982c369c965faffa198b46060f8853e0f1f0 upstream.
The function e_show was called with protection from RCU. This only ensures that exp will not be freed. Therefore, the reference count for exp can drop to zero, which will trigger a refcount use-after-free warning when exp_get is called. To resolve this issue, use cache_get_rcu to ensure that exp remains active.
------------[ cut here ]------------ refcount_t: addition on 0; use-after-free. WARNING: CPU: 3 PID: 819 at lib/refcount.c:25 refcount_warn_saturate+0xb1/0x120 CPU: 3 UID: 0 PID: 819 Comm: cat Not tainted 6.12.0-rc3+ #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.1-2.fc37 04/01/2014 RIP: 0010:refcount_warn_saturate+0xb1/0x120 ... Call Trace: <TASK> e_show+0x20b/0x230 [nfsd] seq_read_iter+0x589/0x770 seq_read+0x1e5/0x270 vfs_read+0x125/0x530 ksys_read+0xc1/0x160 do_syscall_64+0x5f/0x170 entry_SYSCALL_64_after_hwframe+0x76/0x7e
--- fs/nfsd/export.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
fs/nfsd/export.c +4 -1
@@ -1324,9 +1324,12 @@ static int e_show(struct seq_file *m, voreturn 0 ; } -exp_get (exp); +if (!cache_get_rcu (&exp->h)) +return 0 ; +if (cache_check (cd, &exp->h,NULL ))return 0 ; +exp_put (exp);return svc_export_show (m, cd, cp); }
Greg Kroah-Hartman
maintainerPATCH 392/565 nfsd: fix nfs4_openowner leak when concurrent nfsd4_open occur
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Erkun <[email protected]>
commit 98100e88dd8865999dc6379a3356cd799795fe7b upstream.
The action force umount(umount -f) will attempt to kill all rpc_task even umount operation may ultimately fail if some files remain open. Consequently, if an action attempts to open a file, it can potentially send two rpc_task to nfs server.
NFS CLIENT
thread1 thread2open("file")
...nfs4_do_open
_nfs4_do_open
_nfs4_open_and_get_state
_nfs4_proc_open
nfs4_run_open_task
/* rpc_task1 */
rpc_run_task
rpc_wait_for_completion_task
umount -f
nfs_umount_begin
rpc_killall_tasks
rpc_signal_task
rpc_task1 been wakeup
and return -512
_nfs4_do_open // while loop
...
nfs4_run_open_task
/* rpc_task2 */
rpc_run_task
rpc_wait_for_completion_taskWhile processing an open request, nfsd will first attempt to find or allocate an nfs4_openowner. If it finds an nfs4_openowner that is not marked as NFS4_OO_CONFIRMED, this nfs4_openowner will released. Since two rpc_task can attempt to open the same file simultaneously from the client to server, and because two instances of nfsd can run concurrently, this situation can lead to lots of memory leak. Additionally, when we echo 0 to /proc/fs/nfsd/threads, warning will be triggered.
NFS SERVER
nfsd1 nfsd2 echo 0 > /proc/fs/nfsd/threads
nfsd4_open
nfsd4_process_open1
find_or_alloc_open_stateowner
// alloc oo1, stateid1
nfsd4_open
nfsd4_process_open1
find_or_alloc_open_stateowner
// find oo1, without NFS4_OO_CONFIRMED
release_openowner
unhash_openowner_locked
list_del_init(&oo->oo_perclient)
// cannot find this oo
// from client, LEAK!!!
alloc_stateowner // alloc oo2 nfsd4_process_open2
init_open_stateid
// associate oo1
// with stateid1, stateid1 LEAK!!!
nfs4_get_vfs_file
// alloc nfsd_file1 and nfsd_file_mark1
// all LEAK!!!
nfsd4_process_open2
...
write_threads
...
nfsd_destroy_serv
nfsd_shutdown_net
nfs4_state_shutdown_net
nfs4_state_destroy_net
destroy_client
__destroy_client
// won't find oo1!!!
nfsd_shutdown_generic
nfsd_file_cache_shutdown
kmem_cache_destroy
for nfsd_file_slab
and nfsd_file_mark_slab
// bark since nfsd_file1
// and nfsd_file_mark1
// still alive=======================================================================
BUG nfsd_file (Not tainted): Objects remaining in nfsd_file on __kmem_cache_shutdown()
-----------------------------------------------------------------------
Slab 0xffd4000004438a80 objects=34 used=1 fp=0xff11000110e2ad28 flags=0x17ffffc0000240(workingset|head|node=0|zone=2|lastcpupid=0x1fffff)
CPU: 4 UID: 0 PID: 757 Comm: sh Not tainted 6.12.0-rc6+ #19 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.1-2.fc37 04/01/2014 Call Trace: <TASK> dump_stack_lvl+0x53/0x70 slab_err+0xb0/0xf0 __kmem_cache_shutdown+0x15c/0x310 kmem_cache_destroy+0x66/0x160 nfsd_file_cache_shutdown+0xac/0x210 [nfsd] nfsd_destroy_serv+0x251/0x2a0 [nfsd] nfsd_svc+0x125/0x1e0 [nfsd] write_threads+0x16a/0x2a0 [nfsd] nfsctl_transaction_write+0x74/0xa0 [nfsd] vfs_write+0x1ae/0x6d0 ksys_write+0xc1/0x160 do_syscall_64+0x5f/0x170 entry_SYSCALL_64_after_hwframe+0x76/0x7e
Disabling lock debugging due to kernel taint
Object 0xff11000110e2ac38 @offset=3128
Allocated in nfsd_file_do_acquire+0x20f/0xa30 [nfsd] age=1635 cpu=3 pid=800
nfsd_file_do_acquire+0x20f/0xa30 [nfsd] nfsd_file_acquire_opened+0x5f/0x90 [nfsd] nfs4_get_vfs_file+0x4c9/0x570 [nfsd] nfsd4_process_open2+0x713/0x1070 [nfsd] nfsd4_open+0x74b/0x8b0 [nfsd] nfsd4_proc_compound+0x70b/0xc20 [nfsd] nfsd_dispatch+0x1b4/0x3a0 [nfsd] svc_process_common+0x5b8/0xc50 [sunrpc] svc_process+0x2ab/0x3b0 [sunrpc] svc_handle_xprt+0x681/0xa20 [sunrpc] nfsd+0x183/0x220 [nfsd] kthread+0x199/0x1e0 ret_from_fork+0x31/0x60 ret_from_fork_asm+0x1a/0x30
Add nfs4_openowner_unhashed to help found unhashed nfs4_openowner, and break nfsd4_open process to fix this problem.
--- fs/nfsd/nfs4state.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
fs/nfsd/nfs4state.c +19 -0
@@ -1628,6 +1628,14 @@ static void release_open_stateid(structfree_ol_stateid_reaplist (&reaplist); } +static bool nfs4_openowner_unhashed (struct nfs4_openowner *oo) +{ +lockdep_assert_held (&oo->oo_owner.so_client->cl_lock); + +return list_empty (&oo->oo_owner.so_strhash) && +list_empty (&oo->oo_perclient); +} +static void unhash_openowner_locked (struct nfs4_openowner *oo) {struct nfs4_client *clp = oo->oo_owner.so_client;
@@ -4638,6 +4646,12 @@ retry:spin_lock (&oo->oo_owner.so_client->cl_lock);spin_lock (&fp->fi_lock); +if (nfs4_openowner_unhashed (oo)) { +mutex_unlock (&stp->st_mutex); + stp =NULL ; + goto out_unlock; + } + retstp =nfsd4_find_existing_open (fp, open);if (retstp) goto out_unlock;
@@ -5712,6 +5726,11 @@ nfsd4_process_open2(struct svc_rqst *rqsif (!stp) { stp =init_open_stateid (fp, open); +if (!stp) { + status = nfserr_jukebox; + goto out; + } +if (!open->op_stp) new_stp = true; }
Greg Kroah-Hartman
maintainerPATCH 393/565 btrfs: dont BUG_ON on ENOMEM from btrfs_lookup_extent_info() in walk_down_proc()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
commit a580fb2c3479d993556e1c31b237c9e5be4944a3 upstream.
We handle errors here properly, ENOMEM isn't fatal, return the error.
--- fs/btrfs/extent-tree.c | 1 - 1 file changed, 1 deletion(-)
fs/btrfs/extent-tree.c +0 -1
@@ -5099,7 +5099,6 @@ static noinline int walk_down_proc(struc eb->start, level,1 , &wc->refs[level], &wc->flags[level]); -BUG_ON (ret == -ENOMEM );if (ret)return ret;if (unlikely (wc->refs[level] ==0 )) {
Greg Kroah-Hartman
maintainerPATCH 394/565 drm/sti: avoid potential dereference of error pointers in sti_hqvdp_atomic_check
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Ke <[email protected]>
commit c1ab40a1fdfee732c7e6ff2fb8253760293e47e8 upstream.
The return value of drm_atomic_get_crtc_state() needs to be checked. To avoid use of error pointer 'crtc_state' in case of the failure.
--- drivers/gpu/drm/sti/sti_hqvdp.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/sti/sti_hqvdp.c +3 -0
@@ -1035,6 +1035,9 @@ static int sti_hqvdp_atomic_check(structreturn 0 ; crtc_state =drm_atomic_get_crtc_state (state, crtc); +if (IS_ERR (crtc_state)) +return PTR_ERR (crtc_state); + mode = &crtc_state->mode; dst_x = new_plane_state->crtc_x; dst_y = new_plane_state->crtc_y;
Greg Kroah-Hartman
maintainerPATCH 395/565 drm/sti: avoid potential dereference of error pointers in sti_gdp_atomic_check
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Ke <[email protected]>
commit e965e771b069421c233d674c3c8cd8c7f7245f42 upstream.
The return value of drm_atomic_get_crtc_state() needs to be checked. To avoid use of error pointer 'crtc_state' in case of the failure.
--- drivers/gpu/drm/sti/sti_gdp.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/sti/sti_gdp.c +3 -0
@@ -636,6 +636,9 @@ static int sti_gdp_atomic_check(struct d mixer =to_sti_mixer (crtc); crtc_state =drm_atomic_get_crtc_state (state, crtc); +if (IS_ERR (crtc_state)) +return PTR_ERR (crtc_state); + mode = &crtc_state->mode; dst_x = new_plane_state->crtc_x; dst_y = new_plane_state->crtc_y;
Greg Kroah-Hartman
maintainerPATCH 396/565 drm/sti: avoid potential dereference of error pointers
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Ke <[email protected]>
commit 831214f77037de02afc287eae93ce97f218d8c04 upstream.
The return value of drm_atomic_get_crtc_state() needs to be checked. To avoid use of error pointer 'crtc_state' in case of the failure.
--- drivers/gpu/drm/sti/sti_cursor.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/sti/sti_cursor.c +3 -0
@@ -199,6 +199,9 @@ static int sti_cursor_atomic_check(strucreturn 0 ; crtc_state =drm_atomic_get_crtc_state (state, crtc); +if (IS_ERR (crtc_state)) +return PTR_ERR (crtc_state); + mode = &crtc_state->mode; dst_x = new_plane_state->crtc_x; dst_y = new_plane_state->crtc_y;
Greg Kroah-Hartman
maintainerPATCH 397/565 drm/etnaviv: flush shader L1 cache after user commandstream
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lucas Stach <[email protected]>
commit 4f8dbadef085ab447a01a8d4806a3f629fea05ed upstream.
The shader L1 cache is a writeback cache for shader loads/stores and thus must be flushed before any BOs backing the shader buffers are potentially freed.
--- drivers/gpu/drm/etnaviv/etnaviv_buffer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/etnaviv/etnaviv_buffer.c +2 -1
@@ -481,7 +481,8 @@ void etnaviv_buffer_queue(struct etnaviv }else {CMD_LOAD_STATE (buffer,VIVS_GL_FLUSH_CACHE ,VIVS_GL_FLUSH_CACHE_DEPTH | -VIVS_GL_FLUSH_CACHE_COLOR ); +VIVS_GL_FLUSH_CACHE_COLOR | +VIVS_GL_FLUSH_CACHE_SHADER_L1 );if (has_blt) {CMD_LOAD_STATE (buffer,VIVS_BLT_ENABLE ,0x1 );CMD_LOAD_STATE (buffer,VIVS_BLT_SET_COMMAND ,0x1 );
Greg Kroah-Hartman
maintainerPATCH 398/565 iTCO_wdt: mask NMI_NOW bit for update_no_reboot_bit() call
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleksandr Ocheretnyi <[email protected]>
[ Upstream commit daa814d784ac034c62ab3fb0ef83daeafef527e2 ]
Commit da23b6faa8bf ("watchdog: iTCO: Add support for Cannon Lake PCH iTCO") does not mask NMI_NOW bit during TCO1_CNT register's value comparison for update_no_reboot_bit() call causing following failure:
...
iTCO_vendor_support: vendor-support=0
iTCO_wdt iTCO_wdt: unable to reset NO_REBOOT flag, device
disabled by hardware/BIOS
...
and this can lead to unexpected NMIs later during regular crashkernel's workflow because of watchdog probe call failures.
This change masks NMI_NOW bit for TCO1_CNT register values to avoid unexpected NMI_NOW bit inversions.
--- drivers/watchdog/iTCO_wdt.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-)
drivers/watchdog/iTCO_wdt.c +19 -2
@@ -82,6 +82,13 @@#define TCO2_CNT (p) (TCOBASE(p) + 0x0a)/* TCO2 Control Register */ #define TCOv2_TMR (p) (TCOBASE(p) + 0x12)/* TCOv2 Timer Initial Value*/ +/* +* NMI_NOW is bit 8 of TCO1_CNT register +* Read/Write +* This bit is implemented as RW but has no effect on HW. +*/ +#define NMI_NOW BIT(8) +/* internal variables */ struct iTCO_wdt_private {struct watchdog_device wddev;
@@ -220,13 +227,23 @@ static int update_no_reboot_bit_cnt(void *priv, bool set)struct iTCO_wdt_private *p = priv;u16 val, newval; - val =inw (TCO1_CNT (p)); +/* +* writing back 1b1 to NMI_NOW of TCO1_CNT register +* causes NMI_NOW bit inversion what consequently does +* not allow to perform the register's value comparison +* properly. +* +* NMI_NOW bit masking for TCO1_CNT register values +* helps to avoid possible NMI_NOW bit inversions on +* following write operation. +*/ + val =inw (TCO1_CNT (p)) & ~NMI_NOW ;if (set) val |=BIT (0 );else val &= ~BIT (0 );outw (val,TCO1_CNT (p)); - newval =inw (TCO1_CNT (p)); + newval =inw (TCO1_CNT (p)) & ~NMI_NOW ;/* make sure the update is successful */ return val != newval ? -EIO :0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 399/565 watchdog: mediatek: Make sure system reset gets asserted in mtk_wdt_restart()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yassine Oudjana <[email protected]>
[ Upstream commit a1495a21e0b8aad92132dfcf9c6fffc1bde9d5b2 ]
Clear the IRQ enable bit of WDT_MODE before asserting software reset in order to make TOPRGU issue a system reset signal instead of an IRQ.
--- drivers/watchdog/mtk_wdt.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/watchdog/mtk_wdt.c +6 -0
@@ -164,9 +164,15 @@ static int mtk_wdt_restart(struct watchdog_device *wdt_dev, {struct mtk_wdt_dev *mtk_wdt =watchdog_get_drvdata (wdt_dev);void __iomem *wdt_base; +u32 reg; wdt_base = mtk_wdt->wdt_base; +/* Enable reset in order to issue a system reset instead of an IRQ */ + reg =readl (wdt_base +WDT_MODE ); + reg &= ~WDT_MODE_IRQ_EN ; +writel (reg |WDT_MODE_KEY , wdt_base +WDT_MODE ); +while (1 ) {writel (WDT_SWRST_KEY , wdt_base +WDT_SWRST );mdelay (5 );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 400/565 can: peak_usb: CANFD: store 64-bits hw timestamps
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stephane Grosjean <[email protected]>
[ Upstream commit 28e0a70cede3fa6835e36302207776831cc41b8b ]
This patch allows to use the whole 64-bit timestamps received from the CAN-FD device (expressed in µs) rather than only its low part, in the hwtstamp structure of the skb transferred to the network layer, when a CAN/CANFD frame has been received.
Stable-dep-of: 9e66242504f4 ("can: c_can: c_can_handle_bus_err(): update statistics if skb allocation fails")
--- drivers/net/can/usb/peak_usb/pcan_usb_core.c | 13 +++++++++++++ drivers/net/can/usb/peak_usb/pcan_usb_core.h | 1 + drivers/net/can/usb/peak_usb/pcan_usb_fd.c | 9 ++++++--- 3 files changed, 20 insertions(+), 3 deletions(-)
drivers/net/can/usb/peak_usb/pcan_usb_core.c +13 -0
@@ -205,6 +205,19 @@ int peak_usb_netif_rx(struct sk_buff *skb,return netif_rx (skb); } +/* post received skb with native 64-bit hw timestamp */ +int peak_usb_netif_rx_64 (struct sk_buff *skb,u32 ts_low,u32 ts_high) +{ +struct skb_shared_hwtstamps *hwts =skb_hwtstamps (skb); +u64 ns_ts; + + ns_ts = (u64 )ts_high <<32 | ts_low; + ns_ts *=NSEC_PER_USEC ; + hwts->hwtstamp =ns_to_ktime (ns_ts); + +return netif_rx (skb); +} +/* * callback for bulk Rx urb */
drivers/net/can/usb/peak_usb/pcan_usb_core.h +1 -0
@@ -143,6 +143,7 @@ void peak_usb_set_ts_now(struct peak_time_ref *time_ref, u32 ts_now);void peak_usb_get_ts_time (struct peak_time_ref *time_ref,u32 ts,ktime_t *tv);int peak_usb_netif_rx (struct sk_buff *skb,struct peak_time_ref *time_ref,u32 ts_low); +int peak_usb_netif_rx_64 (struct sk_buff *skb,u32 ts_low,u32 ts_high);void peak_usb_async_complete (struct urb *urb);void peak_usb_restart_complete (struct peak_usb_device *dev);
drivers/net/can/usb/peak_usb/pcan_usb_fd.c +6 -3
@@ -515,7 +515,8 @@ static int pcan_usb_fd_decode_canmsg(struct pcan_usb_fd_if *usb_if, netdev->stats.rx_packets++; netdev->stats.rx_bytes += cfd->len; -peak_usb_netif_rx (skb, &usb_if->time_ref,le32_to_cpu (rm->ts_low)); +peak_usb_netif_rx_64 (skb,le32_to_cpu (rm->ts_low), +le32_to_cpu (rm->ts_high));return 0 ; }
@@ -579,7 +580,8 @@ static int pcan_usb_fd_decode_status(struct pcan_usb_fd_if *usb_if, netdev->stats.rx_packets++; netdev->stats.rx_bytes += cf->len; -peak_usb_netif_rx (skb, &usb_if->time_ref,le32_to_cpu (sm->ts_low)); +peak_usb_netif_rx_64 (skb,le32_to_cpu (sm->ts_low), +le32_to_cpu (sm->ts_high));return 0 ; }
@@ -629,7 +631,8 @@ static int pcan_usb_fd_decode_overrun(struct pcan_usb_fd_if *usb_if, cf->can_id |=CAN_ERR_CRTL ; cf->data[1 ] |=CAN_ERR_CRTL_RX_OVERFLOW ; -peak_usb_netif_rx (skb, &usb_if->time_ref,le32_to_cpu (ov->ts_low)); +peak_usb_netif_rx_64 (skb,le32_to_cpu (ov->ts_low), +le32_to_cpu (ov->ts_high)); netdev->stats.rx_over_errors++; netdev->stats.rx_errors++;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 401/565 can: do not increase rx statistics when generating a CAN rx error message frame
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vincent Mailhol <[email protected]>
[ Upstream commit 676068db69b847f06fe054fca15bf6b107bd24da ]
The CAN error message frames (i.e. error skb) are an interface specific to socket CAN. The payload of the CAN error message frames does not correspond to any actual data sent on the wire. Only an error flag and a delimiter are transmitted when an error occurs (c.f. ISO 11898-1 section 10.4.4.2 "Error flag").
For this reason, it makes no sense to increment the rx_packets and rx_bytes fields of struct net_device_stats because no actual payload were transmitted on the wire.
This patch fixes all the CAN drivers.
Stable-dep-of: 9e66242504f4 ("can: c_can: c_can_handle_bus_err(): update statistics if skb allocation fails")
--- drivers/net/can/at91_can.c | 6 ------ drivers/net/can/c_can/c_can_main.c | 5 ----- drivers/net/can/cc770/cc770.c | 3 --- drivers/net/can/dev/dev.c | 4 ---- drivers/net/can/dev/rx-offload.c | 6 ++++-- drivers/net/can/ifi_canfd/ifi_canfd.c | 5 ----- drivers/net/can/kvaser_pciefd.c | 5 ----- drivers/net/can/m_can/m_can.c | 7 ------- drivers/net/can/mscan/mscan.c | 9 +++++---- drivers/net/can/pch_can.c | 3 --- drivers/net/can/peak_canfd/peak_canfd.c | 4 ---- drivers/net/can/rcar/rcar_can.c | 6 +----- drivers/net/can/rcar/rcar_canfd.c | 4 ---- drivers/net/can/sja1000/sja1000.c | 2 -- drivers/net/can/sun4i_can.c | 7 ++----- drivers/net/can/usb/ems_usb.c | 2 -- drivers/net/can/usb/esd_usb2.c | 2 -- drivers/net/can/usb/etas_es58x/es58x_core.c | 7 ------- drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | 2 -- drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 8 -------- drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 4 ---- drivers/net/can/usb/peak_usb/pcan_usb.c | 2 -- drivers/net/can/usb/peak_usb/pcan_usb_fd.c | 3 --- drivers/net/can/usb/peak_usb/pcan_usb_pro.c | 2 -- drivers/net/can/usb/ucan.c | 6 ++++-- drivers/net/can/usb/usb_8dev.c | 2 -- drivers/net/can/xilinx_can.c | 9 +-------- 27 files changed, 17 insertions(+), 108 deletions(-)
drivers/net/can/at91_can.c +0 -6
@@ -553,8 +553,6 @@ static void at91_rx_overflow_err(struct net_device *dev) cf->can_id |=CAN_ERR_CRTL ; cf->data[1 ] =CAN_ERR_CRTL_RX_OVERFLOW ; - stats->rx_packets++; - stats->rx_bytes += cf->len;netif_receive_skb (skb); }
@@ -779,8 +777,6 @@ static int at91_poll_err(struct net_device *dev, int quota, u32 reg_sr)at91_poll_err_frame (dev, cf, reg_sr); - dev->stats.rx_packets++; - dev->stats.rx_bytes += cf->len;netif_receive_skb (skb);return 1 ;
@@ -1037,8 +1033,6 @@ static void at91_irq_err(struct net_device *dev)at91_irq_err_state (dev, cf, new_state); - dev->stats.rx_packets++; - dev->stats.rx_bytes += cf->len;netif_rx (skb); priv->can.state = new_state;
drivers/net/can/c_can/c_can_main.c +0 -5
@@ -919,7 +919,6 @@ static int c_can_handle_state_change(struct net_device *dev,unsigned int reg_err_counter;unsigned int rx_err_passive;struct c_can_priv *priv =netdev_priv (dev); -struct net_device_stats *stats = &dev->stats;struct can_frame *cf;struct sk_buff *skb;struct can_berr_counter bec;
@@ -995,8 +994,6 @@ static int c_can_handle_state_change(struct net_device *dev,break ; } - stats->rx_packets++; - stats->rx_bytes += cf->len;netif_receive_skb (skb);return 1 ;
@@ -1068,8 +1065,6 @@ static int c_can_handle_bus_err(struct net_device *dev,break ; } - stats->rx_packets++; - stats->rx_bytes += cf->len;netif_receive_skb (skb);return 1 ; }
drivers/net/can/cc770/cc770.c +0 -3
@@ -499,7 +499,6 @@ static void cc770_rx(struct net_device *dev, unsigned int mo, u8 ctrl1)static int cc770_err (struct net_device *dev,u8 status) {struct cc770_priv *priv =netdev_priv (dev); -struct net_device_stats *stats = &dev->stats;struct can_frame *cf;struct sk_buff *skb;u8 lec;
@@ -571,8 +570,6 @@ static int cc770_err(struct net_device *dev, u8 status) } - stats->rx_packets++; - stats->rx_bytes += cf->len;netif_rx (skb);return 0 ;
drivers/net/can/dev/dev.c +0 -4
@@ -136,7 +136,6 @@ EXPORT_SYMBOL_GPL(can_change_state);static void can_restart (struct net_device *dev) {struct can_priv *priv =netdev_priv (dev); -struct net_device_stats *stats = &dev->stats;struct sk_buff *skb;struct can_frame *cf;int err;
@@ -156,9 +155,6 @@ static void can_restart(struct net_device *dev) cf->can_id |=CAN_ERR_RESTARTED ; - stats->rx_packets++; - stats->rx_bytes += cf->len; -netif_rx_ni (skb); restart:
drivers/net/can/dev/rx-offload.c +4 -2
@@ -54,8 +54,10 @@ static int can_rx_offload_napi_poll(struct napi_struct *napi, int quota)struct can_frame *cf = (struct can_frame *)skb->data; work_done++; - stats->rx_packets++; - stats->rx_bytes += cf->len; +if (!(cf->can_id &CAN_ERR_FLAG )) { + stats->rx_packets++; + stats->rx_bytes += cf->len; + }netif_receive_skb (skb); }
drivers/net/can/ifi_canfd/ifi_canfd.c +0 -5
@@ -430,8 +430,6 @@ static int ifi_canfd_handle_lec_err(struct net_device *ndev) priv->base + IFI_CANFD_INTERRUPT);writel (IFI_CANFD_ERROR_CTR_ER_ENABLE , priv->base +IFI_CANFD_ERROR_CTR ); - stats->rx_packets++; - stats->rx_bytes += cf->len;netif_receive_skb (skb);return 1 ;
@@ -456,7 +454,6 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev, enum can_state new_state) {struct ifi_canfd_priv *priv =netdev_priv (ndev); -struct net_device_stats *stats = &ndev->stats;struct can_frame *cf;struct sk_buff *skb;struct can_berr_counter bec;
@@ -522,8 +519,6 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev,break ; } - stats->rx_packets++; - stats->rx_bytes += cf->len;netif_receive_skb (skb);return 1 ;
drivers/net/can/kvaser_pciefd.c +0 -5
@@ -1327,9 +1327,6 @@ static int kvaser_pciefd_rx_error_frame(struct kvaser_pciefd_can *can, cf->data[6 ] = bec.txerr; cf->data[7 ] = bec.rxerr; - stats->rx_packets++; - stats->rx_bytes += cf->len; -netif_rx (skb);return 0 ; }
@@ -1524,8 +1521,6 @@ static void kvaser_pciefd_handle_nack_packet(struct kvaser_pciefd_can *can,if (skb) { cf->can_id |=CAN_ERR_BUSERROR ; - stats->rx_bytes += cf->len; - stats->rx_packets++;netif_rx (skb); }else { stats->rx_dropped++;
drivers/net/can/m_can/m_can.c +0 -7
@@ -653,9 +653,6 @@ static int m_can_handle_lec_err(struct net_device *dev,break ; } - stats->rx_packets++; - stats->rx_bytes += cf->len; -if (cdev->is_peripheral) timestamp =m_can_get_timestamp (cdev);
@@ -712,7 +709,6 @@ static int m_can_handle_state_change(struct net_device *dev, enum can_state new_state) {struct m_can_classdev *cdev =netdev_priv (dev); -struct net_device_stats *stats = &dev->stats;struct can_frame *cf;struct sk_buff *skb;struct can_berr_counter bec;
@@ -777,9 +773,6 @@ static int m_can_handle_state_change(struct net_device *dev,break ; } - stats->rx_packets++; - stats->rx_bytes += cf->len; -if (cdev->is_peripheral) timestamp =m_can_get_timestamp (cdev);
drivers/net/can/mscan/mscan.c +5 -4
@@ -401,13 +401,14 @@ static int mscan_rx_poll(struct napi_struct *napi, int quota)continue ; } -if (canrflg &MSCAN_RXF ) +if (canrflg &MSCAN_RXF ) {mscan_get_rx_frame (dev, frame); -else if (canrflg &MSCAN_ERR_IF ) + stats->rx_packets++; + stats->rx_bytes += frame->len; + }else if (canrflg &MSCAN_ERR_IF ) {mscan_get_err_frame (dev, frame, canrflg); + } - stats->rx_packets++; - stats->rx_bytes += frame->len; work_done++;netif_receive_skb (skb); }
drivers/net/can/pch_can.c +0 -3
@@ -561,9 +561,6 @@ static void pch_can_error(struct net_device *ndev, u32 status) priv->can.state = state;netif_receive_skb (skb); - - stats->rx_packets++; - stats->rx_bytes += cf->len; }static irqreturn_t pch_can_interrupt (int irq,void *dev_id)
drivers/net/can/peak_canfd/peak_canfd.c +0 -4
@@ -409,8 +409,6 @@ static int pucan_handle_status(struct peak_canfd_priv *priv,return -ENOMEM ; } - stats->rx_packets++; - stats->rx_bytes += cf->len;pucan_netif_rx (skb, msg->ts_low, msg->ts_high);return 0 ;
@@ -438,8 +436,6 @@ static int pucan_handle_cache_critical(struct peak_canfd_priv *priv) cf->data[6 ] = priv->bec.txerr; cf->data[7 ] = priv->bec.rxerr; - stats->rx_bytes += cf->len; - stats->rx_packets++;netif_rx (skb);return 0 ;
drivers/net/can/rcar/rcar_can.c +1 -5
@@ -223,7 +223,6 @@ static void tx_failure_cleanup(struct net_device *ndev)static void rcar_can_error (struct net_device *ndev) {struct rcar_can_priv *priv =netdev_priv (ndev); -struct net_device_stats *stats = &ndev->stats;struct can_frame *cf;struct sk_buff *skb;u8 eifr, txerr =0 , rxerr =0 ;
@@ -362,11 +361,8 @@ static void rcar_can_error(struct net_device *ndev) } } -if (skb) { - stats->rx_packets++; - stats->rx_bytes += cf->len; +if (skb)netif_rx (skb); - } }static void rcar_can_tx_done (struct net_device *ndev)
drivers/net/can/rcar/rcar_canfd.c +0 -4
@@ -1033,8 +1033,6 @@ static void rcar_canfd_error(struct net_device *ndev, u32 cerfl,/* Clear channel error interrupts that are handled */ rcar_canfd_write (priv->base,RCANFD_CERFL (ch),RCANFD_CERFL_ERR (~cerfl)); - stats->rx_packets++; - stats->rx_bytes += cf->len;netif_rx (skb); }
@@ -1176,8 +1174,6 @@ static void rcar_canfd_state_change(struct net_device *ndev, rx_state = txerr <= rxerr ? state :0 ;can_change_state (ndev, cf, tx_state, rx_state); - stats->rx_packets++; - stats->rx_bytes += cf->len;netif_rx (skb); } }
drivers/net/can/sja1000/sja1000.c +0 -2
@@ -488,8 +488,6 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)can_bus_off (dev); } - stats->rx_packets++; - stats->rx_bytes += cf->len;netif_rx (skb);return 0 ;
drivers/net/can/sun4i_can.c +2 -5
@@ -621,13 +621,10 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)can_bus_off (dev); } -if (likely (skb)) { - stats->rx_packets++; - stats->rx_bytes += cf->len; +if (likely (skb))netif_rx (skb); - }else { +else return -ENOMEM ; - }return 0 ; }
drivers/net/can/usb/ems_usb.c +0 -2
@@ -397,8 +397,6 @@ static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg) stats->rx_errors++; } - stats->rx_packets++; - stats->rx_bytes += cf->len;netif_rx (skb); }
drivers/net/can/usb/esd_usb2.c +0 -2
@@ -301,8 +301,6 @@ static void esd_usb2_rx_event(struct esd_usb2_net_priv *priv, priv->bec.txerr = txerr; priv->bec.rxerr = rxerr; - stats->rx_packets++; - stats->rx_bytes += cf->len;netif_rx (skb); } }
drivers/net/can/usb/etas_es58x/es58x_core.c +0 -7
@@ -849,13 +849,6 @@ int es58x_rx_err_msg(struct net_device *netdev, enum es58x_err error,break ; } -/* driver/net/can/dev.c:can_restart() takes in account error -* messages in the RX stats. Doing the same here for -* consistency. -*/ - netdev->stats.rx_packets++; - netdev->stats.rx_bytes +=CAN_ERR_DLC ; -if (cf) {if (cf->data[1 ]) cf->can_id |=CAN_ERR_CRTL ;
drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +0 -2
@@ -315,8 +315,6 @@ int kvaser_usb_can_rx_over_error(struct net_device *netdev) cf->can_id |=CAN_ERR_CRTL ; cf->data[1 ] =CAN_ERR_CRTL_RX_OVERFLOW ; - stats->rx_packets++; - stats->rx_bytes += cf->len;netif_rx (skb);return 0 ;
drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c +0 -8
@@ -922,7 +922,6 @@ static void kvaser_usb_hydra_update_state(struct kvaser_usb_net_priv *priv,struct net_device *netdev = priv->netdev;struct can_frame *cf;struct sk_buff *skb; -struct net_device_stats *stats;enum can_state new_state, old_state; old_state = priv->can.state;
@@ -974,9 +973,6 @@ static void kvaser_usb_hydra_update_state(struct kvaser_usb_net_priv *priv, cf->data[7 ] = bec->rxerr; } - stats = &netdev->stats; - stats->rx_packets++; - stats->rx_bytes += cf->len;netif_rx (skb); }
@@ -1131,8 +1127,6 @@ kvaser_usb_hydra_error_frame(struct kvaser_usb_net_priv *priv, cf->data[7 ] = bec.rxerr; } - stats->rx_packets++; - stats->rx_bytes += cf->len;netif_rx (skb); priv->bec.txerr = bec.txerr;
@@ -1166,8 +1160,6 @@ static void kvaser_usb_hydra_one_shot_fail(struct kvaser_usb_net_priv *priv, } stats->tx_errors++; - stats->rx_packets++; - stats->rx_bytes += cf->len;netif_rx (skb); }
drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +0 -4
@@ -907,8 +907,6 @@ static void kvaser_usb_leaf_tx_acknowledge(const struct kvaser_usb *dev,if (skb) { cf->can_id |=CAN_ERR_RESTARTED ; - stats->rx_packets++; - stats->rx_bytes += cf->len;netif_rx (skb); }else { netdev_err(priv->netdev,
@@ -1131,8 +1129,6 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev, cf->data[7 ] = es->rxerr; } - stats->rx_packets++; - stats->rx_bytes += cf->len;netif_rx (skb); }
drivers/net/can/usb/peak_usb/pcan_usb.c +0 -2
@@ -520,8 +520,6 @@ static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n, &hwts->hwtstamp); } - mc->netdev->stats.rx_packets++; - mc->netdev->stats.rx_bytes += cf->len;netif_rx (skb);return 0 ;
drivers/net/can/usb/peak_usb/pcan_usb_fd.c +0 -3
@@ -577,9 +577,6 @@ static int pcan_usb_fd_decode_status(struct pcan_usb_fd_if *usb_if,if (!skb)return -ENOMEM ; - netdev->stats.rx_packets++; - netdev->stats.rx_bytes += cf->len; -peak_usb_netif_rx_64 (skb,le32_to_cpu (sm->ts_low),le32_to_cpu (sm->ts_high));
drivers/net/can/usb/peak_usb/pcan_usb_pro.c +0 -2
@@ -660,8 +660,6 @@ static int pcan_usb_pro_handle_error(struct pcan_usb_pro_interface *usb_if, hwts =skb_hwtstamps (skb);peak_usb_get_ts_time (&usb_if->time_ref,le32_to_cpu (er->ts32), &hwts->hwtstamp); - netdev->stats.rx_packets++; - netdev->stats.rx_bytes += can_frame->len;netif_rx (skb);return 0 ;
drivers/net/can/usb/ucan.c +4 -2
@@ -621,8 +621,10 @@ static void ucan_rx_can_msg(struct ucan_priv *up, struct ucan_message_in *m)memcpy (cf->data, m->msg.can_msg.data, cf->len);/* don't count error frames as real packets */ - stats->rx_packets++; - stats->rx_bytes += cf->len; +if (!(cf->can_id &CAN_ERR_FLAG )) { + stats->rx_packets++; + stats->rx_bytes += cf->len; + }/* pass it to Linux */ netif_rx (skb);
drivers/net/can/usb/usb_8dev.c +0 -2
@@ -450,8 +450,6 @@ static void usb_8dev_rx_err_msg(struct usb_8dev_priv *priv, priv->bec.txerr = txerr; priv->bec.rxerr = rxerr; - stats->rx_packets++; - stats->rx_bytes += cf->len;netif_rx (skb); }
drivers/net/can/xilinx_can.c +1 -8
@@ -966,13 +966,8 @@ static void xcan_update_error_state_after_rxtx(struct net_device *ndev)xcan_set_error_state (ndev, new_state, skb ? cf :NULL ); -if (skb) { -struct net_device_stats *stats = &ndev->stats; - - stats->rx_packets++; - stats->rx_bytes += cf->len; +if (skb)netif_rx (skb); - } } }
@@ -1096,8 +1091,6 @@ static void xcan_err_interrupt(struct net_device *ndev, u32 isr)if (skb) { skb_cf->can_id |= cf.can_id;memcpy (skb_cf->data, cf.data,CAN_ERR_DLC ); - stats->rx_packets++; - stats->rx_bytes +=CAN_ERR_DLC ;netif_rx (skb); } }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 402/565 can: c_can: c_can_handle_bus_err(): update statistics if skb allocation fails
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dario Binacchi <[email protected]>
[ Upstream commit 9e66242504f49e17481d8e197730faba7d99c934 ]
Ensure that the statistics are always updated, even if the skb allocation fails.
--- drivers/net/can/c_can/c_can_main.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-)
drivers/net/can/c_can/c_can_main.c +17 -9
@@ -1022,49 +1022,57 @@ static int c_can_handle_bus_err(struct net_device *dev,/* propagate the error condition to the CAN stack */ skb =alloc_can_err_skb (dev, &cf); -if (unlikely (!skb)) -return 0 ;/* check for 'last error code' which tells us the * type of the last error to occur on the CAN bus */ - cf->can_id |=CAN_ERR_PROT |CAN_ERR_BUSERROR ; +if (likely (skb)) + cf->can_id |=CAN_ERR_PROT |CAN_ERR_BUSERROR ;switch (lec_type) {case LEC_STUFF_ERROR :netdev_dbg (dev,"stuff error\n" ); - cf->data[2 ] |=CAN_ERR_PROT_STUFF ; +if (likely (skb)) + cf->data[2 ] |=CAN_ERR_PROT_STUFF ; stats->rx_errors++;break ;case LEC_FORM_ERROR :netdev_dbg (dev,"form error\n" ); - cf->data[2 ] |=CAN_ERR_PROT_FORM ; +if (likely (skb)) + cf->data[2 ] |=CAN_ERR_PROT_FORM ; stats->rx_errors++;break ;case LEC_ACK_ERROR :netdev_dbg (dev,"ack error\n" ); - cf->data[3 ] =CAN_ERR_PROT_LOC_ACK ; +if (likely (skb)) + cf->data[3 ] =CAN_ERR_PROT_LOC_ACK ; stats->tx_errors++;break ;case LEC_BIT1_ERROR :netdev_dbg (dev,"bit1 error\n" ); - cf->data[2 ] |=CAN_ERR_PROT_BIT1 ; +if (likely (skb)) + cf->data[2 ] |=CAN_ERR_PROT_BIT1 ; stats->tx_errors++;break ;case LEC_BIT0_ERROR :netdev_dbg (dev,"bit0 error\n" ); - cf->data[2 ] |=CAN_ERR_PROT_BIT0 ; +if (likely (skb)) + cf->data[2 ] |=CAN_ERR_PROT_BIT0 ; stats->tx_errors++;break ;case LEC_CRC_ERROR :netdev_dbg (dev,"CRC error\n" ); - cf->data[3 ] =CAN_ERR_PROT_LOC_CRC_SEQ ; +if (likely (skb)) + cf->data[3 ] =CAN_ERR_PROT_LOC_CRC_SEQ ; stats->rx_errors++;break ;default :break ; } +if (unlikely (!skb)) +return 0 ; +netif_receive_skb (skb);return 1 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 403/565 can: sun4i_can: sun4i_can_err(): call can_change_state() even if cf is NULL
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dario Binacchi <[email protected]>
[ Upstream commit ee6bf3677ae03569d833795064e17f605c2163c7 ]
Call the function can_change_state() if the allocation of the skb fails, as it handles the cf parameter when it is null.
Additionally, this ensures that the statistics related to state error counters (i. e. warning, passive, and bus-off) are updated.
--- drivers/net/can/sun4i_can.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/can/sun4i_can.c +4 -4
@@ -613,10 +613,10 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status) tx_state = txerr >= rxerr ? state :0 ; rx_state = txerr <= rxerr ? state :0 ; -if (likely (skb)) -can_change_state (dev, cf, tx_state, rx_state); -else - priv->can.state = state; +/* The skb allocation might fail, but can_change_state() +* handles cf == NULL. +*/ +can_change_state (dev, cf, tx_state, rx_state);if (state ==CAN_STATE_BUS_OFF )can_bus_off (dev); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 404/565 can: m_can: m_can_handle_lec_err(): fix {rx,tx}_errors statistics
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dario Binacchi <[email protected]>
[ Upstream commit 988d4222bf9039a875a3d48f2fe35c317831ff68 ]
The m_can_handle_lec_err() function was incorrectly incrementing only the receive error counter, even in cases of bit or acknowledgment errors that occur during transmission.
Fix the issue by incrementing the appropriate counter based on the type of error.
--- drivers/net/can/m_can/m_can.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-)
drivers/net/can/m_can/m_can.c +23 -10
@@ -612,47 +612,60 @@ static int m_can_handle_lec_err(struct net_device *dev,u32 timestamp =0 ; cdev->can.can_stats.bus_error++; - stats->rx_errors++;/* propagate the error condition to the CAN stack */ skb =alloc_can_err_skb (dev, &cf); -if (unlikely (!skb)) -return 0 ;/* check for 'last error code' which tells us the * type of the last error to occur on the CAN bus */ - cf->can_id |=CAN_ERR_PROT |CAN_ERR_BUSERROR ; +if (likely (skb)) + cf->can_id |=CAN_ERR_PROT |CAN_ERR_BUSERROR ;switch (lec_type) {case LEC_STUFF_ERROR :netdev_dbg (dev,"stuff error\n" ); - cf->data[2 ] |=CAN_ERR_PROT_STUFF ; + stats->rx_errors++; +if (likely (skb)) + cf->data[2 ] |=CAN_ERR_PROT_STUFF ;break ;case LEC_FORM_ERROR :netdev_dbg (dev,"form error\n" ); - cf->data[2 ] |=CAN_ERR_PROT_FORM ; + stats->rx_errors++; +if (likely (skb)) + cf->data[2 ] |=CAN_ERR_PROT_FORM ;break ;case LEC_ACK_ERROR :netdev_dbg (dev,"ack error\n" ); - cf->data[3 ] =CAN_ERR_PROT_LOC_ACK ; + stats->tx_errors++; +if (likely (skb)) + cf->data[3 ] =CAN_ERR_PROT_LOC_ACK ;break ;case LEC_BIT1_ERROR :netdev_dbg (dev,"bit1 error\n" ); - cf->data[2 ] |=CAN_ERR_PROT_BIT1 ; + stats->tx_errors++; +if (likely (skb)) + cf->data[2 ] |=CAN_ERR_PROT_BIT1 ;break ;case LEC_BIT0_ERROR :netdev_dbg (dev,"bit0 error\n" ); - cf->data[2 ] |=CAN_ERR_PROT_BIT0 ; + stats->tx_errors++; +if (likely (skb)) + cf->data[2 ] |=CAN_ERR_PROT_BIT0 ;break ;case LEC_CRC_ERROR :netdev_dbg (dev,"CRC error\n" ); - cf->data[3 ] =CAN_ERR_PROT_LOC_CRC_SEQ ; + stats->rx_errors++; +if (likely (skb)) + cf->data[3 ] =CAN_ERR_PROT_LOC_CRC_SEQ ;break ;default :break ; } +if (unlikely (!skb)) +return 0 ; +if (cdev->is_peripheral) timestamp =m_can_get_timestamp (cdev);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 405/565 can: ifi_canfd: ifi_canfd_handle_lec_err(): fix {rx,tx}_errors statistics
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dario Binacchi <[email protected]>
[ Upstream commit bb03d568bb21b4afe7935d1943bcf68ddea3ea45 ]
The ifi_canfd_handle_lec_err() function was incorrectly incrementing only the receive error counter, even in cases of bit or acknowledgment errors that occur during transmission.
Fix the issue by incrementing the appropriate counter based on the type of error.
--- drivers/net/can/ifi_canfd/ifi_canfd.c | 58 ++++++++++++++++++--------- 1 file changed, 40 insertions(+), 18 deletions(-)
drivers/net/can/ifi_canfd/ifi_canfd.c +40 -18
@@ -393,36 +393,55 @@ static int ifi_canfd_handle_lec_err(struct net_device *ndev)return 0 ; priv->can.can_stats.bus_error++; - stats->rx_errors++;/* Propagate the error condition to the CAN stack. */ skb =alloc_can_err_skb (ndev, &cf); -if (unlikely (!skb)) -return 0 ;/* Read the error counter register and check for new errors. */ - cf->can_id |=CAN_ERR_PROT |CAN_ERR_BUSERROR ; +if (likely (skb)) + cf->can_id |=CAN_ERR_PROT |CAN_ERR_BUSERROR ; -if (errctr &IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST ) - cf->data[2 ] |=CAN_ERR_PROT_OVERLOAD ; +if (errctr &IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST ) { + stats->rx_errors++; +if (likely (skb)) + cf->data[2 ] |=CAN_ERR_PROT_OVERLOAD ; + } -if (errctr &IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST ) - cf->data[3 ] =CAN_ERR_PROT_LOC_ACK ; +if (errctr &IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST ) { + stats->tx_errors++; +if (likely (skb)) + cf->data[3 ] =CAN_ERR_PROT_LOC_ACK ; + } -if (errctr &IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST ) - cf->data[2 ] |=CAN_ERR_PROT_BIT0 ; +if (errctr &IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST ) { + stats->tx_errors++; +if (likely (skb)) + cf->data[2 ] |=CAN_ERR_PROT_BIT0 ; + } -if (errctr &IFI_CANFD_ERROR_CTR_BIT1_ERROR_FIRST ) - cf->data[2 ] |=CAN_ERR_PROT_BIT1 ; +if (errctr &IFI_CANFD_ERROR_CTR_BIT1_ERROR_FIRST ) { + stats->tx_errors++; +if (likely (skb)) + cf->data[2 ] |=CAN_ERR_PROT_BIT1 ; + } -if (errctr &IFI_CANFD_ERROR_CTR_STUFF_ERROR_FIRST ) - cf->data[2 ] |=CAN_ERR_PROT_STUFF ; +if (errctr &IFI_CANFD_ERROR_CTR_STUFF_ERROR_FIRST ) { + stats->rx_errors++; +if (likely (skb)) + cf->data[2 ] |=CAN_ERR_PROT_STUFF ; + } -if (errctr &IFI_CANFD_ERROR_CTR_CRC_ERROR_FIRST ) - cf->data[3 ] =CAN_ERR_PROT_LOC_CRC_SEQ ; +if (errctr &IFI_CANFD_ERROR_CTR_CRC_ERROR_FIRST ) { + stats->rx_errors++; +if (likely (skb)) + cf->data[3 ] =CAN_ERR_PROT_LOC_CRC_SEQ ; + } -if (errctr &IFI_CANFD_ERROR_CTR_FORM_ERROR_FIRST ) - cf->data[2 ] |=CAN_ERR_PROT_FORM ; +if (errctr &IFI_CANFD_ERROR_CTR_FORM_ERROR_FIRST ) { + stats->rx_errors++; +if (likely (skb)) + cf->data[2 ] |=CAN_ERR_PROT_FORM ; + }/* Reset the error counter, ack the IRQ and re-enable the counter. */ writel (IFI_CANFD_ERROR_CTR_ER_RESET , priv->base +IFI_CANFD_ERROR_CTR );
@@ -430,6 +449,9 @@ static int ifi_canfd_handle_lec_err(struct net_device *ndev) priv->base + IFI_CANFD_INTERRUPT);writel (IFI_CANFD_ERROR_CTR_ER_ENABLE , priv->base +IFI_CANFD_ERROR_CTR ); +if (unlikely (!skb)) +return 0 ; +netif_receive_skb (skb);return 1 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 406/565 can: sun4i_can: sun4i_can_err(): fix {rx,tx}_errors statistics
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dario Binacchi <[email protected]>
[ Upstream commit 595a81988a6fe06eb5849e972c8b9cb21c4e0d54 ]
The sun4i_can_err() function only incremented the receive error counter and never the transmit error counter, even if the STA_ERR_DIR flag reported that an error had occurred during transmission.
Increment the receive/transmit error counter based on the value of the STA_ERR_DIR flag.
--- drivers/net/can/sun4i_can.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
drivers/net/can/sun4i_can.c +9 -5
@@ -563,11 +563,9 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)/* bus error interrupt */ netdev_dbg (dev,"bus error interrupt\n" ); priv->can.can_stats.bus_error++; - stats->rx_errors++; + ecc =readl (priv->base +SUN4I_REG_STA_ADDR );if (likely (skb)) { - ecc =readl (priv->base +SUN4I_REG_STA_ADDR ); - cf->can_id |=CAN_ERR_PROT |CAN_ERR_BUSERROR ;switch (ecc &SUN4I_STA_MASK_ERR ) {
@@ -585,9 +583,15 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status) >> 16;break ; } -/* error occurred during transmission? */ -if ((ecc &SUN4I_STA_ERR_DIR ) ==0 ) + } + +/* error occurred during transmission? */ +if ((ecc &SUN4I_STA_ERR_DIR ) ==0 ) { +if (likely (skb)) cf->data[2 ] |=CAN_ERR_PROT_TX ; + stats->tx_errors++; + }else { + stats->rx_errors++; } }if (isrc &SUN4I_INT_ERR_PASSIVE ) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 407/565 can: ems_usb: ems_usb_rx_err(): fix {rx,tx}_errors statistics
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dario Binacchi <[email protected]>
[ Upstream commit 72a7e2e74b3075959f05e622bae09b115957dffe ]
The ems_usb_rx_err() function only incremented the receive error counter and never the transmit error counter, even if the ECC_DIR flag reported that an error had occurred during transmission.
Increment the receive/transmit error counter based on the value of the ECC_DIR flag.
--- drivers/net/can/usb/ems_usb.c | 58 ++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 25 deletions(-)
drivers/net/can/usb/ems_usb.c +33 -25
@@ -334,15 +334,14 @@ static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg)struct net_device_stats *stats = &dev->netdev->stats; skb =alloc_can_err_skb (dev->netdev, &cf); -if (skb ==NULL ) -return ;if (msg->type ==CPC_MSG_TYPE_CAN_STATE ) {u8 state = msg->msg.can_state;if (state &SJA1000_SR_BS ) { dev->can.state =CAN_STATE_BUS_OFF ; - cf->can_id |=CAN_ERR_BUSOFF ; +if (skb) + cf->can_id |=CAN_ERR_BUSOFF ; dev->can.can_stats.bus_off++;can_bus_off (dev->netdev);
@@ -360,44 +359,53 @@ static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg)/* bus error interrupt */ dev->can.can_stats.bus_error++; - stats->rx_errors++; - cf->can_id |=CAN_ERR_PROT |CAN_ERR_BUSERROR ; +if (skb) { + cf->can_id |=CAN_ERR_PROT |CAN_ERR_BUSERROR ; -switch (ecc &SJA1000_ECC_MASK ) { -case SJA1000_ECC_BIT : - cf->data[2 ] |=CAN_ERR_PROT_BIT ; -break ; -case SJA1000_ECC_FORM : - cf->data[2 ] |=CAN_ERR_PROT_FORM ; -break ; -case SJA1000_ECC_STUFF : - cf->data[2 ] |=CAN_ERR_PROT_STUFF ; -break ; -default : - cf->data[3 ] = ecc &SJA1000_ECC_SEG ; -break ; +switch (ecc &SJA1000_ECC_MASK ) { +case SJA1000_ECC_BIT : + cf->data[2 ] |=CAN_ERR_PROT_BIT ; +break ; +case SJA1000_ECC_FORM : + cf->data[2 ] |=CAN_ERR_PROT_FORM ; +break ; +case SJA1000_ECC_STUFF : + cf->data[2 ] |=CAN_ERR_PROT_STUFF ; +break ; +default : + cf->data[3 ] = ecc &SJA1000_ECC_SEG ; +break ; + } }/* Error occurred during transmission? */ -if ((ecc &SJA1000_ECC_DIR ) ==0 ) - cf->data[2 ] |=CAN_ERR_PROT_TX ; +if ((ecc &SJA1000_ECC_DIR ) ==0 ) { + stats->tx_errors++; +if (skb) + cf->data[2 ] |=CAN_ERR_PROT_TX ; + }else { + stats->rx_errors++; + } -if (dev->can.state ==CAN_STATE_ERROR_WARNING || - dev->can.state ==CAN_STATE_ERROR_PASSIVE ) { +if (skb && (dev->can.state ==CAN_STATE_ERROR_WARNING || + dev->can.state ==CAN_STATE_ERROR_PASSIVE )) { cf->can_id |=CAN_ERR_CRTL ; cf->data[1 ] = (txerr > rxerr) ?CAN_ERR_CRTL_TX_PASSIVE :CAN_ERR_CRTL_RX_PASSIVE ; } }else if (msg->type ==CPC_MSG_TYPE_OVERRUN ) { - cf->can_id |=CAN_ERR_CRTL ; - cf->data[1 ] =CAN_ERR_CRTL_RX_OVERFLOW ; +if (skb) { + cf->can_id |=CAN_ERR_CRTL ; + cf->data[1 ] =CAN_ERR_CRTL_RX_OVERFLOW ; + } stats->rx_over_errors++; stats->rx_errors++; } -netif_rx (skb); +if (skb) +netif_rx (skb); }/*
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 408/565 ipvs: fix UB due to uninitialized stack access in ip_vs_protocol_init()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinghao Jia <[email protected]>
[ Upstream commit 146b6f1112eb30a19776d6c323c994e9d67790db ]
Under certain kernel configurations when building with Clang/LLVM, the compiler does not generate a return or jump as the terminator instruction for ip_vs_protocol_init(), triggering the following objtool warning during build time:
vmlinux.o: warning: objtool: ip_vs_protocol_init() falls through to next function __initstub__kmod_ip_vs_rr__935_123_ip_vs_rr_init6()
At runtime, this either causes an oops when trying to load the ipvs module or a boot-time panic if ipvs is built-in. This same issue has been reported by the Intel kernel test robot previously.
Digging deeper into both LLVM and the kernel code reveals this to be a undefined behavior problem. ip_vs_protocol_init() uses a on-stack buffer of 64 chars to store the registered protocol names and leaves it uninitialized after definition. The function calls strnlen() when concatenating protocol names into the buffer. With CONFIG_FORTIFY_SOURCE strnlen() performs an extra step to check whether the last byte of the input char buffer is a null character (commit 3009f891bb9f ("fortify:
Allow strlen() and strnlen() to pass compile-time known lengths")). This, together with possibly other configurations, cause the following IR to be generated:
define hidden i32 @ip_vs_protocol_init() local_unnamed_addr #5 section ".init.text" align 16 !kcfi_type !29 {
%1 = alloca [64 x i8], align 16
...14: ; preds = %11
%15 = getelementptr inbounds i8, ptr %1, i64 63
%16 = load i8, ptr %15, align 1
%17 = tail call i1 @llvm.is.constant.i8(i8 %16)
%18 = icmp eq i8 %16, 0
%19 = select i1 %17, i1 %18, i1 false
br i1 %19, label %20, label %23 20: ; preds = %14
%21 = call i64 @strlen(ptr noundef nonnull dereferenceable(1) %1) #23
...
23: ; preds = %14, %11, %20
%24 = call i64 @strnlen(ptr noundef nonnull dereferenceable(1) %1, i64 noundef 64) #24
...
}The above code calculates the address of the last char in the buffer (value %15) and then loads from it (value %16). Because the buffer is never initialized, the LLVM GVN pass marks value %16 as undefined:
%13 = getelementptr inbounds i8, ptr %1, i64 63
br i1 undef, label %14, label %17
This gives later passes (SCCP, in particular) more DCE opportunities by propagating the undef value further, and eventually removes everything after the load on the uninitialized stack location:
define hidden i32 @ip_vs_protocol_init() local_unnamed_addr #0 section ".init.text" align 16 !kcfi_type !11 {
%1 = alloca [64 x i8], align 16
...
12: ; preds = %11
%13 = getelementptr inbounds i8, ptr %1, i64 63
unreachable
}In this way, the generated native code will just fall through to the next function, as LLVM does not generate any code for the unreachable IR instruction and leaves the function without a terminator.
Zero the on-stack buffer to avoid this possible UB.
--- net/netfilter/ipvs/ip_vs_proto.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
net/netfilter/ipvs/ip_vs_proto.c +1 -3
@@ -340,7 +340,7 @@ void __net_exit ip_vs_protocol_net_cleanup(struct netns_ipvs *ipvs)int __init ip_vs_protocol_init (void ) { -char protocols[64 ]; +char protocols[64 ] = {0 };#define REGISTER_PROTOCOL (p) \ do { \ register_ip_vs_protocol(p); \
@@ -348,8 +348,6 @@ int __init ip_vs_protocol_init(void)strcat (protocols, (p)->name); \ } while (0) - protocols[0 ] ='\0' ; - protocols[2 ] ='\0' ;#ifdef CONFIG_IP_VS_PROTO_TCP REGISTER_PROTOCOL (&ip_vs_protocol_tcp);#endif
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 409/565 netfilter: x_tables: fix LED ID check in led_tg_check()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Antipov <[email protected]>
[ Upstream commit 04317f4eb2aad312ad85c1a17ad81fe75f1f9bc7 ]
Syzbot has reported the following BUG detected by KASAN:
BUG: KASAN: slab-out-of-bounds in strlen+0x58/0x70 Read of size 1 at addr ffff8881022da0c8 by task repro/5879 ... Call Trace: <TASK> dump_stack_lvl+0x241/0x360 ? __pfx_dump_stack_lvl+0x10/0x10 ? __pfx__printk+0x10/0x10 ? _printk+0xd5/0x120 ? __virt_addr_valid+0x183/0x530 ? __virt_addr_valid+0x183/0x530 print_report+0x169/0x550 ? __virt_addr_valid+0x183/0x530 ? __virt_addr_valid+0x183/0x530 ? __virt_addr_valid+0x45f/0x530 ? __phys_addr+0xba/0x170 ? strlen+0x58/0x70 kasan_report+0x143/0x180 ? strlen+0x58/0x70 strlen+0x58/0x70 kstrdup+0x20/0x80 led_tg_check+0x18b/0x3c0 xt_check_target+0x3bb/0xa40 ? __pfx_xt_check_target+0x10/0x10 ? stack_depot_save_flags+0x6e4/0x830 ? nft_target_init+0x174/0xc30 nft_target_init+0x82d/0xc30 ? __pfx_nft_target_init+0x10/0x10 ? nf_tables_newrule+0x1609/0x2980 ? nf_tables_newrule+0x1609/0x2980 ? rcu_is_watching+0x15/0xb0 ? nf_tables_newrule+0x1609/0x2980 ? nf_tables_newrule+0x1609/0x2980 ? __kmalloc_noprof+0x21a/0x400 nf_tables_newrule+0x1860/0x2980 ? __pfx_nf_tables_newrule+0x10/0x10 ? __nla_parse+0x40/0x60 nfnetlink_rcv+0x14e5/0x2ab0 ? __pfx_validate_chain+0x10/0x10 ? __pfx_nfnetlink_rcv+0x10/0x10 ? __lock_acquire+0x1384/0x2050 ? netlink_deliver_tap+0x2e/0x1b0 ? __pfx_lock_release+0x10/0x10 ? netlink_deliver_tap+0x2e/0x1b0 netlink_unicast+0x7f8/0x990 ? __pfx_netlink_unicast+0x10/0x10 ? __virt_addr_valid+0x183/0x530 ? __check_object_size+0x48e/0x900 netlink_sendmsg+0x8e4/0xcb0 ? __pfx_netlink_sendmsg+0x10/0x10 ? aa_sock_msg_perm+0x91/0x160 ? __pfx_netlink_sendmsg+0x10/0x10 __sock_sendmsg+0x223/0x270 ____sys_sendmsg+0x52a/0x7e0 ? __pfx_____sys_sendmsg+0x10/0x10 __sys_sendmsg+0x292/0x380 ? __pfx___sys_sendmsg+0x10/0x10 ? lockdep_hardirqs_on_prepare+0x43d/0x780 ? __pfx_lockdep_hardirqs_on_prepare+0x10/0x10 ? exc_page_fault+0x590/0x8c0 ? do_syscall_64+0xb6/0x230 do_syscall_64+0xf3/0x230 entry_SYSCALL_64_after_hwframe+0x77/0x7f ... </TASK>
Since an invalid (without '\0' byte at all) byte sequence may be passed from userspace, add an extra check to ensure that such a sequence is rejected as possible ID and so never passed to 'kstrdup()' and further.
--- net/netfilter/xt_LED.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/netfilter/xt_LED.c +3 -1
@@ -97,7 +97,9 @@ static int led_tg_check(const struct xt_tgchk_param *par)struct xt_led_info_internal *ledinternal;int err; -if (ledinfo->id[0 ] =='\0' ) +/* Bail out if empty string or not a string at all. */ +if (ledinfo->id[0 ] =='\0' || + !memchr (ledinfo->id,'\0' ,sizeof (ledinfo->id)))return -EINVAL ;mutex_lock (&xt_led_mutex);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 410/565 ptp: Add error handling for adjfine callback in ptp_clock_adjtime
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ajay Kaher <[email protected]>
[ Upstream commit 98337d7c87577ded71114f6976edb70a163e27bc ]
ptp_clock_adjtime sets ptp->dialed_frequency even when adjfine callback returns an error. This causes subsequent reads to return an incorrect value.
Fix this by adding error check before ptp->dialed_frequency is set.
--- drivers/ptp/ptp_clock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/ptp/ptp_clock.c +2 -1
@@ -136,7 +136,8 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct __kernel_timex *tx) err = ops->adjfine (ops, tx->freq); else err = ops->adjfreq (ops, ppb); - ptp->dialed_frequency = tx->freq; +if (!err) + ptp->dialed_frequency = tx->freq; }else if (tx->modes &ADJ_OFFSET ) {if (ops->adjphase) {s32 offset = tx->offset;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 411/565 net/sched: tbf: correct backlog statistic for GSO packets
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin Ottens <[email protected]>
[ Upstream commit 1596a135e3180c92e42dd1fbcad321f4fb3e3b17 ]
When the length of a GSO packet in the tbf qdisc is larger than the burst size configured the packet will be segmented by the tbf_segment function. Whenever this function is used to enqueue SKBs, the backlog statistic of the tbf is not increased correctly. This can lead to underflows of the 'backlog' byte-statistic value when these packets are dequeued from tbf.
Reproduce the bug:
Ensure that the sender machine has GSO enabled. Configured the tbf on the outgoing interface of the machine as follows (burstsize = 1 MTU):
$ tc qdisc add dev <oif> root handle 1: tbf rate 50Mbit burst 1514 latency 50ms
Send bulk TCP traffic out via this interface, e.g., by running an iPerf3 client on this machine. Check the qdisc statistics:
$ tc -s qdisc show dev <oif>
The 'backlog' byte-statistic has incorrect values while traffic is transferred, e.g., high values due to u32 underflows. When the transfer is stopped, the value is != 0, which should never happen.
This patch fixes this bug by updating the statistics correctly, even if single SKBs of a GSO SKB cannot be enqueued.
--- net/sched/sch_tbf.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
net/sched/sch_tbf.c +12 -6
@@ -193,7 +193,7 @@ static int tbf_segment(struct sk_buff *skb, struct Qdisc *sch,struct tbf_sched_data *q =qdisc_priv (sch);struct sk_buff *segs, *nskb;netdev_features_t features =netif_skb_features (skb); -unsigned int len =0 , prev_len =qdisc_pkt_len (skb); +unsigned int len =0 , prev_len =qdisc_pkt_len (skb), seg_len;int ret, nb; segs =skb_gso_segment (skb, features & ~NETIF_F_GSO_MASK );
@@ -204,21 +204,27 @@ static int tbf_segment(struct sk_buff *skb, struct Qdisc *sch, nb =0 ; skb_list_walk_safe(segs, segs, nskb) {skb_mark_not_on_list (segs); -qdisc_skb_cb (segs)->pkt_len = segs->len; - len += segs->len; + seg_len = segs->len; +qdisc_skb_cb (segs)->pkt_len = seg_len; ret =qdisc_enqueue (segs, q->qdisc, to_free);if (ret !=NET_XMIT_SUCCESS ) {if (net_xmit_drop_count (ret))qdisc_qstats_drop (sch); }else { nb++; + len += seg_len; } } sch->q.qlen += nb; -if (nb >1 ) + sch->qstats.backlog += len; +if (nb >0 ) {qdisc_tree_reduce_backlog (sch,1 - nb, prev_len - len); -consume_skb (skb); -return nb >0 ?NET_XMIT_SUCCESS :NET_XMIT_DROP ; +consume_skb (skb); +return NET_XMIT_SUCCESS ; + } + +kfree_skb (skb); +return NET_XMIT_DROP ; } static int tbf_enqueue(struct sk_buff *skb, struct Qdisc *sch,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 412/565 net: hsr: avoid potential out-of-bound access in fill_frame_info()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit b9653d19e556c6afd035602927a93d100a0d7644 ]
syzbot is able to feed a packet with 14 bytes, pretending it is a vlan one.
Since fill_frame_info() is relying on skb->mac_len already, extend the check to cover this case.
BUG: KMSAN: uninit-value in fill_frame_info net/hsr/hsr_forward.c:709 [inline] BUG: KMSAN: uninit-value in hsr_forward_skb+0x9ee/0x3b10 net/hsr/hsr_forward.c:724 fill_frame_info net/hsr/hsr_forward.c:709 [inline] hsr_forward_skb+0x9ee/0x3b10 net/hsr/hsr_forward.c:724 hsr_dev_xmit+0x2f0/0x350 net/hsr/hsr_device.c:235 __netdev_start_xmit include/linux/netdevice.h:5002 [inline] netdev_start_xmit include/linux/netdevice.h:5011 [inline] xmit_one net/core/dev.c:3590 [inline] dev_hard_start_xmit+0x247/0xa20 net/core/dev.c:3606 __dev_queue_xmit+0x366a/0x57d0 net/core/dev.c:4434 dev_queue_xmit include/linux/netdevice.h:3168 [inline] packet_xmit+0x9c/0x6c0 net/packet/af_packet.c:276 packet_snd net/packet/af_packet.c:3146 [inline] packet_sendmsg+0x91ae/0xa6f0 net/packet/af_packet.c:3178 sock_sendmsg_nosec net/socket.c:711 [inline] __sock_sendmsg+0x30f/0x380 net/socket.c:726 __sys_sendto+0x594/0x750 net/socket.c:2197 __do_sys_sendto net/socket.c:2204 [inline] __se_sys_sendto net/socket.c:2200 [inline] __x64_sys_sendto+0x125/0x1d0 net/socket.c:2200 x64_sys_call+0x346a/0x3c30 arch/x86/include/generated/asm/syscalls_64.h:45 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xcd/0x1e0 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f
Uninit was created at:
slab_post_alloc_hook mm/slub.c:4091 [inline] slab_alloc_node mm/slub.c:4134 [inline] kmem_cache_alloc_node_noprof+0x6bf/0xb80 mm/slub.c:4186 kmalloc_reserve+0x13d/0x4a0 net/core/skbuff.c:587 __alloc_skb+0x363/0x7b0 net/core/skbuff.c:678 alloc_skb include/linux/skbuff.h:1323 [inline] alloc_skb_with_frags+0xc8/0xd00 net/core/skbuff.c:6612 sock_alloc_send_pskb+0xa81/0xbf0 net/core/sock.c:2881 packet_alloc_skb net/packet/af_packet.c:2995 [inline] packet_snd net/packet/af_packet.c:3089 [inline] packet_sendmsg+0x74c6/0xa6f0 net/packet/af_packet.c:3178 sock_sendmsg_nosec net/socket.c:711 [inline] __sock_sendmsg+0x30f/0x380 net/socket.c:726 __sys_sendto+0x594/0x750 net/socket.c:2197 __do_sys_sendto net/socket.c:2204 [inline] __se_sys_sendto net/socket.c:2200 [inline] __x64_sys_sendto+0x125/0x1d0 net/socket.c:2200 x64_sys_call+0x346a/0x3c30 arch/x86/include/generated/asm/syscalls_64.h:45 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xcd/0x1e0 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f
--- net/hsr/hsr_forward.c | 2 ++ 1 file changed, 2 insertions(+)
net/hsr/hsr_forward.c +2 -0
@@ -546,6 +546,8 @@ static int fill_frame_info(struct hsr_frame_info *frame, frame->is_vlan = true;if (frame->is_vlan) { + if (skb->mac_len < offsetofend(struct hsr_vlan_ethhdr, vlanhdr)) +return -EINVAL ; vlan_hdr = (struct hsr_vlan_ethhdr *)ethhdr; proto = vlan_hdr->vlanhdr.h_vlan_encapsulated_proto;/* FIXME: */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 413/565 can: j1939: j1939_session_new(): fix skb reference counting
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Antipov <[email protected]>
[ Upstream commit a8c695005bfe6569acd73d777ca298ddddd66105 ]
Since j1939_session_skb_queue() does an extra skb_get() for each new skb, do the same for the initial one in j1939_session_new() to avoid refcount underflow.
--- net/can/j1939/transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/can/j1939/transport.c +1 -1
@@ -1505,7 +1505,7 @@ static struct j1939_session *j1939_session_new(struct j1939_priv *priv, session->state =J1939_SESSION_NEW ;skb_queue_head_init (&session->skb_queue); -skb_queue_tail (&session->skb_queue, skb); +skb_queue_tail (&session->skb_queue,skb_get (skb)); skcb =j1939_skb_to_cb (skb);memcpy (&session->skcb, skcb,sizeof (session->skcb));
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 414/565 net/ipv6: release expired exception dst cached in socket
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Wiesner <[email protected]>
[ Upstream commit 3301ab7d5aeb0fe270f73a3d4810c9d1b6a9f045 ]
Dst objects get leaked in ip6_negative_advice() when this function is executed for an expired IPv6 route located in the exception table. There are several conditions that must be fulfilled for the leak to occur:
* an ICMPv6 packet indicating a change of the MTU for the path is received, resulting in an exception dst being created
* a TCP connection that uses the exception dst for routing packets must start timing out so that TCP begins retransmissions
* after the exception dst expires, the FIB6 garbage collector must not run before TCP executes ip6_negative_advice() for the expired exception dst
When TCP executes ip6_negative_advice() for an exception dst that has expired and if no other socket holds a reference to the exception dst, the refcount of the exception dst is 2, which corresponds to the increment made by dst_init() and the increment made by the TCP socket for which the connection is timing out. The refcount made by the socket is never released. The refcount of the dst is decremented in sk_dst_reset() but that decrement is counteracted by a dst_hold() intentionally placed just before the sk_dst_reset() in ip6_negative_advice(). After ip6_negative_advice() has finished, there is no other object tied to the dst. The socket lost its reference stored in sk_dst_cache and the dst is no longer in the exception table. The exception dst becomes a leaked object.
As a result of this dst leak, an unbalanced refcount is reported for the loopback device of a net namespace being destroyed under kernels that do not contain e5f80fcf869a ("ipv6: give an IPv6 dev to blackhole_netdev"):unregister_netdevice: waiting for lo to become free. Usage count = 2
Fix the dst leak by removing the dst_hold() in ip6_negative_advice(). The patch that introduced the dst_hold() in ip6_negative_advice() was 92f1655aa2b22 ("net: fix __dst_negative_advice() race"). But 92f1655aa2b22 merely refactored the code with regards to the dst refcount so the issue was present even before 92f1655aa2b22. The bug was introduced in 54c1a859efd9f ("ipv6: Don't drop cache route entry unless timer actually expired.") where the expired cached route is deleted and the sk_dst_cache member of the socket is set to NULL by calling dst_negative_advice() but the refcount belonging to the socket is left unbalanced.
The IPv4 version - ipv4_negative_advice() - is not affected by this bug. When the TCP connection times out ipv4_negative_advice() merely resets the sk_dst_cache of the socket while decrementing the refcount of the exception dst.
--- net/ipv6/route.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
net/ipv6/route.c +3 -3
@@ -2769,10 +2769,10 @@ static void ip6_negative_advice(struct sock *sk,if (rt->rt6i_flags &RTF_CACHE ) {rcu_read_lock ();if (rt6_check_expired (rt)) { -/* counteract the dst_release() in sk_dst_reset() */ -dst_hold (dst); +/* rt/dst can not be destroyed yet, +* because of rcu_read_lock() +*/ sk_dst_reset (sk); -rt6_remove_exception_rt (rt); }rcu_read_unlock ();
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 415/565 dccp: Fix memory leak in dccp_feat_change_recv
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ivan Solodovnikov <[email protected]>
[ Upstream commit 22be4727a8f898442066bcac34f8a1ad0bc72e14 ]
If dccp_feat_push_confirm() fails after new value for SP feature was accepted without reconciliation ('entry == NULL' branch), memory allocated for that value with dccp_feat_clone_sp_val() is never freed.
Here is the kmemleak stack for this:
unreferenced object 0xffff88801d4ab488 (size 8):
comm "syz-executor310", pid 1127, jiffies 4295085598 (age 41.666s) hex dump (first 8 bytes):
01 b4 4a 1d 80 88 ff ff ..J.....
backtrace:
[<00000000db7cabfe>] kmemdup+0x23/0x50 mm/util.c:128
[<0000000019b38405>] kmemdup include/linux/string.h:465 [inline]
[<0000000019b38405>] dccp_feat_clone_sp_val net/dccp/feat.c:371 [inline]
[<0000000019b38405>] dccp_feat_clone_sp_val net/dccp/feat.c:367 [inline]
[<0000000019b38405>] dccp_feat_change_recv net/dccp/feat.c:1145 [inline]
[<0000000019b38405>] dccp_feat_parse_options+0x1196/0x2180 net/dccp/feat.c:1416
[<00000000b1f6d94a>] dccp_parse_options+0xa2a/0x1260 net/dccp/options.c:125
[<0000000030d7b621>] dccp_rcv_state_process+0x197/0x13d0 net/dccp/input.c:650
[<000000001f74c72e>] dccp_v4_do_rcv+0xf9/0x1a0 net/dccp/ipv4.c:688
[<00000000a6c24128>] sk_backlog_rcv include/net/sock.h:1041 [inline]
[<00000000a6c24128>] __release_sock+0x139/0x3b0 net/core/sock.c:2570
[<00000000cf1f3a53>] release_sock+0x54/0x1b0 net/core/sock.c:3111
[<000000008422fa23>] inet_wait_for_connect net/ipv4/af_inet.c:603 [inline]
[<000000008422fa23>] __inet_stream_connect+0x5d0/0xf70 net/ipv4/af_inet.c:696
[<0000000015b6f64d>] inet_stream_connect+0x53/0xa0 net/ipv4/af_inet.c:735
[<0000000010122488>] __sys_connect_file+0x15c/0x1a0 net/socket.c:1865
[<00000000b4b70023>] __sys_connect+0x165/0x1a0 net/socket.c:1882
[<00000000f4cb3815>] __do_sys_connect net/socket.c:1892 [inline]
[<00000000f4cb3815>] __se_sys_connect net/socket.c:1889 [inline]
[<00000000f4cb3815>] __x64_sys_connect+0x6e/0xb0 net/socket.c:1889
[<00000000e7b1e839>] do_syscall_64+0x33/0x40 arch/x86/entry/common.c:46
[<0000000055e91434>] entry_SYSCALL_64_after_hwframe+0x67/0xd1Clean up the allocated memory in case of dccp_feat_push_confirm() failure and bail out with an error reset code.
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
--- net/dccp/feat.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
net/dccp/feat.c +5 -1
@@ -1166,8 +1166,12 @@ static u8 dccp_feat_change_recv(struct list_head *fn, u8 is_mandatory, u8 opt, goto not_valid_or_not_known; } -return dccp_feat_push_confirm (fn, feat, local, &fval); +if (dccp_feat_push_confirm (fn, feat, local, &fval)) { +kfree (fval.sp.vec); +return DCCP_RESET_CODE_TOO_BUSY ; + } +return 0 ; }else if (entry->state ==FEAT_UNSTABLE ) {/* 6.6.2 */ return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 416/565 tipc: Fix use-after-free of kernel socket in cleanup_bearer().
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 6a2fa13312e51a621f652d522d7e2df7066330b6 ]
syzkaller reported a use-after-free of UDP kernel socket in cleanup_bearer() without repro. [0][1]
When bearer_disable() calls tipc_udp_disable(), cleanup of the UDP kernel socket is deferred by work calling cleanup_bearer().
tipc_net_stop() waits for such works to finish by checking tipc_net(net)->wq_count. However, the work decrements the count too early before releasing the kernel socket, unblocking cleanup_net() and resulting in use-after-free.
Let's move the decrement after releasing the socket in cleanup_bearer().
[0]:ref_tracker: net notrefcnt@000000009b3d1faf has 1/1 users at
sk_alloc+0x438/0x608
inet_create+0x4c8/0xcb0
__sock_create+0x350/0x6b8
sock_create_kern+0x58/0x78
udp_sock_create4+0x68/0x398
udp_sock_create+0x88/0xc8
tipc_udp_enable+0x5e8/0x848
__tipc_nl_bearer_enable+0x84c/0xed8
tipc_nl_bearer_enable+0x38/0x60
genl_family_rcv_msg_doit+0x170/0x248
genl_rcv_msg+0x400/0x5b0
netlink_rcv_skb+0x1dc/0x398
genl_rcv+0x44/0x68
netlink_unicast+0x678/0x8b0
netlink_sendmsg+0x5e4/0x898
____sys_sendmsg+0x500/0x830[1]:
BUG: KMSAN: use-after-free in udp_hashslot include/net/udp.h:85 [inline] BUG: KMSAN: use-after-free in udp_lib_unhash+0x3b8/0x930 net/ipv4/udp.c:1979 udp_hashslot include/net/udp.h:85 [inline] udp_lib_unhash+0x3b8/0x930 net/ipv4/udp.c:1979 sk_common_release+0xaf/0x3f0 net/core/sock.c:3820 inet_release+0x1e0/0x260 net/ipv4/af_inet.c:437 inet6_release+0x6f/0xd0 net/ipv6/af_inet6.c:489 __sock_release net/socket.c:658 [inline] sock_release+0xa0/0x210 net/socket.c:686 cleanup_bearer+0x42d/0x4c0 net/tipc/udp_media.c:819 process_one_work kernel/workqueue.c:3229 [inline] process_scheduled_works+0xcaf/0x1c90 kernel/workqueue.c:3310 worker_thread+0xf6c/0x1510 kernel/workqueue.c:3391 kthread+0x531/0x6b0 kernel/kthread.c:389 ret_from_fork+0x60/0x80 arch/x86/kernel/process.c:147 ret_from_fork_asm+0x11/0x20 arch/x86/entry/entry_64.S:244
Uninit was created at:
slab_free_hook mm/slub.c:2269 [inline] slab_free mm/slub.c:4580 [inline] kmem_cache_free+0x207/0xc40 mm/slub.c:4682 net_free net/core/net_namespace.c:454 [inline] cleanup_net+0x16f2/0x19d0 net/core/net_namespace.c:647 process_one_work kernel/workqueue.c:3229 [inline] process_scheduled_works+0xcaf/0x1c90 kernel/workqueue.c:3310 worker_thread+0xf6c/0x1510 kernel/workqueue.c:3391 kthread+0x531/0x6b0 kernel/kthread.c:389 ret_from_fork+0x60/0x80 arch/x86/kernel/process.c:147 ret_from_fork_asm+0x11/0x20 arch/x86/entry/entry_64.S:244 CPU: 0 UID: 0 PID: 54 Comm: kworker/0:2 Not tainted 6.12.0-rc1-00131-gf66ebf37d69c #7 91723d6f74857f70725e1583cba3cf4adc716cfa Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014 Workqueue: events cleanup_bearer
--- net/tipc/udp_media.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/tipc/udp_media.c +1 -1
@@ -818,10 +818,10 @@ static void cleanup_bearer(struct work_struct *work)kfree_rcu (rcast, rcu); } -atomic_dec (&tipc_net (sock_net (ub->ubsock->sk))->wq_count);dst_cache_destroy (&ub->rcast.dst_cache);udp_tunnel_sock_release (ub->ubsock);synchronize_net (); +atomic_dec (&tipc_net (sock_net (ub->ubsock->sk))->wq_count);kfree (ub); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 417/565 net/smc: Limit backlog connections
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: D. Wythe <[email protected]>
[ Upstream commit 8270d9c21041470f58348248b9d9dcf3bf79592e ]
Current implementation does not handling backlog semantics, one potential risk is that server will be flooded by infinite amount connections, even if client was SMC-incapable.
This patch works to put a limit on backlog connections, referring to the TCP implementation, we divides SMC connections into two categories:
1. Half SMC connection, which includes all TCP established while SMC not connections.
2. Full SMC connection, which includes all SMC established connections.
For half SMC connection, since all half SMC connections starts with TCP established, we can achieve our goal by put a limit before TCP established. Refer to the implementation of TCP, this limits will based on not only the half SMC connections but also the full connections, which is also a constraint on full SMC connections.
For full SMC connections, although we know exactly where it starts, it's quite hard to put a limit before it. The easiest way is to block wait before receive SMC confirm CLC message, while it's under protection by smc_server_lgr_pending, a global lock, which leads this limit to the entire host instead of a single listen socket. Another way is to drop the full connections, but considering the cast of SMC connections, we prefer to keep full SMC connections.
Even so, the limits of full SMC connections still exists, see commits about half SMC connection below.
After this patch, the limits of backend connection shows like:
For SMC:
1. Client with SMC-capability can makes 2 * backlog full SMC connections or 1 * backlog half SMC connections and 1 * backlog full SMC connections at most.
2. Client without SMC-capability can only makes 1 * backlog half TCP connections and 1 * backlog full TCP connections.
Stable-dep-of: 2c7f14ed9c19 ("net/smc: fix LGR and link use-after-free issue")
--- net/smc/af_smc.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ net/smc/smc.h | 6 +++++- 2 files changed, 50 insertions(+), 1 deletion(-)
net/smc/af_smc.c +45 -0
@@ -71,6 +71,36 @@ static void smc_set_keepalive(struct sock *sk, int val) smc->clcsock->sk->sk_prot->keepalive (smc->clcsock->sk, val); } +static struct sock *smc_tcp_syn_recv_sock (const struct sock *sk, +struct sk_buff *skb, +struct request_sock *req, +struct dst_entry *dst, +struct request_sock *req_unhash, +bool *own_req) +{ +struct smc_sock *smc; + + smc =smc_clcsock_user_data (sk); + +if (READ_ONCE (sk->sk_ack_backlog) +atomic_read (&smc->queued_smc_hs) > + sk->sk_max_ack_backlog) + goto drop; + +if (sk_acceptq_is_full (&smc->sk)) { +NET_INC_STATS (sock_net (sk),LINUX_MIB_LISTENOVERFLOWS ); + goto drop; + } + +/* passthrough to original syn recv sock fct */ +return smc->ori_af_ops->syn_recv_sock (sk, skb, req, dst, req_unhash, + own_req); + +drop: +dst_release (dst); +tcp_listendrop (sk); +return NULL ; +} +static struct smc_hashinfo smc_v4_hashinfo = { .lock =__RW_LOCK_UNLOCKED (smc_v4_hashinfo.lock), };
@@ -1476,6 +1506,9 @@ static void smc_listen_out(struct smc_sock *new_smc)struct smc_sock *lsmc = new_smc->listen_smc;struct sock *newsmcsk = &new_smc->sk; +if (tcp_sk (new_smc->clcsock->sk)->syn_smc) +atomic_dec (&lsmc->queued_smc_hs); +if (lsmc->sk.sk_state ==SMC_LISTEN ) {lock_sock_nested (&lsmc->sk,SINGLE_DEPTH_NESTING );smc_accept_enqueue (&lsmc->sk, newsmcsk);
@@ -2008,6 +2041,9 @@ static void smc_tcp_listen_work(struct work_struct *work)if (!new_smc)continue ; +if (tcp_sk (new_smc->clcsock->sk)->syn_smc) +atomic_inc (&lsmc->queued_smc_hs); + new_smc->listen_smc = lsmc; new_smc->use_fallback = lsmc->use_fallback; new_smc->fallback_rsn = lsmc->fallback_rsn;
@@ -2074,6 +2110,15 @@ static int smc_listen(struct socket *sock, int backlog) smc->clcsock->sk->sk_data_ready = smc_clcsock_data_ready; smc->clcsock->sk->sk_user_data = (void *)((uintptr_t )smc |SK_USER_DATA_NOCOPY ); + +/* save original ops */ + smc->ori_af_ops =inet_csk (smc->clcsock->sk)->icsk_af_ops; + + smc->af_ops = *smc->ori_af_ops; + smc->af_ops.syn_recv_sock = smc_tcp_syn_recv_sock; + +inet_csk (smc->clcsock->sk)->icsk_af_ops = &smc->af_ops; + rc =kernel_listen (smc->clcsock, backlog);if (rc) { smc->clcsock->sk->sk_data_ready = smc->clcsk_data_ready;
net/smc/smc.h +5 -1
@@ -241,6 +241,10 @@ struct smc_sock { /* smc sock container */bool use_fallback;/* fallback to tcp */ int fallback_rsn;/* reason for fallback */ u32 peer_diagnosis;/* decline reason from peer */ +atomic_t queued_smc_hs;/* queued smc handshakes */ +struct inet_connection_sock_af_ops af_ops; +const struct inet_connection_sock_af_ops *ori_af_ops; +/* original af ops */ int sockopt_defer_accept;/* sockopt TCP_DEFER_ACCEPT * value
@@ -265,7 +269,7 @@ static inline struct smc_sock *smc_sk(const struct sock *sk)return (struct smc_sock *)sk; } -static inline struct smc_sock *smc_clcsock_user_data (struct sock *clcsk) +static inline struct smc_sock *smc_clcsock_user_data (const struct sock *clcsk) {return (struct smc_sock *) ((uintptr_t )clcsk->sk_user_data & ~SK_USER_DATA_NOCOPY );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 418/565 net/smc: fix LGR and link use-after-free issue
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wen Gu <[email protected]>
[ Upstream commit 2c7f14ed9c19ec0f149479d1c2842ec1f9bf76d7 ]
We encountered a LGR/link use-after-free issue, which manifested as the LGR/link refcnt reaching 0 early and entering the clear process, making resource access unsafe.
refcount_t: addition on 0; use-after-free.
WARNING: CPU: 14 PID: 107447 at lib/refcount.c:25 refcount_warn_saturate+0x9c/0x140 Workqueue: events smc_lgr_terminate_work [smc] Call trace: refcount_warn_saturate+0x9c/0x140 __smc_lgr_terminate.part.45+0x2a8/0x370 [smc] smc_lgr_terminate_work+0x28/0x30 [smc] process_one_work+0x1b8/0x420 worker_thread+0x158/0x510 kthread+0x114/0x118
or
refcount_t: underflow; use-after-free.
WARNING: CPU: 6 PID: 93140 at lib/refcount.c:28 refcount_warn_saturate+0xf0/0x140 Workqueue: smc_hs_wq smc_listen_work [smc] Call trace: refcount_warn_saturate+0xf0/0x140 smcr_link_put+0x1cc/0x1d8 [smc] smc_conn_free+0x110/0x1b0 [smc] smc_conn_abort+0x50/0x60 [smc] smc_listen_find_device+0x75c/0x790 [smc] smc_listen_work+0x368/0x8a0 [smc] process_one_work+0x1b8/0x420 worker_thread+0x158/0x510 kthread+0x114/0x118
It is caused by repeated release of LGR/link refcnt. One suspect is that smc_conn_free() is called repeatedly because some smc_conn_free() from server listening path are not protected by sock lock.
e.g.
Calls under socklock | smc_listen_work
-------------------------------------------------------
lock_sock(sk) | smc_conn_abort smc_conn_free | \- smc_conn_free \- smcr_link_put | \- smcr_link_put (duplicated)
release_sock(sk)
So here add sock lock protection in smc_listen_work() path, making it exclusive with other connection operations.
--- net/smc/af_smc.c | 2 ++ 1 file changed, 2 insertions(+)
net/smc/af_smc.c +2 -0
@@ -1509,6 +1509,7 @@ static void smc_listen_out(struct smc_sock *new_smc)if (tcp_sk (new_smc->clcsock->sk)->syn_smc)atomic_dec (&lsmc->queued_smc_hs); +release_sock (newsmcsk);/* lock in smc_listen_work() */ if (lsmc->sk.sk_state ==SMC_LISTEN ) {lock_sock_nested (&lsmc->sk,SINGLE_DEPTH_NESTING );smc_accept_enqueue (&lsmc->sk, newsmcsk);
@@ -1921,6 +1922,7 @@ static void smc_listen_work(struct work_struct *work)struct smc_init_info *ini =NULL ;int rc =0 ; +lock_sock (&new_smc->sk);/* release in smc_listen_out() */ if (new_smc->listen_smc->sk.sk_state !=SMC_LISTEN )return smc_listen_out_err (new_smc);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 419/565 net/qed: allow old cards not supporting "num_images" to work
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Louis Leseur <[email protected]>
[ Upstream commit 7a0ea70da56ee8c2716d0b79e9959d3c47efab62 ]
Commit 43645ce03e00 ("qed: Populate nvm image attribute shadow.") added support for populating flash image attributes, notably "num_images". However, some cards were not able to return this information. In such cases, the driver would return EINVAL, causing the driver to exit.
Add check to return EOPNOTSUPP instead of EINVAL when the card is not able to return these information. The caller function already handles EOPNOTSUPP without error.
--- drivers/net/ethernet/qlogic/qed/qed_mcp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ethernet/qlogic/qed/qed_mcp.c +3 -1
@@ -3253,7 +3253,9 @@ int qed_mcp_bist_nvm_get_num_images(struct qed_hwfn *p_hwfn,if (rc)return rc; -if (((rsp &FW_MSG_CODE_MASK ) !=FW_MSG_CODE_OK )) +if (((rsp &FW_MSG_CODE_MASK ) ==FW_MSG_CODE_UNSUPPORTED )) + rc = -EOPNOTSUPP ; +else if (((rsp &FW_MSG_CODE_MASK ) !=FW_MSG_CODE_OK )) rc = -EINVAL ;return rc;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 420/565 igb: Fix potential invalid memory access in igb_init_module()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuan Can <[email protected]>
[ Upstream commit 0566f83d206c7a864abcd741fe39d6e0ae5eef29 ]
The pci_register_driver() can fail and when this happened, the dca_notifier needs to be unregistered, otherwise the dca_notifier can be called when igb fails to install, resulting to invalid memory access.
--- drivers/net/ethernet/intel/igb/igb_main.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/net/ethernet/intel/igb/igb_main.c +4 -0
@@ -667,6 +667,10 @@ static int __init igb_init_module(void)dca_register_notify (&dca_notifier);#endif ret =pci_register_driver (&igb_driver); +#ifdef CONFIG_IGB_DCA +if (ret) +dca_unregister_notify (&dca_notifier); +#endif return ret; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 421/565 net: sched: fix erspan_opt settings in cls_flower
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xin Long <[email protected]>
[ Upstream commit 292207809486d99c78068d3f459cbbbffde88415 ]
When matching erspan_opt in cls_flower, only the (version, dir, hwid) fields are relevant. However, in fl_set_erspan_opt() it initializes all bits of erspan_opt and its mask to 1. This inadvertently requires packets to match not only the (version, dir, hwid) fields but also the other fields that are unexpectedly set to 1.
This patch resolves the issue by ensuring that only the (version, dir, hwid) fields are configured in fl_set_erspan_opt(), leaving the other fields to 0 in erspan_opt.
--- net/sched/cls_flower.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
net/sched/cls_flower.c +3 -2
@@ -1224,7 +1224,6 @@ static int fl_set_erspan_opt(const struct nlattr *nla, struct fl_flow_key *key,int err; md = (struct erspan_metadata *)&key->enc_opts.data[key->enc_opts.len]; -memset (md,0xff ,sizeof (*md)); md->version =1 ;if (!depth)
@@ -1253,9 +1252,9 @@ static int fl_set_erspan_opt(const struct nlattr *nla, struct fl_flow_key *key,NL_SET_ERR_MSG (extack,"Missing tunnel key erspan option index" );return -EINVAL ; } +memset (&md->u.index,0xff ,sizeof (md->u.index));if (tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_INDEX ]) { nla = tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_INDEX ]; -memset (&md->u,0x00 ,sizeof (md->u)); md->u.index =nla_get_be32 (nla); } }else if (md->version ==2 ) {
@@ -1264,10 +1263,12 @@ static int fl_set_erspan_opt(const struct nlattr *nla, struct fl_flow_key *key,NL_SET_ERR_MSG (extack,"Missing tunnel key erspan option dir or hwid" );return -EINVAL ; } + md->u.md2.dir =1 ;if (tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_DIR ]) { nla = tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_DIR ]; md->u.md2.dir =nla_get_u8 (nla); } +set_hwid (&md->u.md2,0xff );if (tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_HWID ]) { nla = tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_HWID ];set_hwid (&md->u.md2,nla_get_u8 (nla));
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 422/565 netfilter: ipset: Hold module reference while requesting a module
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Phil Sutter <[email protected]>
[ Upstream commit 456f010bfaefde84d3390c755eedb1b0a5857c3c ]
User space may unload ip_set.ko while it is itself requesting a set type backend module, leading to a kernel crash. The race condition may be provoked by inserting an mdelay() right after the nfnl_unlock() call.
--- net/netfilter/ipset/ip_set_core.c | 5 +++++ 1 file changed, 5 insertions(+)
net/netfilter/ipset/ip_set_core.c +5 -0
@@ -104,14 +104,19 @@ find_set_type(const char *name, u8 family, u8 revision)static bool load_settype (const char *name) { +if (!try_module_get (THIS_MODULE )) +return false; +nfnl_unlock (NFNL_SUBSYS_IPSET );pr_debug ("try to load ip_set_%s\n" , name);if (request_module ("ip_set_%s" , name) <0 ) {pr_warn ("Can't find ip_set type %s\n" , name);nfnl_lock (NFNL_SUBSYS_IPSET ); +module_put (THIS_MODULE );return false; }nfnl_lock (NFNL_SUBSYS_IPSET ); +module_put (THIS_MODULE );return true; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 423/565 netfilter: nft_set_hash: skip duplicated elements pending gc run
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pablo Neira Ayuso <[email protected]>
[ Upstream commit 7ffc7481153bbabf3332c6a19b289730c7e1edf5 ]
rhashtable does not provide stable walk, duplicated elements are possible in case of resizing. I considered that checking for errors when calling rhashtable_walk_next() was sufficient to detect the resizing. However, rhashtable_walk_next() returns -EAGAIN only at the end of the iteration, which is too late, because a gc work containing duplicated elements could have been already scheduled for removal to the worker.
Add a u32 gc worker sequence number per set, bump it on every workqueue run. Annotate gc worker sequence number on the expired element. Use it to skip those already seen in this gc workqueue run.
Note that this new field is never reset in case gc transaction fails, so next gc worker run on the expired element overrides it. Wraparound of gc worker sequence number should not be an issue with stale gc worker sequence number in the element, that would just postpone the element removal in one gc run.
Note that it is not possible to use flags to annotate that element is pending gc run to detect duplicates, given that gc transaction can be invalidated in case of update from the control plane, therefore, not allowing to clear such flag.
On x86_64, pahole reports no changes in the size of nft_rhash_elem.
--- net/netfilter/nft_set_hash.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
net/netfilter/nft_set_hash.c +16 -0
@@ -24,10 +24,12 @@struct nft_rhash {struct rhashtable ht;struct delayed_work gc_work; +u32 wq_gc_seq; };struct nft_rhash_elem {struct rhash_head node; +u32 wq_gc_seq;struct nft_set_ext ext; };
@@ -339,6 +341,10 @@ static void nft_rhash_gc(struct work_struct *work)if (!gc) goto done; +/* Elements never collected use a zero gc worker sequence number. */ +if (unlikely (++priv->wq_gc_seq ==0 )) + priv->wq_gc_seq++; +rhashtable_walk_enter (&priv->ht, &hti);rhashtable_walk_start (&hti);
@@ -356,6 +362,14 @@ static void nft_rhash_gc(struct work_struct *work) goto try_later; } +/* rhashtable walk is unstable, already seen in this gc run? +* Then, skip this element. In case of (unlikely) sequence +* wraparound and stale element wq_gc_seq, next gc run will +* just find this expired element. +*/ +if (he->wq_gc_seq == priv->wq_gc_seq) +continue ; +if (nft_set_elem_is_dead (&he->ext)) goto dead_elem;
@@ -372,6 +386,8 @@ static void nft_rhash_gc(struct work_struct *work)if (!gc) goto try_later; +/* annotate gc sequence for this attempt. */ + he->wq_gc_seq = priv->wq_gc_seq;nft_trans_gc_elem_add (gc, he); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 424/565 ethtool: Fix wrong mod state in case of verbose and no_mask bitset
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kory Maincent <[email protected]>
[ Upstream commit 910c4788d6155b2202ec88273376cd7ecdc24f0a ]
A bitset without mask in a _SET request means we want exactly the bits in the bitset to be set. This works correctly for compact format but when verbose format is parsed, ethnl_update_bitset32_verbose() only sets the bits present in the request bitset but does not clear the rest. The commit 6699170376ab ("ethtool: fix application of verbose no_mask bitset") fixes this issue by clearing the whole target bitmap before we start iterating. The solution proposed brought an issue with the behavior of the mod variable. As the bitset is always cleared the old value will always differ to the new value.
Fix it by adding a new function to compare bitmaps and a temporary variable which save the state of the old bitmap.
--- net/ethtool/bitset.c | 48 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-)
net/ethtool/bitset.c +44 -4
@@ -425,12 +425,32 @@ static int ethnl_parse_bit(unsigned int *index, bool *val, unsigned int nbits,return 0 ; } +/** +* ethnl_bitmap32_equal() - Compare two bitmaps +* @map1: first bitmap +* @map2: second bitmap +* @nbits: bit size to compare +* +* Return: true if first @nbits are equal, false if not +*/ +static bool ethnl_bitmap32_equal (const u32 *map1,const u32 *map2, +unsigned int nbits) +{ +if (memcmp (map1, map2, nbits /32 *sizeof (u32))) +return false; +if (nbits %32 ==0 ) +return true; +return !((map1[nbits /32 ] ^ map2[nbits /32 ]) & +ethnl_lower_bits (nbits %32 )); +} +static int ethnl_update_bitset32_verbose (u32 *bitmap,unsigned int nbits,const struct nlattr *attr,struct nlattr **tb,ethnl_string_array_t names,struct netlink_ext_ack *extack,bool *mod) { +u32 *saved_bitmap =NULL ;struct nlattr *bit_attr;bool no_mask;int rem;
@@ -448,8 +468,20 @@ ethnl_update_bitset32_verbose(u32 *bitmap, unsigned int nbits, } no_mask = tb[ETHTOOL_A_BITSET_NOMASK ]; -if (no_mask) -ethnl_bitmap32_clear (bitmap,0 , nbits, mod); +if (no_mask) { +unsigned int nwords =DIV_ROUND_UP (nbits,32 ); +unsigned int nbytes = nwords *sizeof (u32); +bool dummy; + +/* The bitmap size is only the size of the map part without +* its mask part. +*/ + saved_bitmap =kcalloc (nwords,sizeof (u32),GFP_KERNEL ); +if (!saved_bitmap) +return -ENOMEM ; +memcpy (saved_bitmap, bitmap, nbytes); +ethnl_bitmap32_clear (bitmap,0 , nbits, &dummy); + }nla_for_each_nested (bit_attr, tb[ETHTOOL_A_BITSET_BITS ], rem) {bool old_val, new_val;
@@ -458,22 +490,30 @@ ethnl_update_bitset32_verbose(u32 *bitmap, unsigned int nbits,if (nla_type (bit_attr) !=ETHTOOL_A_BITSET_BITS_BIT ) {NL_SET_ERR_MSG_ATTR (extack, bit_attr,"only ETHTOOL_A_BITSET_BITS_BIT allowed in ETHTOOL_A_BITSET_BITS" ); +kfree (saved_bitmap);return -EINVAL ; } ret =ethnl_parse_bit (&idx, &new_val, nbits, bit_attr, no_mask, names, extack); -if (ret <0 ) +if (ret <0 ) { +kfree (saved_bitmap);return ret; + } old_val = bitmap[idx /32 ] & ((u32 )1 << (idx %32 ));if (new_val != old_val) {if (new_val) bitmap[idx /32 ] |= ((u32 )1 << (idx %32 ));else bitmap[idx /32 ] &= ~((u32 )1 << (idx %32 )); - *mod = true; +if (!no_mask) + *mod = true; } } +if (no_mask && !ethnl_bitmap32_equal (saved_bitmap, bitmap, nbits)) + *mod = true; + +kfree (saved_bitmap);return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 425/565 geneve: do not assume mac header is set in geneve_xmit_skb()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 8588c99c7d47448fcae39e3227d6e2bb97aad86d ]
We should not assume mac header is set in output path.
Use skb_eth_hdr() instead of eth_hdr() to fix the issue.
sysbot reported the following :
WARNING: CPU: 0 PID: 11635 at include/linux/skbuff.h:3052 skb_mac_header include/linux/skbuff.h:3052 [inline] WARNING: CPU: 0 PID: 11635 at include/linux/skbuff.h:3052 eth_hdr include/linux/if_ether.h:24 [inline] WARNING: CPU: 0 PID: 11635 at include/linux/skbuff.h:3052 geneve_xmit_skb drivers/net/geneve.c:898 [inline] WARNING: CPU: 0 PID: 11635 at include/linux/skbuff.h:3052 geneve_xmit+0x4c38/0x5730 drivers/net/geneve.c:1039 Modules linked in: CPU: 0 UID: 0 PID: 11635 Comm: syz.4.1423 Not tainted 6.12.0-syzkaller-10296-gaaf20f870da0 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024 RIP: 0010:skb_mac_header include/linux/skbuff.h:3052 [inline] RIP: 0010:eth_hdr include/linux/if_ether.h:24 [inline] RIP: 0010:geneve_xmit_skb drivers/net/geneve.c:898 [inline] RIP: 0010:geneve_xmit+0x4c38/0x5730 drivers/net/geneve.c:1039 Code: 21 c6 02 e9 35 d4 ff ff e8 a5 48 4c fb 90 0f 0b 90 e9 fd f5 ff ff e8 97 48 4c fb 90 0f 0b 90 e9 d8 f5 ff ff e8 89 48 4c fb 90 <0f> 0b 90 e9 41 e4 ff ff e8 7b 48 4c fb 90 0f 0b 90 e9 cd e7 ff ff RSP: 0018:ffffc90003b2f870 EFLAGS: 00010283 RAX: 000000000000037a RBX: 000000000000ffff RCX: ffffc9000dc3d000 RDX: 0000000000080000 RSI: ffffffff86428417 RDI: 0000000000000003 RBP: ffffc90003b2f9f0 R08: 0000000000000003 R09: 000000000000ffff R10: 000000000000ffff R11: 0000000000000002 R12: ffff88806603c000 R13: 0000000000000000 R14: ffff8880685b2780 R15: 0000000000000e23 FS: 00007fdc2deed6c0(0000) GS:ffff8880b8600000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000001b30a1dff8 CR3: 0000000056b8c000 CR4: 00000000003526f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> __netdev_start_xmit include/linux/netdevice.h:5002 [inline] netdev_start_xmit include/linux/netdevice.h:5011 [inline] __dev_direct_xmit+0x58a/0x720 net/core/dev.c:4490 dev_direct_xmit include/linux/netdevice.h:3181 [inline] packet_xmit+0x1e4/0x360 net/packet/af_packet.c:285 packet_snd net/packet/af_packet.c:3146 [inline] packet_sendmsg+0x2700/0x5660 net/packet/af_packet.c:3178 sock_sendmsg_nosec net/socket.c:711 [inline] __sock_sendmsg net/socket.c:726 [inline] __sys_sendto+0x488/0x4f0 net/socket.c:2197 __do_sys_sendto net/socket.c:2204 [inline] __se_sys_sendto net/socket.c:2200 [inline] __x64_sys_sendto+0xe0/0x1c0 net/socket.c:2200 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xcd/0x250 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f
--- drivers/net/geneve.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/geneve.c +1 -1
@@ -985,7 +985,7 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,if (geneve->cfg.df ==GENEVE_DF_SET ) { df =htons (IP_DF ); }else if (geneve->cfg.df ==GENEVE_DF_INHERIT ) { -struct ethhdr *eth =eth_hdr (skb); +struct ethhdr *eth =skb_eth_hdr (skb);if (ntohs (eth->h_proto) ==ETH_P_IPV6 ) { df =htons (IP_DF );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 426/565 gpio: grgpio: use a helper variable to store the address of ofdev->dev
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bartosz Golaszewski <[email protected]>
[ Upstream commit d036ae41cebdfae92666024163c109b8fef516fa ]
Instead of dereferencing the platform device pointer repeatedly, just store its address in a helper variable.
Stable-dep-of: 050b23d081da ("gpio: grgpio: Add NULL check in grgpio_probe")
--- drivers/gpio/gpio-grgpio.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-)
drivers/gpio/gpio-grgpio.c +12 -11
@@ -328,6 +328,7 @@ static const struct irq_domain_ops grgpio_irq_domain_ops = {static int grgpio_probe (struct platform_device *ofdev) {struct device_node *np = ofdev->dev.of_node; +struct device *dev = &ofdev->dev;void __iomem *regs;struct gpio_chip *gc;struct grgpio_priv *priv;
@@ -337,7 +338,7 @@ static int grgpio_probe(struct platform_device *ofdev)int size;int i; - priv =devm_kzalloc (&ofdev->dev,sizeof (*priv),GFP_KERNEL ); + priv =devm_kzalloc (dev,sizeof (*priv),GFP_KERNEL );if (!priv)return -ENOMEM ;
@@ -346,29 +347,29 @@ static int grgpio_probe(struct platform_device *ofdev)return PTR_ERR (regs); gc = &priv->gc; - err =bgpio_init (gc, &ofdev->dev,4 , regs +GRGPIO_DATA , + err =bgpio_init (gc, dev,4 , regs +GRGPIO_DATA , regs +GRGPIO_OUTPUT ,NULL , regs +GRGPIO_DIR ,NULL ,BGPIOF_BIG_ENDIAN_BYTE_ORDER );if (err) { -dev_err (&ofdev->dev,"bgpio_init() failed\n" ); +dev_err (dev,"bgpio_init() failed\n" );return err; } priv->regs = regs; priv->imask = gc->read_reg (regs +GRGPIO_IMASK ); - priv->dev = &ofdev->dev; + priv->dev = dev; gc->of_node = np; gc->owner =THIS_MODULE ; gc->to_irq = grgpio_to_irq; - gc->label =devm_kasprintf (&ofdev->dev,GFP_KERNEL ,"%pOF" , np); + gc->label =devm_kasprintf (dev,GFP_KERNEL ,"%pOF" , np); gc->base =-1 ; err =of_property_read_u32 (np,"nbits" , &prop);if (err || prop <=0 || prop >GRGPIO_MAX_NGPIO ) { gc->ngpio =GRGPIO_MAX_NGPIO ; -dev_dbg (&ofdev->dev, -"No or invalid nbits property: assume %d\n" , gc->ngpio); +dev_dbg (dev,"No or invalid nbits property: assume %d\n" , + gc->ngpio); }else { gc->ngpio = prop; }
@@ -380,7 +381,7 @@ static int grgpio_probe(struct platform_device *ofdev) irqmap = (s32 *)of_get_property (np,"irqmap" , &size);if (irqmap) {if (size < gc->ngpio) { -dev_err (&ofdev->dev, +dev_err (dev,"irqmap shorter than ngpio (%d < %d)\n" , size, gc->ngpio);return -EINVAL ;
@@ -390,7 +391,7 @@ static int grgpio_probe(struct platform_device *ofdev) &grgpio_irq_domain_ops, priv);if (!priv->domain) { -dev_err (&ofdev->dev,"Could not add irq domain\n" ); +dev_err (dev,"Could not add irq domain\n" );return -EINVAL ; }
@@ -420,13 +421,13 @@ static int grgpio_probe(struct platform_device *ofdev) err =gpiochip_add_data (gc, priv);if (err) { -dev_err (&ofdev->dev,"Could not add gpiochip\n" ); +dev_err (dev,"Could not add gpiochip\n" );if (priv->domain)irq_domain_remove (priv->domain);return err; } -dev_info (&ofdev->dev,"regs=0x%p, base=%d, ngpio=%d, irqs=%s\n" , +dev_info (dev,"regs=0x%p, base=%d, ngpio=%d, irqs=%s\n" , priv->regs, gc->base, gc->ngpio, priv->domain ?"on" :"off" );return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 427/565 gpio: grgpio: Add NULL check in grgpio_probe
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Charles Han <[email protected]>
[ Upstream commit 050b23d081da0f29474de043e9538c1f7a351b3b ]
devm_kasprintf() can return a NULL pointer on failure,but this returned value in grgpio_probe is not checked.
Add NULL check in grgpio_probe, to handle kernel NULL pointer dereference error.
--- drivers/gpio/gpio-grgpio.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpio/gpio-grgpio.c +3 -0
@@ -363,6 +363,9 @@ static int grgpio_probe(struct platform_device *ofdev) gc->owner =THIS_MODULE ; gc->to_irq = grgpio_to_irq; gc->label =devm_kasprintf (dev,GFP_KERNEL ,"%pOF" , np); +if (!gc->label) +return -ENOMEM ; + gc->base =-1 ; err =of_property_read_u32 (np,"nbits" , &prop);
Signature · 1 line
2.43.0