From: Lianqin Hu <hulianqin(a)vivo.com>
stable inclusion
from stable-v6.6.67
commit 8ca07a3d18f39b1669927ef536e485787e856df6
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBEAO8
CVE: CVE-2024-56670
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit 4cfbca86f6a8b801f3254e0e3c8f2b1d2d64be2b upstream.
Considering that in some extreme cases,
when u_serial driver is accessed by multiple threads,
Thread A is executing the open operation and calling the gs_open,
Thread B is executing the disconnect operation and calling the
gserial_disconnect function,The port->port_usb pointer will be set to NULL.
E.g.
Thread A Thread B
gs_open() gadget_unbind_driver()
gs_start_io() composite_disconnect()
gs_start_rx() gserial_disconnect()
... ...
spin_unlock(&port->port_lock)
status = usb_ep_queue() spin_lock(&port->port_lock)
spin_lock(&port->port_lock) port->port_usb = NULL
gs_free_requests(port->port_usb->in) spin_unlock(&port->port_lock)
Crash
This causes thread A to access a null pointer (port->port_usb is null)
when calling the gs_free_requests function, causing a crash.
If port_usb is NULL, the release request will be skipped as it
will be done by gserial_disconnect.
So add a null pointer check to gs_start_io before attempting
to access the value of the pointer port->port_usb.
Call trace:
gs_start_io+0x164/0x25c
gs_open+0x108/0x13c
tty_open+0x314/0x638
chrdev_open+0x1b8/0x258
do_dentry_open+0x2c4/0x700
vfs_open+0x2c/0x3c
path_openat+0xa64/0xc60
do_filp_open+0xb8/0x164
do_sys_openat2+0x84/0xf0
__arm64_sys_openat+0x70/0x9c
invoke_syscall+0x58/0x114
el0_svc_common+0x80/0xe0
do_el0_svc+0x1c/0x28
el0_svc+0x38/0x68
Fixes: c1dca562be8a ("usb gadget: split out serial core")
Cc: stable(a)vger.kernel.org
Suggested-by: Prashanth K <quic_prashk(a)quicinc.com>
Signed-off-by: Lianqin Hu <hulianqin(a)vivo.com>
Acked-by: Prashanth K <quic_prashk(a)quicinc.com>
Link: https://lore.kernel.org/r/TYUPR06MB62178DC3473F9E1A537DCD02D2362@TYUPR06MB6…
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Liu Mingrui <liumingrui(a)huawei.com>
---
drivers/usb/gadget/function/u_serial.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c
index 8962f96ae729..729b0472bab0 100644
--- a/drivers/usb/gadget/function/u_serial.c
+++ b/drivers/usb/gadget/function/u_serial.c
@@ -575,9 +575,12 @@ static int gs_start_io(struct gs_port *port)
* we didn't in gs_start_tx() */
tty_wakeup(port->port.tty);
} else {
- gs_free_requests(ep, head, &port->read_allocated);
- gs_free_requests(port->port_usb->in, &port->write_pool,
- &port->write_allocated);
+ /* Free reqs only if we are still connected */
+ if (port->port_usb) {
+ gs_free_requests(ep, head, &port->read_allocated);
+ gs_free_requests(port->port_usb->in, &port->write_pool,
+ &port->write_allocated);
+ }
status = -EIO;
}
--
2.25.1
From: Dan Carpenter <dan.carpenter(a)linaro.org>
stable inclusion
from stable-v6.6.67
commit 325cf73a1b449fea3158ab99d03a7a717aad1618
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBEAMV
CVE: CVE-2024-56660
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git/commit/?id=325c…
--------------------------------
[ Upstream commit 11776cff0b563c8b8a4fa76cab620bfb633a8cb8 ]
The dr_domain_add_vport_cap() function generally returns NULL on error
but sometimes we want it to return ERR_PTR(-EBUSY) so the caller can
retry. The problem here is that "ret" can be either -EBUSY or -ENOMEM
and if it's and -ENOMEM then the error pointer is propogated back and
eventually dereferenced in dr_ste_v0_build_src_gvmi_qpn_tag().
Fixes: 11a45def2e19 ("net/mlx5: DR, Add support for SF vports")
Signed-off-by: Dan Carpenter <dan.carpenter(a)linaro.org>
Reviewed-by: Tariq Toukan <tariqt(a)nvidia.com>
Link: https://patch.msgid.link/07477254-e179-43e2-b1b3-3b9db4674195@stanley.mount…
Signed-off-by: Jakub Kicinski <kuba(a)kernel.org>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Wang Wensheng <wangwensheng4(a)huawei.com>
---
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_domain.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_domain.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_domain.c
index 3d74109f8230..49f22cad92bf 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_domain.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_domain.c
@@ -297,7 +297,9 @@ dr_domain_add_vport_cap(struct mlx5dr_domain *dmn, u16 vport)
if (ret) {
mlx5dr_dbg(dmn, "Couldn't insert new vport into xarray (%d)\n", ret);
kvfree(vport_caps);
- return ERR_PTR(ret);
+ if (ret == -EBUSY)
+ return ERR_PTR(-EBUSY);
+ return NULL;
}
return vport_caps;
--
2.22.0
From: Wei Fang <wei.fang(a)nxp.com>
stable inclusion
from stable-v6.6.66
commit 66127f0d1ecf00604aeab71132bde398fd9ec7c9
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBEAO0
CVE: CVE-2024-56649
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit b2420b8c81ec674552d00c55d46245e5c184b260 ]
Both ENETC PF and VF drivers share enetc_setup_tc_mqprio() to configure
MQPRIO. And enetc_setup_tc_mqprio() calls enetc_change_preemptible_tcs()
to configure preemptible TCs. However, only PF is able to configure
preemptible TCs. Because only PF has related registers, while VF does not
have these registers. So for VF, its hw->port pointer is NULL. Therefore,
VF will access an invalid pointer when accessing a non-existent register,
which will cause a crash issue. The simplified log is as follows.
root@ls1028ardb:~# tc qdisc add dev eno0vf0 parent root handle 100: \
mqprio num_tc 4 map 0 0 1 1 2 2 3 3 queues 1@0 1@1 1@2 1@3 hw 1
[ 187.290775] Unable to handle kernel paging request at virtual address 0000000000001f00
[ 187.424831] pc : enetc_mm_commit_preemptible_tcs+0x1c4/0x400
[ 187.430518] lr : enetc_mm_commit_preemptible_tcs+0x30c/0x400
[ 187.511140] Call trace:
[ 187.513588] enetc_mm_commit_preemptible_tcs+0x1c4/0x400
[ 187.518918] enetc_setup_tc_mqprio+0x180/0x214
[ 187.523374] enetc_vf_setup_tc+0x1c/0x30
[ 187.527306] mqprio_enable_offload+0x144/0x178
[ 187.531766] mqprio_init+0x3ec/0x668
[ 187.535351] qdisc_create+0x15c/0x488
[ 187.539023] tc_modify_qdisc+0x398/0x73c
[ 187.542958] rtnetlink_rcv_msg+0x128/0x378
[ 187.547064] netlink_rcv_skb+0x60/0x130
[ 187.550910] rtnetlink_rcv+0x18/0x24
[ 187.554492] netlink_unicast+0x300/0x36c
[ 187.558425] netlink_sendmsg+0x1a8/0x420
[ 187.606759] ---[ end trace 0000000000000000 ]---
In addition, some PFs also do not support configuring preemptible TCs,
such as eno1 and eno3 on LS1028A. It won't crash like it does for VFs,
but we should prevent these PFs from accessing these unimplemented
registers.
Fixes: 827145392a4a ("net: enetc: only commit preemptible TCs to hardware when MM TX is active")
Signed-off-by: Wei Fang <wei.fang(a)nxp.com>
Suggested-by: Vladimir Oltean <vladimir.oltean(a)nxp.com>
Reviewed-by: Frank Li <Frank.Li(a)nxp.com>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Li Huafei <lihuafei1(a)huawei.com>
---
drivers/net/ethernet/freescale/enetc/enetc.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
index c17b9e338516..87b27bd7a13b 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc.c
@@ -28,6 +28,9 @@ EXPORT_SYMBOL_GPL(enetc_port_mac_wr);
static void enetc_change_preemptible_tcs(struct enetc_ndev_priv *priv,
u8 preemptible_tcs)
{
+ if (!(priv->si->hw_features & ENETC_SI_F_QBU))
+ return;
+
priv->preemptible_tcs = preemptible_tcs;
enetc_mm_commit_preemptible_tcs(priv);
}
--
2.25.1
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IBAFF1
--------------------------------
Unlinking file may cause the following deadlock in state manager:
[root@localhost test]# cat /proc/2943/stack
[<0>] rpc_wait_bit_killable+0x1a/0x90
[<0>] _nfs4_proc_delegreturn+0x60f/0x760
[<0>] nfs4_proc_delegreturn+0x13d/0x2a0
[<0>] nfs_do_return_delegation+0xba/0x110
[<0>] nfs_end_delegation_return+0x32c/0x620
[<0>] nfs_complete_unlink+0xc7/0x290
[<0>] nfs_dentry_iput+0x36/0x50
[<0>] __dentry_kill+0xaa/0x250
[<0>] dput.part.0+0x26c/0x4d0
[<0>] __put_nfs_open_context+0x1d9/0x260
[<0>] nfs4_open_reclaim+0x77/0xa0
[<0>] nfs4_do_reclaim+0x385/0xf40
[<0>] nfs4_state_manager+0x762/0x14e0
[<0>] nfs4_run_state_manager+0x181/0x330
[<0>] kthread+0x1a7/0x1f0
[<0>] ret_from_fork+0x34/0x60
[<0>] ret_from_fork_asm+0x1a/0x30
[root@localhost test]#
It can be reproduced by following steps:
1) client: open file
2) client: unlink file
3) server: service restart(trigger state manager in client)
4) client: close file(in nfs4_open_reclaim, between nfs4_do_open_reclaim
and put_nfs_open_context)
Since the file has been open, unlinking will just set DCACHE_NFSFS_RENAMED
for the dentry like this:
nfs_unlink
nfs_sillyrename
nfs_async_unlink
// set DCACHE_NFSFS_RENAMED
Restarting service will trigger state manager in client.
(1) NFS4_SLOT_TBL_DRAINING will be set to nfs4_slot_table since session
has been reset.
(2) DCACHE_NFSFS_RENAMED is detected in nfs_dentry_iput. Therefore,
nfs_complete_unlink is called to trigger delegation return.
(3) Due to the slot table being in draining state and sa_privileged being
0, the delegation return will be queued and wait.
nfs4_state_manager
nfs4_reset_session
nfs4_begin_drain_session
nfs4_drain_slot_tbl
// set NFS4_SLOT_TBL_DRAINING (1)
nfs4_do_reclaim
nfs4_open_reclaim
__put_nfs_open_context
__dentry_kill
nfs_dentry_iput // check DCACHE_NFSFS_RENAMED (2)
nfs_complete_unlink
nfs_end_delegation_return
nfs_do_return_delegation
nfs4_proc_delegreturn
_nfs4_proc_delegreturn
rpc_run_task
...
nfs4_delegreturn_prepare
nfs4_setup_sequence
nfs4_slot_tbl_draining // check NFS4_SLOT_TBL_DRAINING
// and sa_privileged is 0 (3)
rpc_sleep_on // set queued and add to slot_tbl_waitq
// rpc_task is async and wait in __rpc_execute
rpc_wait_for_completion_task
__rpc_wait_for_completion_task
out_of_line_wait_on_bit
rpc_wait_bit_killable // wait for rpc_task to complete
<-------- can not get here to wake up rpc_task -------->
nfs4_end_drain_session
nfs4_end_drain_slot_table
nfs41_wake_slot_table
On the one hand, the state manager is blocked by the unfinished delegation
return. As a result, nfs4_end_drain_session cannot be invoked to clear
NFS4_SLOT_TBL_DRAINING and wake up waiting tasks.
On the other hand, since NFS4_SLOT_TBL_DRAINING is not cleared,
delegation return can only wait in the queue, resulting in a deadlock.
Fix it by turning the delegation return into a privileged operation for
the case where the nfs_client is in NFS4CLNT_RECLAIM_REBOOT state.
Fixes: 977fcc2b0b41 ("NFS: Add a delegation return into nfs4_proc_unlink_setup()")
Signed-off-by: Li Lingfeng <lilingfeng3(a)huawei.com>
---
fs/nfs/nfs4proc.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 5985f326550e..282e5559b176 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -6295,7 +6295,8 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
data->lr.roc = false;
}
- if (!data->inode)
+ if (!data->inode ||
+ test_bit(NFS4CLNT_RECLAIM_REBOOT, &server->nfs_client->cl_state))
nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 1,
1);
else
--
2.31.1