5.15.217-rc1 review
Subsystems (2)
Greg Kroah-Hartman
maintainerPATCH 217/272 super: fix emergency thaw deadlock on frozen block devices
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <[email protected]>
[ Upstream commit 749d7aa0377aae32af8c0a4ad43371e7bf830ab5 ]
do_thaw_all_callback() calls bdev_thaw() while holding sb->s_umount exclusively. If the block device was frozen via bdev_freeze() dropping the last block layer freeze reference calls fs_bdev_thaw() which reacquires s_umount:
do_thaw_all_callback(sb)
super_lock_excl(sb) # holds sb->s_umount
bdev_thaw(sb->s_bdev)
mutex_lock(&bdev->bd_fsfreeze_mutex)
# bd_fsfreeze_count drops 1 -> 0
bd_holder_ops->thaw == fs_bdev_thaw
get_bdev_super(bdev)
bdev_super_lock(bdev, true)
super_lock(sb, true)
down_write(&sb->s_umount) # same task: deadlockThe emergency thaw worker deadlocks against itself holding both s_umount and bd_fsfreeze_mutex. That fscks any subsequent unmount, freeze, or thaw of that filesystem and block device.
[ 81.878470] sysrq: Show Blocked State [ 81.880140] task:kworker/0:1 state:D stack:0 pid:11 tgid:11 ppid:2 task_flags:0x4208060 flags:0x00080000 [ 81.884876] Workqueue: events do_thaw_all [ 81.886656] Call Trace: [ 81.887759] <TASK> [ 81.888763] __schedule+0x579/0x1420 [ 81.890372] schedule+0x3a/0x100 [ 81.891794] schedule_preempt_disabled+0x15/0x30 [ 81.893848] rwsem_down_write_slowpath+0x1ea/0x900 [ 81.895191] ? __pfx_do_thaw_all_callback+0x10/0x10 [ 81.896528] down_write+0xbd/0xc0 [ 81.897505] super_lock+0x91/0x180 [ 81.898457] ? __mutex_lock+0xa99/0x1140 [ 81.900748] ? __mutex_unlock_slowpath+0x1f/0x400 [ 81.902069] bdev_super_lock+0x5b/0x150 [ 81.903132] get_bdev_super+0x10/0x60 [ 81.904042] fs_bdev_thaw+0x23/0xf0 [ 81.904755] bdev_thaw+0x82/0x100 [ 81.905484] do_thaw_all_callback+0x2c/0x50 [ 81.906298] __iterate_supers+0x5d/0x130 [ 81.907067] do_thaw_all+0x20/0x40 [ 81.907739] process_one_work+0x206/0x5e0 [ 81.908545] worker_thread+0x1e2/0x3c0 [ 81.909339] ? __pfx_worker_thread+0x10/0x10 [ 81.910171] kthread+0xf4/0x130 [ 81.910799] ? __pfx_kthread+0x10/0x10 [ 81.911528] ret_from_fork+0x2e2/0x3b0 [ 81.912259] ? __pfx_kthread+0x10/0x10 [ 81.913010] ret_from_fork_asm+0x1a/0x30 [ 81.913806] </TASK>
bdev_super_lock() even documents the violated requirement with lockdep_assert_not_held(&sb->s_umount).
Acquiring bd_fsfreeze_mutex under s_umount also inverts the bd_fsfreeze_mutex vs. s_umount ordering established by bdev_{freeze,thaw}() and can thus ABBA against a concurrent block-layer freeze even when the recursive path isn't hit.
Fix this by not holding s_umount around the bdev_thaw() loop at all. Pin the superblock with an active reference instead as filesystems_freeze_callback() does. The active reference keeps the superblock from being shut down and so ->s_bdev stays valid without holding s_umount. The block-layer-held freeze is dropped by fs_bdev_thaw() with FREEZE_MAY_NEST | FREEZE_HOLDER_USERSPACE exactly as a regular unfreeze would and thaw_super_locked() handles filesystem-level freezes as before.
The emergency thaw path has deadlocked like this in one form or another for a long long time but the current exclusively-held shape dates back to commit [1] where thaw_bdev() already ended in thaw_super() with s_umount held by do_thaw_all_callback().
--- fs/super.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-)
fs/super.c +15 -4
@@ -1006,13 +1006,24 @@ void emergency_remount(void)static void do_thaw_all_callback (struct super_block *sb) { +bool active = false; + +down_write (&sb->s_umount); +if (sb->s_root && sb->s_flags &SB_BORN ) + active =atomic_inc_not_zero (&sb->s_active); +up_write (&sb->s_umount); +if (!active) +return ; + +/* thaw_bdev() acquires s_umount so it must not be held here */ +emergency_thaw_bdev (sb); +down_write (&sb->s_umount); -if (sb->s_root && sb->s_flags &SB_BORN ) { -emergency_thaw_bdev (sb); +if (sb->s_root && sb->s_flags &SB_BORN )thaw_super_locked (sb); - }else { +else up_write (&sb->s_umount); - } +deactivate_super (sb); }static void do_thaw_all (struct work_struct *work)
Greg Kroah-Hartman
maintainerPATCH 218/272 ksmbd: rename smb2_get_msg to smb_get_msg
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <[email protected]>
[ Upstream commit 0b444cfd8b74ebce421ccd96eac9c495e536c92e ]
With the removal of the RFC1002 length field from the SMB header, smb2_get_msg is now used to get the smb1 request from the request buffer. Since this function is no longer exclusive to smb2 and now supports smb1 as well, This patch rename it to smb_get_msg to better reflect its usage.
Stable-dep-of: cfc0b8e5080a ("ksmbd: validate minimum PDU size for transform requests")
--- fs/ksmbd/auth.c | 4 +- fs/ksmbd/connection.c | 2 - fs/ksmbd/oplock.c | 8 ++--- fs/ksmbd/smb2pdu.c | 70 +++++++++++++++++++++++++------------------------- fs/ksmbd/smb2pdu.h | 9 ------ fs/ksmbd/smb_common.c | 6 ++-- fs/ksmbd/smb_common.h | 9 ++++++ 7 files changed, 54 insertions(+), 54 deletions(-)
fs/ksmbd/auth.c +2 -2
@@ -920,7 +920,7 @@ int ksmbd_gen_preauth_integrity_hash(str __u8 *pi_hash) {int rc; -struct smb2_hdr *rcv_hdr =smb2_get_msg (buf); +struct smb2_hdr *rcv_hdr =smb_get_msg (buf);char *all_bytes_msg = (char *)&rcv_hdr->ProtocolId;int msg_size =get_rfc1002_len (buf);struct ksmbd_crypto_ctx *ctx =NULL ;
@@ -1107,7 +1107,7 @@ int ksmbd_crypt_message(struct ksmbd_wor unsigned int nvec, int enc) {struct ksmbd_conn *conn = work->conn; -struct smb2_transform_hdr *tr_hdr =smb2_get_msg (iov[0 ].iov_base); +struct smb2_transform_hdr *tr_hdr =smb_get_msg (iov[0 ].iov_base);unsigned int assoc_data_len =sizeof (struct smb2_transform_hdr ) -20 ;int rc;DECLARE_CRYPTO_WAIT (wait);
fs/ksmbd/connection.c +1 -1
@@ -396,7 +396,7 @@ int ksmbd_conn_handler_loop(void *p)if (!ksmbd_smb_request (conn))break ; -if (((struct smb2_hdr *)smb2_get_msg (conn->request_buf))->ProtocolId == +if (((struct smb2_hdr *)smb_get_msg (conn->request_buf))->ProtocolId ==SMB2_PROTO_NUMBER ) {if (pdu_size <SMB2_MIN_SUPPORTED_HEADER_SIZE )break ;
fs/ksmbd/oplock.c +4 -4
@@ -656,7 +656,7 @@ static void __smb2_oplock_break_noti(str goto out; } - rsp_hdr =smb2_get_msg (work->response_buf); + rsp_hdr =smb_get_msg (work->response_buf);memset (rsp_hdr,0 ,sizeof (struct smb2_hdr ) +2 ); rsp_hdr->ProtocolId =SMB2_PROTO_NUMBER ; rsp_hdr->StructureSize =SMB2_HEADER_STRUCTURE_SIZE ;
@@ -670,7 +670,7 @@ static void __smb2_oplock_break_noti(str rsp_hdr->SessionId =0 ;memset (rsp_hdr->Signature,0 ,16 ); - rsp =smb2_get_msg (work->response_buf); + rsp =smb_get_msg (work->response_buf); rsp->StructureSize =cpu_to_le16 (24 ); if (!br_info->open_trunc &&
@@ -760,7 +760,7 @@ static void __smb2_lease_break_noti(stru goto out; } - rsp_hdr =smb2_get_msg (work->response_buf); + rsp_hdr =smb_get_msg (work->response_buf);memset (rsp_hdr,0 ,sizeof (struct smb2_hdr ) +2 ); rsp_hdr->ProtocolId =SMB2_PROTO_NUMBER ; rsp_hdr->StructureSize =SMB2_HEADER_STRUCTURE_SIZE ;
@@ -774,7 +774,7 @@ static void __smb2_lease_break_noti(stru rsp_hdr->SessionId =0 ;memset (rsp_hdr->Signature,0 ,16 ); - rsp =smb2_get_msg (work->response_buf); + rsp =smb_get_msg (work->response_buf); rsp->StructureSize =cpu_to_le16 (44 ); rsp->Epoch = br_info->epoch; rsp->Flags =0 ;
fs/ksmbd/smb2pdu.c +35 -35
240 lines not on this page · raw message
fs/ksmbd/smb2pdu.h +0 -9
@@ -1704,13 +1704,4 @@ int smb2_ioctl(struct ksmbd_work *work);int smb2_oplock_break (struct ksmbd_work *work);int smb2_notify (struct ksmbd_work *ksmbd_work); -/* -* Get the body of the smb2 message excluding the 4 byte rfc1002 headers -* from request/response buffer. -*/ -static inline void *smb2_get_msg (void *buf) -{ -return buf +4 ; -} -#endif /* _SMB2PDU_H */
fs/ksmbd/smb_common.c +3 -3
@@ -163,7 +163,7 @@ bool ksmbd_smb_request(struct ksmbd_connif (conn->request_buf[0 ] !=0 )return false; - proto = (__le32 *)smb2_get_msg (conn->request_buf); + proto = (__le32 *)smb_get_msg (conn->request_buf);if (*proto ==SMB2_COMPRESSION_TRANSFORM_ID ) {pr_err_ratelimited ("smb2 compression not support yet" );return false;
@@ -259,14 +259,14 @@ int ksmbd_lookup_dialect_by_id(__le16 *cstatic int ksmbd_negotiate_smb_dialect (void *buf) {int smb_buf_length =get_rfc1002_len (buf); -__le32 proto = ((struct smb2_hdr *)smb2_get_msg (buf))->ProtocolId; +__le32 proto = ((struct smb2_hdr *)smb_get_msg (buf))->ProtocolId;if (proto ==SMB2_PROTO_NUMBER ) {struct smb2_negotiate_req *req;int smb2_neg_size = offsetof(struct smb2_negotiate_req , Dialects); - req = (struct smb2_negotiate_req *)smb2_get_msg (buf); + req = (struct smb2_negotiate_req *)smb_get_msg (buf);if (smb2_neg_size > smb_buf_length) goto err_out;
fs/ksmbd/smb_common.h +9 -0
@@ -512,4 +512,13 @@ static inline void inc_rfc1001_len(void {be32_add_cpu ((__be32 *)buf, count); } + +/* +* Get the body of the smb message excluding the 4 byte rfc1002 headers +* from request/response buffer. +*/ +static inline void *smb_get_msg (void *buf) +{ +return buf +4 ; +}#endif /* __SMB_COMMON_H__ */
Greg Kroah-Hartman
maintainerPATCH 219/272 smb/server: fix minimum SMB1 PDU size
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 3b9c30eb8f5aaad4a54cdfa470b74c0467cc71e8 ]
Since the RFC1002 header has been removed from struct smb_hdr, the minimum SMB1 PDU size should be updated as well.
Stable-dep-of: cfc0b8e5080a ("ksmbd: validate minimum PDU size for transform requests")
--- fs/ksmbd/connection.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
fs/ksmbd/connection.c +3 -2
@@ -305,7 +305,8 @@ bool ksmbd_conn_alive(struct ksmbd_connreturn true; } -#define SMB1_MIN_SUPPORTED_HEADER_SIZE (sizeof(struct smb_hdr)) +/* "+2" for BCC field (ByteCount, 2 bytes) */ +#define SMB1_MIN_SUPPORTED_PDU_SIZE (sizeof(struct smb_hdr) + 2)#define SMB2_MIN_SUPPORTED_HEADER_SIZE (sizeof(struct smb2_hdr) + 4)/**
@@ -365,7 +366,7 @@ int ksmbd_conn_handler_loop(void *p)if (pdu_size >MAX_STREAM_PROT_LEN )break ; -if (pdu_size <SMB1_MIN_SUPPORTED_HEADER_SIZE ) +if (pdu_size <SMB1_MIN_SUPPORTED_PDU_SIZE )break ;/* 4 for rfc1002 length field */
Greg Kroah-Hartman
maintainerPATCH 220/272 smb/server: fix minimum SMB2 PDU size
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 4c7d8eb9a79ae5400eac19c4f6f0815bff674452 ]
The minimum SMB2 PDU size should be updated to the size of struct smb2_pdu (that is, the size of struct smb2_hdr + 2).
Stable-dep-of: cfc0b8e5080a ("ksmbd: validate minimum PDU size for transform requests")
--- fs/ksmbd/connection.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/ksmbd/connection.c +2 -2
@@ -307,7 +307,7 @@ bool ksmbd_conn_alive(struct ksmbd_conn/* "+2" for BCC field (ByteCount, 2 bytes) */ #define SMB1_MIN_SUPPORTED_PDU_SIZE (sizeof(struct smb_hdr) + 2) -#define SMB2_MIN_SUPPORTED_HEADER_SIZE (sizeof(struct smb2_hdr) + 4) +#define SMB2_MIN_SUPPORTED_PDU_SIZE (sizeof(struct smb2_pdu))/** * ksmbd_conn_handler_loop() - session thread to listen on new smb requests
@@ -399,7 +399,7 @@ int ksmbd_conn_handler_loop(void *p)if (((struct smb2_hdr *)smb_get_msg (conn->request_buf))->ProtocolId ==SMB2_PROTO_NUMBER ) { -if (pdu_size <SMB2_MIN_SUPPORTED_HEADER_SIZE ) +if (pdu_size <SMB2_MIN_SUPPORTED_PDU_SIZE )break ; }
Greg Kroah-Hartman
maintainerPATCH 221/272 ksmbd: validate minimum PDU size for transform requests
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <[email protected]>
[ Upstream commit cfc0b8e5080aec87700774e8568765eaa4b7b92b ]
The receive path applies the minimum SMB2 PDU size check only when ProtocolId is SMB2_PROTO_NUMBER. A packet carrying SMB2_TRANSFORM_PROTO_NUM bypasses the check even when the negotiated dialect does not provide transform handling.
On an SMB 2.1 connection, a short transform packet therefore reaches init_smb2_rsp_hdr(), which interprets the request as a full SMB2 header and reads beyond the request allocation. The copied fields can then be returned to the unauthenticated client.
Compression transforms are converted to ordinary SMB2 messages before protocol validation. After that conversion, validate ordinary SMB2 requests against SMB2_MIN_SUPPORTED_PDU_SIZE and require encryption transform requests to contain both a transform header and an SMB2 header. This rejects truncated requests before work allocation.
--- fs/ksmbd/connection.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
fs/ksmbd/connection.c +11 -5
@@ -308,6 +308,8 @@ bool ksmbd_conn_alive(struct ksmbd_conn/* "+2" for BCC field (ByteCount, 2 bytes) */ #define SMB1_MIN_SUPPORTED_PDU_SIZE (sizeof(struct smb_hdr) + 2)#define SMB2_MIN_SUPPORTED_PDU_SIZE (sizeof(struct smb2_pdu)) +#define SMB2_TRANSFORM_MIN_SUPPORTED_PDU_SIZE \ + (sizeof(struct smb2_transform_hdr) + sizeof(struct smb2_hdr))/** * ksmbd_conn_handler_loop() - session thread to listen on new smb requests
@@ -322,6 +324,7 @@ int ksmbd_conn_handler_loop(void *p)struct ksmbd_conn *conn = (struct ksmbd_conn *)p;struct ksmbd_transport *t = conn->transport;unsigned int pdu_size, max_allowed_pdu_size; +__le32 proto;char hdr_buf[4 ] = {0 ,};int size;
@@ -397,11 +400,14 @@ int ksmbd_conn_handler_loop(void *p)if (!ksmbd_smb_request (conn))break ; -if (((struct smb2_hdr *)smb_get_msg (conn->request_buf))->ProtocolId == -SMB2_PROTO_NUMBER ) { -if (pdu_size <SMB2_MIN_SUPPORTED_PDU_SIZE ) -break ; - } + proto = *(__le32 *)smb_get_msg (conn->request_buf); +if (proto ==SMB2_PROTO_NUMBER && + pdu_size <SMB2_MIN_SUPPORTED_PDU_SIZE ) +break ; + +if (proto ==SMB2_TRANSFORM_PROTO_NUM && + pdu_size <SMB2_TRANSFORM_MIN_SUPPORTED_PDU_SIZE ) +break ;if (!default_conn_ops.process_fn) {pr_err ("No connection request callback\n" );
Greg Kroah-Hartman
maintainerPATCH 222/272 mm/vmstat: fold stranded per-cpu node stats when a node comes online
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gregory Price <[email protected]>
[ Upstream commit ea3034b2b00fa50c8d2518d0804c9d427bbafa86 ]
A per-node vmstat counter is pgdat->vm_stat[] plus per-cpu deltas. A balanced counter can sit split as global=+N / per-cpu=-N.
The folds reconciling the split only walk online nodes, so when try_offline_node() marks a node offline the per-cpu deltas are stranded.
A subsequent online resets the per-cpu area but not pgdat->vm_stat[], orphaning the +N permanently. All NR_VM_NODE_STAT_ITEMS are affected.
The existing code zeroes the per-cpu counters and causes a permanent skew. Fold the stranded deltas instead, before the node rejoins the online set. The node is not online yet and the hotplug lock is held, so the remote access to per-cpu values is safe.
Discovered when node compaction hung for a nearly empty node, as the math to determine throttling broke. Reproduced by repeated memory hotplug/unplug cycles on a node under pressure: NR_ISOLATED_ANON ratchets up and never returns to zero.
--- mm/memory_hotplug.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
mm/memory_hotplug.c +11 -4
@@ -1190,7 +1190,7 @@ static pg_data_t __ref *hotadd_new_pgdatalloc_percpu (struct per_cpu_nodestat );arch_refresh_nodedata (nid, pgdat); }else { -int cpu; +int cpu, i;/* * Reset the nr_zones, order and highest_zoneidx before reuse. * Note that kswapd will init kswapd_highest_zoneidx properly
@@ -1199,10 +1199,17 @@ static pg_data_t __ref *hotadd_new_pgdat pgdat->nr_zones =0 ; pgdat->kswapd_order =0 ; pgdat->kswapd_highest_zoneidx =0 ; -for_each_online_cpu (cpu) { -struct per_cpu_nodestat *p; +/* +* Hot-unplug can leave per-cpu vmstat deltas unfolded (folders skip +* offline nodes) - reconcile this at online. Foreign access to counters +* is safe: the node is not online yet and we hold the hotplug lock. +*/ +for_each_possible_cpu (cpu) { +struct per_cpu_nodestat *p =per_cpu_ptr (pgdat->per_cpu_nodestats, cpu); - p =per_cpu_ptr (pgdat->per_cpu_nodestats, cpu); +for (i =0 ; i <NR_VM_NODE_STAT_ITEMS ; i++) +if (p->vm_node_stat_diff[i]) +node_page_state_add (p->vm_node_stat_diff[i], pgdat, i);memset (p,0 ,sizeof (*p)); } }
Greg Kroah-Hartman
maintainerPATCH 223/272 ksmbd: conn lock to serialize smb2 negotiate
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <[email protected]>
[ Upstream commit fe4ed2f09b492e3507615a053814daa8fafdecb1 ]
If client send parallel smb2 negotiate request on same connection, ksmbd_conn can be racy. smb2 negotiate handling that are not performance-related can be serialized with conn lock.
Stable-dep-of: cb469993b3a6 ("ksmbd: reject repeated SMB2 NEGOTIATE requests")
--- fs/ksmbd/smb2pdu.c | 2 ++ 1 file changed, 2 insertions(+)
fs/ksmbd/smb2pdu.c +2 -0
@@ -1126,6 +1126,7 @@ int smb2_handle_negotiate(struct ksmbd_wreturn rc; } +ksmbd_conn_lock (conn); smb2_buf_len =get_rfc1002_len (work->request_buf); smb2_neg_size = offsetof(struct smb2_negotiate_req , Dialects);if (smb2_neg_size > smb2_buf_len) {
@@ -1275,6 +1276,7 @@ int smb2_handle_negotiate(struct ksmbd_wksmbd_conn_set_need_negotiate (conn); err_out: +ksmbd_conn_unlock (conn);if (rc) rsp->hdr.Status =STATUS_INSUFFICIENT_RESOURCES ;
Greg Kroah-Hartman
maintainerPATCH 224/272 ksmbd: reject repeated SMB2 NEGOTIATE requests
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <[email protected]>
[ Upstream commit cb469993b3a61a72653770856d37af616d72d05f ]
Unauthenticated client can send multiple successful SMB2 NEGOTIATE requests on one connection before SESSION_SETUP. While the connection is in KSMBD_SESS_NEED_SETUP, smb2_handle_negotiate() accepts another SMB3.1.1 NEGOTIATE and overwrites conn->preauth_info with a new allocation. Only the final allocation is freed when the connection is released, leaking one object for every additional successful request.
A repeated SMB2 NEGOTIATE after a dialect has been selected is a protocol violation. MS-SMB2 section 3.3.5.4 requires the server to disconnect without replying in this case. Set the connection exiting when rejecting the request, in addition to suppressing the response.
Reject SMB2 NEGOTIATE unless the connection is new or is waiting for the SMB2 NEGOTIATE that follows an SMB1 multi-protocol negotiate. Serialize both SMB1 and SMB2 negotiation paths under conn->srv_mutex, since they update connection-wide dialect and negotiation state.
Move the locking contract to ksmbd_smb_negotiate_common(), where the state and dialect are selected, and add ksmbd_conn_new() for consistent state access.
--- fs/ksmbd/connection.h | 5 +++++ fs/ksmbd/smb2pdu.c | 10 ++-------- fs/ksmbd/smb_common.c | 37 ++++++++++++++++++++++++++++++------- 3 files changed, 37 insertions(+), 15 deletions(-)
fs/ksmbd/connection.h +5 -0
@@ -176,6 +176,11 @@ void ksmbd_conn_unlock(struct ksmbd_conn *conn);* This is a hack. We will move status to a proper place once we land * a multi-sessions support. */ +static inline bool ksmbd_conn_new (struct ksmbd_conn *conn) +{ +return READ_ONCE (conn->status) ==KSMBD_SESS_NEW ; +} +static inline bool ksmbd_conn_good (struct ksmbd_conn *conn) {return READ_ONCE (conn->status) ==KSMBD_SESS_GOOD ;
fs/ksmbd/smb2pdu.c +2 -8
@@ -1107,6 +1107,8 @@ static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn,* smb2_handle_negotiate() - handler for smb2 negotiate command * @work: smb work containing smb request buffer * +* The caller holds conn->srv_mutex. +* * Return: 0 */ int smb2_handle_negotiate (struct ksmbd_work *work)
@@ -1120,13 +1122,6 @@ int smb2_handle_negotiate(struct ksmbd_work *work)ksmbd_debug (SMB ,"Received negotiate request\n" ); conn->need_neg = false; -if (ksmbd_conn_good (conn)) { -pr_err ("conn->tcp_status is already in CifsGood State\n" ); - work->send_no_response =1 ; -return rc; - } - -ksmbd_conn_lock (conn); smb2_buf_len =get_rfc1002_len (work->request_buf); smb2_neg_size = offsetof(struct smb2_negotiate_req , Dialects);if (smb2_neg_size > smb2_buf_len) {
@@ -1276,7 +1271,6 @@ int smb2_handle_negotiate(struct ksmbd_work *work)ksmbd_conn_set_need_negotiate (conn); err_out: -ksmbd_conn_unlock (conn);if (rc) rsp->hdr.Status =STATUS_INSUFFICIENT_RESOURCES ;
fs/ksmbd/smb_common.c +30 -7
@@ -585,23 +585,46 @@ int ksmbd_smb_negotiate_common(struct ksmbd_work *work, unsigned int command)struct ksmbd_conn *conn = work->conn;int ret; - conn->dialect = -ksmbd_negotiate_smb_dialect (work->request_buf); -ksmbd_debug (SMB ,"conn->dialect 0x%x\n" , conn->dialect); -if (command ==SMB2_NEGOTIATE_HE ) { +/* +* An SMB2 NEGOTIATE is valid for a new connection, or after an +* SMB1 multi-protocol negotiate has selected SMB2. Do not allow +* a second SMB2 NEGOTIATE to replace connection-wide state +* while a session setup is pending. KSMBD_SESS_NEED_RECONNECT +* is a transient session state and does not restart transport +* negotiation. +*/ +ksmbd_conn_lock (conn); +if (!ksmbd_conn_new (conn) && + !ksmbd_conn_need_negotiate (conn)) { + work->send_no_response =1 ; +ksmbd_conn_set_exiting (conn); +ksmbd_conn_unlock (conn); +return 0 ; + } + + conn->dialect = +ksmbd_negotiate_smb_dialect (work->request_buf); +ksmbd_debug (SMB ,"conn->dialect 0x%x\n" , conn->dialect); ret =smb2_handle_negotiate (work); +ksmbd_conn_unlock (conn);return ret; }if (command ==SMB_COM_NEGOTIATE ) { +ksmbd_conn_lock (conn); + conn->dialect = +ksmbd_negotiate_smb_dialect (work->request_buf); +ksmbd_debug (SMB ,"conn->dialect 0x%x\n" , conn->dialect);if (__smb2_negotiate (conn)) {init_smb3_11_server (conn); -init_smb2_neg_rsp (work); + ret =init_smb2_neg_rsp (work);ksmbd_debug (SMB ,"Upgrade to SMB2 negotiation\n" ); -return 0 ; + }else { + ret =smb_handle_negotiate (work); } -return smb_handle_negotiate (work); +ksmbd_conn_unlock (conn); +return ret; }pr_err ("Unknown SMB negotiation command: %u\n" , command);
Signature · 1 line
2.53.0
Re: [PATCH 5.15 224/272] ksmbd: reject repeated SMB2 NEGOTIATE requests
Hi Greg/sasha,
Quoted 20 lines · Greg Kroah-Hartman
5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <[email protected]>
[ Upstream commit
cb469993b3a61a72653770856d37af616d72d05f]Unauthenticated client can send multiple successful SMB2 NEGOTIATE requests on one connection before
SESSION_SETUP. While the connection is inKSMBD_SESS_NEED_SETUP,smb2_handle_negotiate()accepts another SMB3.1.1 NEGOTIATE and overwritesconn->preauth_infowith a new allocation. Only the final allocation is freed when the connection is released, leaking one object for every additional successful request.A repeated SMB2 NEGOTIATE after a dialect has been selected is a protocol violation. MS-SMB2 section 3.3.5.4 requires the server to disconnect without replying in this case. Set the connection exiting when rejecting the request, in addition to suppressing the response.
Quoted 5 lines
Reject SMB2 NEGOTIATE unless the connection is new or is waiting for the SMB2 NEGOTIATE that follows an SMB1 multi-protocol negotiate. Serialize both SMB1 and SMB2 negotiation paths under
conn->srv_mutex, since they update connection-wide dialect and negotiation state.
I ran an AI-assisted backport review and then checked the finding against 5.15.y. The repeated SMB2 NEGOTIATE fix in 0b1390cf2b6b is incomplete there.
Upstream, after c8b5b7c5da7d, a successful direct SMB2 negotiation does:
ksmbd_conn_set_need_setup(conn);
and cb469993b3a6 only permits another SMB2 NEGOTIATE for a new connection or the SMB1 hand-off state.
The 5.15 backport instead still does:
ksmbd_conn_set_need_negotiate(conn);
so its new !new && !need_negotiate gate accepts a second direct SMB2
NEGOTIATE. For SMB3.1.1, that reaches another assignment toconn->preauth_info, overwriting the previous allocation, while connection cleanup can free only the final pointer.
I think 5.15.y should take a branch-appropriate backport ofc8b5b7c5da7d0c31c9b7190b4a7bba5281fc4780 ("ksmbd: fix null pointer
dereference in alloc_preauth_hash()"), now that we already this patch merged in 5.15.y, we need to think of a way to do it.
thanks,
Harshit
Quoted 19 lines
Move the locking contract to
ksmbd_smb_negotiate_common(), where the state and dialect are selected, and addksmbd_conn_new()for consistent state access.Fixes e2f34481b24d ("cifsd: add server-side procedures for SMB3")Reported-by Runa Takemoto <[email protected]>Signed-off-by Namjae Jeon <[email protected]>Signed-off-by Steve French <[email protected]>Signed-off-by Sasha Levin <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- fs/ksmbd/connection.h | 5 +++++ fs/ksmbd/smb2pdu.c | 10 ++-------- fs/ksmbd/smb_common.c | 37 ++++++++++++++++++++++++++++++------- 3 files changed, 37 insertions(+), 15 deletions(-)fs/ksmbd/connection.h +0
-0
Sasha Levin
maintainerRe: [PATCH 5.15 224/272] ksmbd: reject repeated SMB2 NEGOTIATE requests
Quoted 6 lines
Upstream, after
c8b5b7c5da7d, a successful direct SMB2 negotiation does:ksmbd_conn_set_need_setup(conn);and
cb469993b3a6only permits another SMB2 NEGOTIATE for a new connection or the SMB1 hand-off state.
Confirmed, and 6.1.y is missing it too. c8b5b7c5da7d needs the same reduction 6.6.y already carries - it doesn't cherry-pick cleanly to either tree.
Signature · 2 lines
Thanks, Sasha
Greg Kroah-Hartman
maintainerPATCH 225/272 wifi: libertas_tf: fix use-after-free in lbtf_free_adapter()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maoyi Xie <[email protected]>
[ Upstream commit aa6dcd5c8dd9ba1d7d0f60093bcda41c0d6d438d ]
lbtf_free_adapter() calls timer_delete(&priv->command_timer), which does not wait for a running command_timer_fn() callback. lbtf_free_adapter() runs on the teardown path right before ieee80211_free_hw() frees priv, both in lbtf_remove_card() and in the probe error path. command_timer is armed by mod_timer() in lbtf_cmd() whenever a firmware command is sent. command_timer_fn() dereferences priv. If a command times out as the device is removed, command_timer_fn() runs concurrently with teardown and dereferences priv after it has been freed.
This is the same use-after-free that commit 03cc8f90d053 ("wifi: libertas:
fix use-after-free in lbs_free_adapter()") fixed in the sibling libertas driver. The libertas_tf variant has the identical pattern and was left unchanged. Use timer_delete_sync() so any in-flight callback completes before priv is freed.
--- drivers/net/wireless/marvell/libertas_tf/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/marvell/libertas_tf/main.c +1 -1
@@ -174,7 +174,7 @@ static void lbtf_free_adapter(struct lbt {lbtf_deb_enter (LBTF_DEB_MAIN );lbtf_free_cmd_buffer (priv); -del_timer (&priv->command_timer); +timer_delete_sync (&priv->command_timer);lbtf_deb_leave (LBTF_DEB_MAIN ); }
Greg Kroah-Hartman
maintainerPATCH 226/272 igc: remove napi_synchronize() in igc_down()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Carlier <[email protected]>
[ Upstream commit 5ffab5b9589c50e4cfc0cf36ffd76c89422d4019 ]
When an AF_XDP zero-copy application is killed abruptly, the XSK pool is torn down but NAPI keeps polling. igc_clean_rx_irq_zc() then returns the full budget on every poll, so napi_complete_done() never clears NAPI_STATE_SCHED.
igc_down() calls napi_synchronize() before napi_disable(), so it spins forever waiting for that bit and the interface never goes down. Drop the napi_synchronize() and let napi_disable() do the job -- it sets NAPI_STATE_DISABLE, which forces the stuck poll to complete. Reorder it ahead of igc_set_queue_napi() so the NAPI mapping is cleared only after polling has stopped, matching the recent igb fix b1e067240379.
--- drivers/net/ethernet/intel/igc/igc_main.c | 1 - 1 file changed, 1 deletion(-)
drivers/net/ethernet/intel/igc/igc_main.c +0 -1
@@ -4980,7 +4980,6 @@ void igc_down(struct igc_adapter *adaptefor (i =0 ; i < adapter->num_q_vectors; i++) {if (adapter->q_vector[i]) { -napi_synchronize (&adapter->q_vector[i]->napi);napi_disable (&adapter->q_vector[i]->napi); } }
Greg Kroah-Hartman
maintainerPATCH 227/272 net: pktgen: fix code style (WARNING: Block comments)
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Seiderer <[email protected]>
[ Upstream commit 870b856cb478bc02fffe4d89897e62c692efb09a ]
Fix checkpatch code style warnings:
WARNING: Block comments use a trailing */ on a separate line
+ * removal by worker thread */
WARNING: Block comments use * on subsequent lines
+ __u8 tos; /* six MSB of (former) IPv4 TOS
+ are for dscp codepoint */
WARNING: Block comments use a trailing */ on a separate line
+ are for dscp codepoint */
WARNING: Block comments use * on subsequent lines
+ __u8 traffic_class; /* ditto for the (former) Traffic Class in IPv6
+ (see RFC 3260, sec. 4) */
WARNING: Block comments use a trailing */ on a separate line
+ (see RFC 3260, sec. 4) */
WARNING: Block comments use * on subsequent lines
+ /* = {
+ 0x00, 0x80, 0xC8, 0x79, 0xB3, 0xCB,
WARNING: Block comments use * on subsequent lines
+ /* Field for thread to receive "posted" events terminate,
+ stop ifs etc. */
WARNING: Block comments use a trailing */ on a separate line
+ stop ifs etc. */
WARNING: Block comments should align the * on each line
+ * we go look for it ...
+*/
WARNING: Block comments use a trailing */ on a separate line
+ * we resolve the dst issue */
WARNING: Block comments use a trailing */ on a separate line
+ * with proc_create_data() */
Stable-dep-of: 817ff6efdb7f ("net: pktgen: fix proc entry use-after-free")
--- net/core/pktgen.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-)
net/core/pktgen.c +23 -16
@@ -284,7 +284,8 @@ struct pktgen_dev {int pkt_overhead;/* overhead for MPLS, VLANs, IPSEC etc */ int nfrags;int removal_mark;/* non-zero => the device is marked for -* removal by worker thread */ +* removal by worker thread +*/ struct page *page;u64 delay;/* nano-seconds */
@@ -347,10 +348,12 @@ struct pktgen_dev {__u16 udp_dst_max;/* exclusive, dest UDP port */ /* DSCP + ECN */ -__u8 tos;/* six MSB of (former) IPv4 TOS -are for dscp codepoint */ -__u8 traffic_class;/* ditto for the (former) Traffic Class in IPv6 -(see RFC 3260, sec. 4) */ +__u8 tos;/* six MSB of (former) IPv4 TOS +* are for dscp codepoint +*/ +__u8 traffic_class;/* ditto for the (former) Traffic Class in IPv6 +* (see RFC 3260, sec. 4) +*/ /* IMIX */ unsigned int n_imix_entries;
@@ -390,12 +393,12 @@ struct pktgen_dev {__u8 hh[14 ];/* = { -0x00, 0x80, 0xC8, 0x79, 0xB3, 0xCB, - -We fill in SRC address later -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x08, 0x00 -}; +* 0x00, 0x80, 0xC8, 0x79, 0xB3, 0xCB, +* +* We fill in SRC address later +* 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +* 0x08, 0x00 +* }; */ __u16 pad;/* pad out the hh struct to an even 16 bytes */
@@ -458,7 +461,8 @@ struct pktgen_thread {char result[512 ];/* Field for thread to receive "posted" events terminate, -stop ifs etc. */ +* stop ifs etc. +*/ u32 control;int cpu;
@@ -2341,7 +2345,7 @@ static inline int f_pick(struct pktgen_d#ifdef CONFIG_XFRM /* If there was already an IPSEC SA, we keep it as is, else * we go look for it ... -*/ +*/ #define DUMMY_MARK 0static void get_ipsec_sa (struct pktgen_dev *pkt_dev,int flow) {
@@ -2646,7 +2650,8 @@ static int pktgen_output_ipsec(struct skif (!x)return 0 ;/* XXX: we dont support tunnel mode for now until -* we resolve the dst issue */ +* we resolve the dst issue +*/ if ((x->props.mode !=XFRM_MODE_TRANSPORT ) && (pkt_dev->spi ==0 ))return 0 ;
@@ -3711,7 +3716,8 @@ static int add_dev_to_thread(struct pktg* userspace on another CPU than the kthread. The if_lock() * is used here to sync with concurrent instances of * _rem_dev_from_if_list() invoked via kthread, which is also -* updating the if_list */ +* updating the if_list +*/ if_lock (t);if (pkt_dev->pg_thread) {
@@ -3908,7 +3914,8 @@ static int pktgen_remove_device(struct p/* Remove proc before if_list entry, because add_device uses * list to determine if interface already exist, avoid race -* with proc_create_data() */ +* with proc_create_data() +*/ proc_remove (pkt_dev->entry);/* And update the thread if_list */
Greg Kroah-Hartman
maintainerPATCH 228/272 net: pktgen: fix proc entry use-after-free
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <[email protected]>
[ Upstream commit 817ff6efdb7f484ea547218e11e17d8e43daa3b4 ]
pktgen_change_name() replaces pkt_dev->entry while holding t->if_lock. pktgen_remove_device() removes the same entry before _rem_dev_from_if_list() takes that lock.
This allows the following interleaving:
CPU 0 (NETDEV_CHANGENAME) CPU 1 (kpktgend)
if_lock(t)
proc_remove(pkt_dev->entry)
proc_remove(pkt_dev->entry)
pkt_dev->entry = proc_create_data(...)
if_unlock(t)
The kthread can pass the stale proc_dir_entry to proc_remove() after the rename path has freed it. A reproducer with a widened race window reports:
BUG: KASAN: slab-use-after-free in proc_remove+0x78/0x80 Read of size 8 at addr ffff8881478fea70 by task kpktgend_0/67 Call Trace: proc_remove+0x78/0x80 pktgen_remove_device.isra.0+0x11c/0x4c0 pktgen_thread_worker+0x1214/0x6bc0 kthread+0x2c6/0x3b0 Allocated by task 95: __proc_create+0x204/0x790 proc_create_data+0x72/0xe0 pktgen_thread_write+0xd61/0x1510 Freed by task 28: kmem_cache_free+0xcb/0x3d0 proc_free_inode+0x5b/0x80 rcu_core+0x50a/0x1850 The buggy address belongs to the object at ffff8881478fea00 which belongs to the cache proc_dir_entry of size 192
Move proc_remove() into the if_lock-protected list removal helper. Keep it before list_del_rcu() to preserve the ordering required by add_device(). The rename path must then finish replacing the entry before removal, or it observes that the device is no longer on the list.
--- net/core/pktgen.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
net/core/pktgen.c +1 -3
@@ -3887,6 +3887,7 @@ static void _rem_dev_from_if_list(structstruct pktgen_dev *p;if_lock (t); +proc_remove (pkt_dev->entry);list_for_each_safe (q, n, &t->if_list) { p = list_entry(q, struct pktgen_dev, list);if (p == pkt_dev)
@@ -3916,9 +3917,6 @@ static int pktgen_remove_device(struct p* list to determine if interface already exist, avoid race * with proc_create_data() */ -proc_remove (pkt_dev->entry); - -/* And update the thread if_list */ _rem_dev_from_if_list (t, pkt_dev);#ifdef CONFIG_XFRM
Greg Kroah-Hartman
maintainerPATCH 229/272 scsi: sd: sd_zbc: Improve source code documentation
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
[ Upstream commit aa96bfb4caff59c93f0637092efe3a714cab0fe6 ]
Add several kernel-doc headers. Declare input arrays const. Specify the array size in function declarations.
Stable-dep-of: 93dde0bf2f39 ("scsi: scsi_debug: Fix REPORT ZONES alloc_len underflow OOB write")
--- drivers/scsi/sd.h | 5 +--- drivers/scsi/sd_zbc.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 54 insertions(+), 6 deletions(-)
drivers/scsi/sd.h +2 -3
@@ -217,7 +217,7 @@ static inline int sd_is_zoned(struct scs#ifdef CONFIG_BLK_DEV_ZONED void sd_zbc_release_disk (struct scsi_disk *sdkp); -int sd_zbc_read_zones (struct scsi_disk *sdkp,unsigned char *buffer); +int sd_zbc_read_zones (struct scsi_disk *sdkp,u8 buf[SD_BUF_SIZE ]);int sd_zbc_revalidate_zones (struct scsi_disk *sdkp);blk_status_t sd_zbc_setup_zone_mgmt_cmnd (struct scsi_cmnd *cmd,unsigned char op,bool all);
@@ -233,8 +233,7 @@ blk_status_t sd_zbc_prepare_zone_append(static inline void sd_zbc_release_disk (struct scsi_disk *sdkp) {} -static inline int sd_zbc_read_zones (struct scsi_disk *sdkp, -unsigned char *buf) +static inline int sd_zbc_read_zones (struct scsi_disk *sdkp,u8 buf[SD_BUF_SIZE ]) {return 0 ; }
drivers/scsi/sd_zbc.c +52 -3
97 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 230/272 scsi: sd: sd_zbc: Use logical blocks as unit when querying zones
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]>
[ Upstream commit 43af5da09efb8abe450ec859d3063adeb7d1eb54 ]
When querying zones, track the position in logical blocks instead of in sectors. This change slightly simplifies sd_zbc_report_zones().
Stable-dep-of: 93dde0bf2f39 ("scsi: scsi_debug: Fix REPORT ZONES alloc_len underflow OOB write")
--- drivers/scsi/sd_zbc.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
drivers/scsi/sd_zbc.c +5 -6
@@ -223,7 +223,7 @@ int sd_zbc_report_zones(struct gendisk * unsigned int nr_zones, report_zones_cb cb, void *data) { struct scsi_disk *sdkp = scsi_disk(disk); -sector_t capacity =logical_to_sectors (sdkp->device, sdkp->capacity); +sector_t lba =sectors_to_logical (sdkp->device, sector);unsigned int nr, i;unsigned char *buf;size_t offset, buflen =0 ;
@@ -234,7 +234,7 @@ int sd_zbc_report_zones(struct gendisk */* Not a zoned device */ return -EOPNOTSUPP ; -if (!capacity) +if (!sdkp->capacity)/* Device gone or invalid */ return -ENODEV ;
@@ -242,9 +242,8 @@ int sd_zbc_report_zones(struct gendisk *if (!buf)return -ENOMEM ; -while (zone_idx < nr_zones && sector < capacity) { - ret =sd_zbc_do_report_zones (sdkp, buf, buflen, -sectors_to_logical (sdkp->device, sector), true); +while (zone_idx < nr_zones && lba < sdkp->capacity) { + ret =sd_zbc_do_report_zones (sdkp, buf, buflen, lba, true);if (ret) goto out;
@@ -262,7 +261,7 @@ int sd_zbc_report_zones(struct gendisk * zone_idx++; } - sector +=sd_zbc_zone_sectors (sdkp) * i; + lba += sdkp->zone_blocks * i; } ret = zone_idx;
Greg Kroah-Hartman
maintainerPATCH 231/272 scsi: sd: sd_zbc: Introduce struct zoned_disk_info
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
[ Upstream commit 628617be8968e575ca0a0637fb227f8a990cb2f7 ]
Deriving the meaning of the nr_zones, rev_nr_zones, zone_blocks and rev_zone_blocks member variables requires careful analysis of the source code. Make the meaning of these member variables easier to understand by introducing struct zoned_disk_info.
Stable-dep-of: 93dde0bf2f39 ("scsi: scsi_debug: Fix REPORT ZONES alloc_len underflow OOB write")
--- drivers/scsi/sd.h | 22 ++++++++++++++++++---- drivers/scsi/sd_zbc.c | 49 +++++++++++++++++++++++-------------------------- 2 files changed, 41 insertions(+), 30 deletions(-)
drivers/scsi/sd.h +18 -4
@@ -67,6 +67,20 @@ enum { SD_ZERO_WS10_UNMAP, /* Use WRITE SAME(10) with UNMAP */ }; +/** +* struct zoned_disk_info - Specific properties of a ZBC SCSI device. +* @nr_zones: number of zones. +* @zone_blocks: number of logical blocks per zone. +* +* This data structure holds the ZBC SCSI device properties that are retrieved +* twice: a first time before the gendisk capacity is known and a second time +* after the gendisk capacity is known. +*/ +struct zoned_disk_info { +u32 nr_zones; +u32 zone_blocks; +}; +struct scsi_disk {struct scsi_driver *driver;/* always &sd_template */ struct scsi_device *device;
@@ -74,10 +88,10 @@ struct scsi_disk {struct gendisk *disk;struct opal_dev *opal_dev;#ifdef CONFIG_BLK_DEV_ZONED -u32 nr_zones; -u32 rev_nr_zones; -u32 zone_blocks; -u32 rev_zone_blocks; +/* Updated during revalidation before the gendisk capacity is known. */ +struct zoned_disk_info early_zone_info; +/* Updated during revalidation after the gendisk capacity is known. */ +struct zoned_disk_info zone_info;u32 zones_optimal_open;u32 zones_optimal_nonseq;u32 zones_max_open;
drivers/scsi/sd_zbc.c +23 -26
136 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 232/272 scsi: sd: sd_zbc: Return early in sd_zbc_check_zoned_characteristics()
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]>
[ Upstream commit 60caf3758103b8edc90724ba781ff119f739162a ]
Return early in sd_zbc_check_zoned_characteristics() for host-aware disks. This patch does not change any functionality but makes a later patch easier to read.
Stable-dep-of: 93dde0bf2f39 ("scsi: scsi_debug: Fix REPORT ZONES alloc_len underflow OOB write")
--- drivers/scsi/sd_zbc.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
drivers/scsi/sd_zbc.c +7 -6
@@ -593,14 +593,15 @@ static int sd_zbc_check_zoned_characteri sdkp->zones_optimal_open =get_unaligned_be32 (&buf[8 ]); sdkp->zones_optimal_nonseq =get_unaligned_be32 (&buf[12 ]); sdkp->zones_max_open =0 ; - }else { -/* Host-managed */ - sdkp->urswrz = buf[4 ] &1 ; - sdkp->zones_optimal_open =0 ; - sdkp->zones_optimal_nonseq =0 ; - sdkp->zones_max_open =get_unaligned_be32 (&buf[16 ]); +return 0 ; } +/* Host-managed */ + sdkp->urswrz = buf[4 ] &1 ; + sdkp->zones_optimal_open =0 ; + sdkp->zones_optimal_nonseq =0 ; + sdkp->zones_max_open =get_unaligned_be32 (&buf[16 ]); +/* * Check for unconstrained reads: host-managed devices with * constrained reads (drives failing read after write pointer)
Greg Kroah-Hartman
maintainerPATCH 233/272 scsi: scsi_debug: Rename zone type constants
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]>
[ Upstream commit 35dbe2b9a7b0c92777c855c6a2cca8390f4c166b ]
Rename the scsi_debug zone type constants to prevent a conflict with the ZBC_ZONE_TYPE_GAP constant from include/scsi/scsi_proto.h.
Stable-dep-of: 93dde0bf2f39 ("scsi: scsi_debug: Fix REPORT ZONES alloc_len underflow OOB write")
--- drivers/scsi/scsi_debug.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
drivers/scsi/scsi_debug.c +9 -9
@@ -250,9 +250,9 @@ static const char *sdebug_version_date =/* Zone types (zbcr05 table 25) */ enum sdebug_z_type { -ZBC_ZONE_TYPE_CNV =0x1 , -ZBC_ZONE_TYPE_SWR =0x2 , -ZBC_ZONE_TYPE_SWP =0x3 , +ZBC_ZTYPE_CNV =0x1 , +ZBC_ZTYPE_SWR =0x2 , +ZBC_ZTYPE_SWP =0x3 , };/* enumeration names taken from table 26, zbcr05 */
@@ -2682,7 +2682,7 @@ static struct sdeb_zone_state *zbc_zone(static inline bool zbc_zone_is_conv (struct sdeb_zone_state *zsp) { -return zsp->z_type ==ZBC_ZONE_TYPE_CNV ; +return zsp->z_type ==ZBC_ZTYPE_CNV ; } static void zbc_close_zone(struct sdebug_dev_info *devip,
@@ -2781,7 +2781,7 @@ static void zbc_inc_wp(struct sdebug_devif (zbc_zone_is_conv (zsp))return ; -if (zsp->z_type ==ZBC_ZONE_TYPE_SWR ) { +if (zsp->z_type ==ZBC_ZTYPE_SWR ) { zsp->z_wp += num;if (zsp->z_wp >= zend)zbc_set_zone_full (devip, zsp);
@@ -2848,7 +2848,7 @@ static int check_zbc_access_params(strucreturn 0 ; } -if (zsp->z_type ==ZBC_ZONE_TYPE_SWR ) { +if (zsp->z_type ==ZBC_ZTYPE_SWR ) {/* Writes cannot cross sequential zone boundaries */ if (zsp_end != zsp) { mk_sense_buffer(scp, ILLEGAL_REQUEST,
@@ -4934,14 +4934,14 @@ static int sdebug_device_create_zones(st zsp->z_start = zstart;if (i < devip->nr_conv_zones) { - zsp->z_type =ZBC_ZONE_TYPE_CNV ; + zsp->z_type =ZBC_ZTYPE_CNV ; zsp->z_cond =ZBC_NOT_WRITE_POINTER ; zsp->z_wp = (sector_t)-1 ; }else {if (devip->zmodel ==BLK_ZONED_HM ) - zsp->z_type =ZBC_ZONE_TYPE_SWR ; + zsp->z_type =ZBC_ZTYPE_SWR ;else - zsp->z_type =ZBC_ZONE_TYPE_SWP ; + zsp->z_type =ZBC_ZTYPE_SWP ; zsp->z_cond =ZC1_EMPTY ; zsp->z_wp = zsp->z_start; }
Greg Kroah-Hartman
maintainerPATCH 234/272 scsi: scsi_debug: Fix REPORT ZONES alloc_len underflow OOB write
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ibrahim Hashimov <[email protected]>
[ Upstream commit 93dde0bf2f39a0f9f57fd610aa3201ce5b753433 ]
resp_report_zones() sizes the reply buffer from the CDB allocation length. The v3 fix rounds alloc_len up with ALIGN() before deriving the descriptor count:
rep_max_zones = (ALIGN((u64)alloc_len, RZONES_DESC_HD) - RZONES_DESC_HD) >> ilog2(RZONES_DESC_HD); arr_len = (u64)RZONES_DESC_HD * (rep_max_zones + 1);
For alloc_len in 0xFFFFFFC1..0xFFFFFFFF, ALIGN() rounds up to 0x100000000, so arr_len is 4 GB. On 32-bit, kzalloc()'s size_t is 32-bit and truncates 0x100000000 to 0; kzalloc(0) returns ZERO_SIZE_PTR, which passes the !arr check, and desc = arr + 64 is then dereferenced in the loop -> out-of-bounds write / panic.
Clamp rep_max_zones to devip->nr_zones. The loop already stops at sdebug_capacity (after nr_zones zones), so a report can never hold more than nr_zones descriptors; the clamp does not change the report, it only bounds arr_len to (nr_zones + 1) * RZONES_DESC_HD, a real device property that can never reach 0x100000000.
--- drivers/scsi/scsi_debug.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/scsi/scsi_debug.c +6 -3
@@ -4341,6 +4341,7 @@ static int resp_report_zones(struct scsiu32 alloc_len, rep_opts, rep_len;bool partial;u64 lba, zs_lba; +u64 arr_len;u8 *arr =NULL , *desc;u8 *cmd = scp->cmnd;struct sdeb_zone_state *zsp;
@@ -4364,10 +4365,12 @@ static int resp_report_zones(struct scsi } max_zones = devip->nr_zones - (zs_lba >> devip->zsize_shift); - rep_max_zones =min ((alloc_len -64 ) >>ilog2 (RZONES_DESC_HD ), - max_zones); + rep_max_zones = (ALIGN ((u64 )alloc_len,RZONES_DESC_HD ) -RZONES_DESC_HD ) >> +ilog2 (RZONES_DESC_HD ); + rep_max_zones = min_t(unsigned int, rep_max_zones, max_zones); + arr_len = (u64 )RZONES_DESC_HD * (rep_max_zones +1 ); - arr =kzalloc (alloc_len,GFP_ATOMIC | __GFP_NOWARN); + arr =kzalloc (arr_len,GFP_ATOMIC | __GFP_NOWARN);if (!arr) {mk_sense_buffer (scp,ILLEGAL_REQUEST ,INSUFF_RES_ASC ,INSUFF_RES_ASCQ );
Greg Kroah-Hartman
maintainerPATCH 235/272 ice: fix VF interrupts cleanup
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dawid Osuchowski <[email protected]>
[ Upstream commit fb096882095e5a8d6b5159e43793d4a38a0c5b1f ]
When a virtual function sends an IRQ map command, the PF will set up interrupts according to that request. However, because these interrupts are never reset, the next time Virtual Function initializes, the interrupts are still enabled for a given VF, which leads to performance degradation in certain cases due to interrupts being unexpectedly enabled and thus causing interrupt floods.
--- drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c | 48 +++++++++++++++++++++++ 1 file changed, 48 insertions(+)
drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c +48 -0
@@ -1588,6 +1588,30 @@ static bool ice_is_vf_disabled(struct ic }/** +* ice_reset_interrupts - clear all queue interrupt configuration for a VSI +* @vsi: the VSI whose interrupt registers should be cleared +* +* Zero the QINT_RQCTL and QINT_TQCTL registers for all allocated queues +* in the VSI. This clears the entire register including MSIX_INDX, ITR_INDX, +* CAUSE_ENA and NEXTQ fields, unlike ice_vf_dis_rxq_interrupt() which only +* clears the CAUSE_ENA bit. +*/ +static void ice_reset_interrupts (struct ice_vsi *vsi) +{ +struct ice_pf *pf = vsi->back; +struct ice_hw *hw = &pf->hw; +int i; + +ice_for_each_alloc_rxq (vsi, i) +wr32 (hw,QINT_RQCTL (vsi->rxq_map[i]),0 ); + +ice_for_each_alloc_txq (vsi, i) +wr32 (hw,QINT_TQCTL (vsi->txq_map[i]),0 ); + +ice_flush (hw); +} + +/** * ice_reset_vf - Reset a particular VF * @vf: pointer to the VF structure * @is_vflr: true if VFLR was issued, false if not
@@ -1630,6 +1654,9 @@ bool ice_reset_vf(struct ice_vf *vf, booice_dis_vf_qs (vf); +/* cleanup interrupt registers */ +ice_reset_interrupts (vsi); +/* Call Disable LAN Tx queue AQ whether or not queues are * enabled. This is needed for successful completion of VFR. */
@@ -3168,6 +3195,24 @@ static void ice_vf_ena_rxq_interrupt(str }/** +* ice_vf_dis_rxq_interrupt - disable Rx queue interrupt via QINT_RQCTL +* @vsi: VSI of the VF to configure +* @q_idx: VF queue index used to determine the queue in the PF's space +*/ +static void ice_vf_dis_rxq_interrupt (struct ice_vsi *vsi,u32 q_idx) +{ +struct ice_hw *hw = &vsi->back->hw; +u32 pfq = vsi->rxq_map[q_idx]; +u32 reg; + + reg =rd32 (hw,QINT_RQCTL (pfq)); + reg &= ~QINT_RQCTL_CAUSE_ENA_M ; +wr32 (hw,QINT_RQCTL (pfq), reg); + +ice_flush (hw); +} + +/** * ice_vc_ena_qs_msg * @vf: pointer to the VF info * @msg: pointer to the msg buffer
@@ -3336,6 +3381,8 @@ static int ice_vc_dis_qs_msg(struct ice_ goto error_param; } +for_each_set_bit (vf_q_id, &q_map,ICE_MAX_RSS_QS_PER_VF ) +ice_vf_dis_rxq_interrupt (vsi, vf_q_id);bitmap_zero (vf->rxq_ena,ICE_MAX_RSS_QS_PER_VF ); }else if (q_map) {for_each_set_bit (vf_q_id, &q_map,ICE_MAX_RSS_QS_PER_VF ) {
@@ -3356,6 +3403,7 @@ static int ice_vc_dis_qs_msg(struct ice_ goto error_param; } +ice_vf_dis_rxq_interrupt (vsi, vf_q_id);/* Clear enabled queues flag */ clear_bit (vf_q_id, vf->rxq_ena); }
Greg Kroah-Hartman
maintainerPATCH 236/272 ice: fix memory leak in ice_lbtest_prepare_rings()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dawei Feng <[email protected]>
[ Upstream commit 3a9de5590da4ffd9e9c541c4c4d492aa2b54cf6e ]
ice_lbtest_prepare_rings() frees Rx rings only when ice_vsi_start_all_rx_rings() fails. If ice_vsi_setup_rx_rings() fails after allocating some descriptors, or if ice_vsi_cfg_lan() fails after the Rx rings were prepared, the function reaches the Tx cleanup path without releasing the initialized Rx resources.
Fix this by adding separate unwind paths for Rx setup failure and LAN configuration failure. The Rx setup failure path releases the partially prepared Rx rings before freeing Tx rings, while later failures first undo the LAN Tx configuration and then release the Rx rings in reverse setup order.
The bug was first flagged by an experimental analysis tool we are developing for kernel memory-management bugs while analyzing v6.13-rc1. The tool is still under development and is not yet publicly available. Manual inspection confirms that the bug is still present in v7.1-rc7.
An x86_64 allyesconfig build showed no new warnings. As we do not have an Intel E800 Series adapter available to run the ethtool offline loopback selftest, no runtime testing was able to be performed.
--- drivers/net/ethernet/intel/ice/ice_ethtool.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/net/ethernet/intel/ice/ice_ethtool.c +5 -5
@@ -477,18 +477,18 @@ static int ice_lbtest_prepare_rings(stru status =ice_vsi_cfg (vsi);if (status) - goto err_setup_rx_ring; + goto err_cfg_lan; status =ice_vsi_start_all_rx_rings (vsi);if (status) - goto err_start_rx_ring; + goto err_cfg_lan;return status; -err_start_rx_ring: -ice_vsi_free_rx_rings (vsi); -err_setup_rx_ring: +err_cfg_lan:ice_vsi_stop_lan_tx_rings (vsi,ICE_NO_RESET ,0 ); +err_setup_rx_ring: +ice_vsi_free_rx_rings (vsi); err_setup_tx_ring:ice_vsi_free_tx_rings (vsi);
Greg Kroah-Hartman
maintainerPATCH 237/272 fsnotify: opt-in for permission events at file open time
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amir Goldstein <[email protected]>
[ Upstream commit a94204f4d48e28a711b7ed10399f749286c433e3 ]
Legacy inotify/fanotify listeners can add watches for events on inode, parent or mount and expect to get events (e.g. FS_MODIFY) on files that were already open at the time of setting up the watches.
fanotify permission events are typically used by Anti-malware sofware, that is watching the entire mount and it is not common to have more that one Anti-malware engine installed on a system.
To reduce the overhead of the fsnotify_file_perm() hooks on every file access, relax the semantics of the legacy FAN_ACCESS_PERM event to generate events only if there were *any* permission event listeners on the filesystem at the time that the file was opened.
The new semantic is implemented by extending the FMODE_NONOTIFY bit into two FMODE_NONOTIFY_* bits, that are used to store a mode for which of the events types to report.
This is going to apply to the new fanotify pre-content events in order to reduce the cost of the new pre-content event vfs hooks.
[Thanks to Bert Karwatzki <[email protected]> for reporting a bug in this code with CONFIG_FANOTIFY_ACCESS_PERMISSIONS disabled]
Stable-dep-of: db1856ea9196 ("binfmt_misc: restore write access when removing an entry")
--- include/linux/fs.h | 6 ++++++ 1 file changed, 6 insertions(+)
include/linux/fs.h +6 -0
@@ -181,6 +181,12 @@ typedef int (dio_iodone_t)(struct kiocb#define FMODE_BUF_RASYNC ((__force fmode_t)0x40000000)/* +* fsnotify pre-content events do not exist in this kernel, so a file is never +* watched by a pre-content event listener. +*/ +#define FMODE_FSNOTIFY_HSM (mode) 0 + +/* * Attribute flags. These should be or-ed together to figure out what * has been changed! */
Greg Kroah-Hartman
maintainerPATCH 238/272 fs: dont block write during exec on pre-content watched files
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amir Goldstein <[email protected]>
[ Upstream commit 0357ef03c94ef835bd44a0658b8edb672a9dbf51 ]
Commit 2a010c412853 ("fs: don't block i_writecount during exec") removed the legacy behavior of getting ETXTBSY on attempt to open and executable file for write while it is being executed.
This commit was reverted because an application that depends on this legacy behavior was broken by the change.
We need to allow HSM writing into executable files while executed to fill their content on-the-fly.
To that end, disable the ETXTBSY legacy behavior for files that are watched by pre-content events.
This change is not expected to cause regressions with existing systems which do not have any pre-content event listeners.
Stable-dep-of: db1856ea9196 ("binfmt_misc: restore write access when removing an entry")
--- fs/binfmt_elf.c | 4 ++-- fs/binfmt_elf_fdpic.c | 4 ++-- fs/exec.c | 6 +++--- include/linux/fs.h | 22 ++++++++++++++++++++++ kernel/fork.c | 12 ++++++------ 5 files changed, 35 insertions(+), 13 deletions(-)
fs/binfmt_elf.c +2 -2
@@ -1243,7 +1243,7 @@ out_free_interp: } reloc_func_desc = interp_load_addr; -allow_write_access (interpreter); +exe_file_allow_write_access (interpreter);fput (interpreter);kfree (interp_elf_ex);
@@ -1332,7 +1332,7 @@ out_free_dentry:kfree (interp_elf_ex);kfree (interp_elf_phdata); out_free_file: -allow_write_access (interpreter); +exe_file_allow_write_access (interpreter);if (interpreter)fput (interpreter); out_free_ph:
fs/binfmt_elf_fdpic.c +2 -2
@@ -398,7 +398,7 @@ static int load_elf_fdpic_binary(struct goto error; } -allow_write_access (interpreter); +exe_file_allow_write_access (interpreter);fput (interpreter); interpreter =NULL ; }
@@ -471,7 +471,7 @@ static int load_elf_fdpic_binary(struct error:if (interpreter) { -allow_write_access (interpreter); +exe_file_allow_write_access (interpreter);fput (interpreter); }kfree (interpreter_name);
fs/exec.c +3 -3
@@ -929,7 +929,7 @@ static struct file *do_open_execat(int f path_noexec(&file->f_path)) goto exit; - err =deny_write_access (file); + err =exe_file_deny_write_access (file);if (err) goto exit;
@@ -1499,7 +1499,7 @@ static void free_bprm(struct linux_binprabort_creds (bprm->cred); }if (bprm->file) { -allow_write_access (bprm->file); +exe_file_allow_write_access (bprm->file);fput (bprm->file); }if (bprm->executable)
@@ -1790,7 +1790,7 @@ static int exec_binprm(struct linux_binp bprm->file = bprm->interpreter; bprm->interpreter =NULL ; -allow_write_access (exec); +exe_file_allow_write_access (exec);if (unlikely (bprm->have_execfd)) {if (bprm->executable) {fput (exec);
include/linux/fs.h +22 -0
@@ -3143,6 +3143,28 @@ static inline void allow_write_access(stif (file)atomic_inc (&file_inode (file)->i_writecount); } + +/* +* Do not prevent write to executable file when watched by pre-content events. +* +* Note that FMODE_FSNOTIFY_HSM mode is set depending on pre-content watches at +* the time of file open and remains constant for entire lifetime of the file, +* so if pre-content watches are added post execution or removed before the end +* of the execution, it will not cause i_writecount reference leak. +*/ +static inline int exe_file_deny_write_access (struct file *exe_file) +{ +if (unlikely (FMODE_FSNOTIFY_HSM (exe_file->f_mode))) +return 0 ; +return deny_write_access (exe_file); +} +static inline void exe_file_allow_write_access (struct file *exe_file) +{ +if (unlikely (!exe_file ||FMODE_FSNOTIFY_HSM (exe_file->f_mode))) +return ; +allow_write_access (exe_file); +} +static inline bool inode_is_open_for_write (const struct inode *inode) {return atomic_read (&inode->i_writecount) >0 ;
kernel/fork.c +6 -6
@@ -487,8 +487,8 @@ static void dup_mm_exe_file(struct mm_st* We depend on the oldmm having properly denied write access to the * exe_file already. */ -if (exe_file &&deny_write_access (exe_file)) -pr_warn_once ("deny_write_access() failed in %s\n" , __func__); +if (exe_file &&exe_file_deny_write_access (exe_file)) +pr_warn_once ("exe_file_deny_write_access() failed in %s\n" , __func__); }#ifdef CONFIG_MMU
@@ -1201,13 +1201,13 @@ int set_mm_exe_file(struct mm_struct *mm* We expect the caller (i.e., sys_execve) to already denied * write access, so this is unlikely to fail. */ -if (unlikely (deny_write_access (new_exe_file))) +if (unlikely (exe_file_deny_write_access (new_exe_file)))return -EACCES ;get_file (new_exe_file); }rcu_assign_pointer (mm->exe_file, new_exe_file);if (old_exe_file) { -allow_write_access (old_exe_file); +exe_file_allow_write_access (old_exe_file);fput (old_exe_file); }return 0 ;
@@ -1246,7 +1246,7 @@ int replace_mm_exe_file(struct mm_struct }/* set the new file, lockless */ - ret =deny_write_access (new_exe_file); + ret =exe_file_deny_write_access (new_exe_file);if (ret)return -EACCES ;get_file (new_exe_file);
@@ -1258,7 +1258,7 @@ int replace_mm_exe_file(struct mm_struct* write access while someone might open the file writable. */ mmap_read_lock (mm); -allow_write_access (old_exe_file); +exe_file_allow_write_access (old_exe_file);fput (old_exe_file);mmap_read_unlock (mm); }
Greg Kroah-Hartman
maintainerPATCH 239/272 binfmt_misc: restore write access when removing an entry
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <[email protected]>
[ Upstream commit db1856ea9196cf6e015d12199a34c0b9313c7bfa ]
Registering an entry with the MISC_FMT_OPEN_FILE flag opens the interpreter via open_exec() which denies write access to it for as long as the entry exists. Removing the entry closes the interpreter file via filp_close() but never restores write access, leaving the inode's i_writecount permanently negative. Opening the interpreter for writing keeps failing with ETXTBSY long after the entry is gone until the inode is evicted from the inode cache.
Commit 90f601b497d7 ("binfmt_misc: restore write access before closing files opened by open_exec()") fixed the same imbalance in the error path of bm_register_write() but the actual removal path has been leaking the write denial since the introduction of the flag.
Restore write access in put_binfmt_handler() before closing the interpreter file.
--- fs/binfmt_misc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
fs/binfmt_misc.c +3 -1
@@ -163,8 +163,10 @@ static Node *get_binfmt_handler(struct lstatic void put_binfmt_handler (Node *e) {if (refcount_dec_and_test (&e->users)) { -if (e->flags &MISC_FMT_OPEN_FILE ) +if (e->flags &MISC_FMT_OPEN_FILE ) { +exe_file_allow_write_access (e->interp_file);filp_close (e->interp_file,NULL ); + }kfree (e); } }
Greg Kroah-Hartman
maintainerPATCH 240/272 i2c: imx: Fix slave registration race and error handling
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liem <[email protected]>
[ Upstream commit d64ec362c369bbc33833f7936d5f3a706b0d5c45 ]
In i2c_imx_reg_slave(), the slave pointer was assigned before pm_runtime_resume_and_get(). If pm_runtime_resume_and_get() failed, the error path returned without clearing i2c_imx->slave, leaving it non-NULL and causing all subsequent registration attempts to fail with -EBUSY.
Additionally, because this driver uses a shared IRQ, the interrupt handler i2c_imx_isr() can execute concurrently and, after acquiring slave_lock, dereference i2c_imx->slave. The previous fix attempt added a lockless i2c_imx->slave = NULL on the error path, but that could race with the ISR under the lock and still cause a NULL pointer dereference.
Fix both issues by deferring the assignment of i2c_imx->slave and i2c_imx->last_slave_event to after a successful resume, and by performing the assignment inside the slave_lock critical section. This guarantees that the slave pointer is never left stale on the error path and is always valid when observed by the interrupt handler.
--- drivers/i2c/busses/i2c-imx.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/i2c/busses/i2c-imx.c +6 -3
@@ -832,14 +832,12 @@ static void i2c_imx_slave_init(struct imstatic int i2c_imx_reg_slave (struct i2c_client *client) {struct imx_i2c_struct *i2c_imx =i2c_get_adapdata (client->adapter); +unsigned long flags;int ret;if (i2c_imx->slave)return -EBUSY ; - i2c_imx->slave = client; - i2c_imx->last_slave_event =I2C_SLAVE_STOP ; -/* Resume */ ret =pm_runtime_resume_and_get (i2c_imx->adapter.dev.parent);if (ret <0 ) {
@@ -847,6 +845,11 @@ static int i2c_imx_reg_slave(struct i2c_return ret; } +spin_lock_irqsave (&i2c_imx->slave_lock, flags); + i2c_imx->slave = client; + i2c_imx->last_slave_event =I2C_SLAVE_STOP ; +spin_unlock_irqrestore (&i2c_imx->slave_lock, flags); +i2c_imx_slave_init (i2c_imx);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 241/272 i2c: bcm-iproc: remove printout on handled timeouts
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wolfram Sang <[email protected]>
[ Upstream commit 796e2c260187e32530cf343546ba1cdf2e2f5491 ]
I2C and SMBus timeouts are not something the user needs to be informed about on controller level. The client driver may know if that really is a problem and give more detailed information to the user. The controller should just pass this information upwards. Remove the printout.
Stable-dep-of: 98f2e9e6d6f9 ("i2c: iproc: reset bus after timeout if START_BUSY is stuck")
--- drivers/i2c/busses/i2c-bcm-iproc.c | 2 -- 1 file changed, 2 deletions(-)
drivers/i2c/busses/i2c-bcm-iproc.c +0 -2
@@ -821,8 +821,6 @@ static int bcm_iproc_i2c_xfer_wait(struc }if (!time_left && !iproc_i2c->xfer_is_done) { -dev_err (iproc_i2c->device,"transaction timed out\n" ); -/* flush both TX/RX FIFOs */ val =BIT (M_FIFO_RX_FLUSH_SHIFT ) |BIT (M_FIFO_TX_FLUSH_SHIFT );iproc_i2c_wr_reg (iproc_i2c,M_FIFO_CTRL_OFFSET , val);
Greg Kroah-Hartman
maintainerPATCH 242/272 i2c: iproc: reset bus after timeout if START_BUSY is stuck
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit 98f2e9e6d6f91a6abb43f166b244b428ba85fa2b ]
If a transaction times out, the START_BUSY signal can stay up, and subsequent transactaction attempts will fail as the bus is still considered busy.
I can easily trigger this by attempting to read from an address with no device, e.g. when running i2cdetect. After the first read times out, all subsequent read attempts return busy.
To get to a working state again, the controller needs to be reset to clear the START_BUSY signal. So check for START_BUSY still asserted on a timeout, and do reset in case it is,
This is also done by the original non-upstream iproc-smbus driver implementation [1].
Works around situations like:
bcm-iproc-2c 1803b000.i2c: transaction timed out
bcm-iproc-2c 1803b000.i2c: bus is busy
bcm-iproc-2c 1803b000.i2c: bus is busy
bcm-iproc-2c 1803b000.i2c: bus is busy
bcm-iproc-2c 1803b000.i2c: bus is busy
bcm-iproc-2c 1803b000.i2c: bus is busy
...where the bus never recovers after a timeout.
--- drivers/i2c/busses/i2c-bcm-iproc.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/i2c/busses/i2c-bcm-iproc.c +11 -0
@@ -821,6 +821,17 @@ static int bcm_iproc_i2c_xfer_wait(struc }if (!time_left && !iproc_i2c->xfer_is_done) { +/* +* The controller may fail to clear START_BUSY after a timeout, +* reset the controller to recover in that case. +*/ +if (!!(iproc_i2c_rd_reg (iproc_i2c,M_CMD_OFFSET ) & +BIT (M_CMD_START_BUSY_SHIFT ))) { +bcm_iproc_i2c_enable_disable (iproc_i2c, false); +bcm_iproc_i2c_init (iproc_i2c); +bcm_iproc_i2c_enable_disable (iproc_i2c, true); + } +/* flush both TX/RX FIFOs */ val =BIT (M_FIFO_RX_FLUSH_SHIFT ) |BIT (M_FIFO_TX_FLUSH_SHIFT );iproc_i2c_wr_reg (iproc_i2c,M_FIFO_CTRL_OFFSET , val);
Greg Kroah-Hartman
maintainerPATCH 243/272 can: gs_usb: gs_usb_receive_bulk_callback(): resubmit URB on skb allocation failure
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Kleine-Budde <[email protected]>
[ Upstream commit 68c5724ecd159992f76edb7b57dc508a44c8b7da ]
If the allocation of the SKB in gs_usb_receive_bulk_callback() fails, the driver returns from the callback without resubmitting the URB in order to receive further USB in URBs.
This results in a silent performance degradation which, if it occurs repeatedly, results in starvation of USB in traffic.
Instead of returning immediately, try to resend the URB. If this also fails, this is logged as an info message.
--- drivers/net/can/usb/gs_usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/can/usb/gs_usb.c +1 -1
@@ -333,7 +333,7 @@ static void gs_usb_receive_bulk_callbackif (hf->echo_id ==-1 ) {/* normal rx */ skb =alloc_can_skb (dev->netdev, &cf);if (!skb) -return ; + goto resubmit_urb; cf->can_id =le32_to_cpu (hf->can_id);
Greg Kroah-Hartman
maintainerPATCH 244/272 jiffies: Define secs_to_jiffies()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Easwar Hariharan <[email protected]>
[ Upstream commit b35108a51cf7bab58d7eace1267d7965978bcdb8 ]
secs_to_jiffies() is defined in hci_event.c and cannot be reused by other call sites. Hoist it into the core code to allow conversion of the ~1150 usages of msecs_to_jiffies() that either:
- use a multiplier value of 1000 or equivalently MSEC_PER_SEC, or
- have timeouts that are denominated in seconds (i.e. end in 000)
It's implemented as a macro to allow usage in static initializers.
This will also allow conversion of yet more sites that use (sec * HZ) directly, and improve their readability.
Stable-dep-of: c2816d613f38 ("ice: wait for reset completion in ice_resume()")
--- include/linux/jiffies.h | 13 +++++++++++++ net/bluetooth/hci_event.c | 2 -- 2 files changed, 13 insertions(+), 2 deletions(-)
include/linux/jiffies.h +13 -0
@@ -371,6 +371,19 @@ static __always_inline unsigned long mse } } +/** +* secs_to_jiffies: - convert seconds to jiffies +* @_secs: time in seconds +* +* Conversion is done by simple multiplication with HZ +* +* secs_to_jiffies() is defined as a macro rather than a static inline +* function so it can be used in static initializers. +* +* Return: jiffies value +*/ +#define secs_to_jiffies (_secs) ((_secs) * HZ) +extern unsigned long __usecs_to_jiffies (const unsigned int u);#if !(USEC_PER_SEC %HZ )static inline unsigned long _usecs_to_jiffies (const unsigned int u)
net/bluetooth/hci_event.c +0 -2
@@ -42,8 +42,6 @@#define ZERO_KEY "\x00\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x00\x00\x00\x00" -#define secs_to_jiffies (_secs) msecs_to_jiffies((_secs) * 1000) -/* Handle HCI Event packets */ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb,
Greg Kroah-Hartman
maintainerPATCH 245/272 ice: wait for reset completion in ice_resume()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aaron Ma <[email protected]>
[ Upstream commit c2816d613f388814d27bc9fd6dbd931a88056e19 ]
ice_resume() schedules an asynchronous PF reset and returns immediately. The reset runs later in ice_service_task(). If userspace tries to bring up the net device before the reset finishes, ice_open() fails with -EBUSY:
ice_resume()
ice_schedule_reset() # sets ICE_PFR_REQ, returns
...
ice_open()
ice_is_reset_in_progress() # ICE_PFR_REQ still set, -EBUSY
...
ice_service_task()
ice_do_reset()
ice_rebuild() # clears ICE_PFR_REQ, too late
Reproduced on E800 series NICs during suspend/resume with irdma enabled, where the aux device probe widens the race window.
ice 0000:81:00.0: can't open net device while reset is in progress
Add a best-effort wait (10s timeout, matching ice_devlink_info_get()) for the reset to complete before returning from ice_resume(). In practice the reset completes in ~300ms.
--- drivers/net/ethernet/intel/ice/ice_main.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/net/ethernet/intel/ice/ice_main.c +10 -0
@@ -4948,6 +4948,16 @@ static int __maybe_unused ice_resume(str/* Restart the service task */ mod_timer (&pf->serv_tmr,round_jiffies (jiffies + pf->serv_tmr_period)); +/* Best-effort wait for the scheduled reset to finish so that the +* device is operational before returning. Without this, userspace +* (e.g. NetworkManager) may try to open the net device while the +* asynchronous reset is still in progress, hitting -EBUSY. +*/ + ret =ice_wait_for_reset (pf,secs_to_jiffies (10 )); +if (ret) +dev_err (dev,"Wait for reset timed out (10s) during resume: %d\n" , + ret); + return 0; }#endif /* CONFIG_PM */
Greg Kroah-Hartman
maintainerPATCH 246/272 drm/amd/pm: fix torn gpu metrics reads
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Wang <[email protected]>
[ Upstream commit 048f4541b71fb19645fb79d6e62e6e4da23a4035 ]
amdgpu_dpm_get_gpu_metrics() returns a pointer to the shared metrics cache after dropping adev->pm.mutex. The sysfs path then copies from that pointer. Another reader can refresh the cache in place during the copy and return a snapshot containing data from two generations.
Pass caller-provided storage through the DPM interface and copy the metrics while the mutex is held. This keeps the cache pointer private and makes each sysfs read observe one complete sample.
--- drivers/gpu/drm/amd/pm/amdgpu_pm.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
drivers/gpu/drm/amd/pm/amdgpu_pm.c +6 -8
@@ -1804,18 +1804,16 @@ static ssize_t amdgpu_get_gpu_metrics(streturn ret; } +mutex_lock (&adev->pm.mutex);if (adev->powerplay.pp_funcs->get_gpu_metrics) size =amdgpu_dpm_get_gpu_metrics (adev, &gpu_metrics); -if (size <=0 ) - goto out; - -if (size >=PAGE_SIZE ) - size =PAGE_SIZE -1 ; - -memcpy (buf, gpu_metrics, size); +if (size >0 ) { + size =min_t (ssize_t, size,PAGE_SIZE -1 ); +memcpy (buf, gpu_metrics, size); + } +mutex_unlock (&adev->pm.mutex); -out:pm_runtime_mark_last_busy (ddev->dev);pm_runtime_put_autosuspend (ddev->dev);
Greg Kroah-Hartman
maintainerPATCH 247/272 sched/psi: Shut down rtpoll_timer in psi_cgroup_free()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tejun Heo <[email protected]>
[ Upstream commit 5457025fa8ca3c0d2732109513de839e3e797190 ]
psi_schedule_rtpoll_work() is called locklessly from the scheduler hotpath and can race psi_trigger_destroy() taking down the last rtpoll trigger under rtpoll_trigger_lock:
psi_schedule_rtpoll_work() psi_trigger_destroy()
rcu_read_lock();
task = rcu_dereference(rtpoll_task);
rcu_assign_pointer(rtpoll_task, NULL);
timer_delete(&rtpoll_timer);
mod_timer(&rtpoll_timer, ...);
rcu_read_unlock();
synchronize_rcu();
kthread_stop(task_to_destroy);The group can then be freed with the re-armed timer still pending, and poll_timer_fn() runs on freed memory.
461daba06bdc ("psi: eliminate kthread_worker from psi trigger scheduling mechanism") deleted the timer synchronously after the synchronize_rcu(), which prevented this but raced trigger creation instead: the deletion could cancel the timer that a new trigger set armed during the grace period and, as creation also reinitialized the timer at the time, corrupt it. 8f91efd870ea ("psi: Fix race between psi_trigger_create/destroy") moved the initialization into group_init() and the deletion into the locked section, trading the creation races for the window above.
Neither placement in the destruction path works. A pending timer firing while the group is alive is harmless though. poll_timer_fn() just wakes the rtpoll waitqueue and doesn't re-arm itself. Bind the timer to the group's lifetime instead and shut it down in psi_cgroup_free(). Nothing can arm it by then. timer_shutdown_sync() because the timer is never armed again.
--- kernel/sched/psi.c | 6 ++++++ 1 file changed, 6 insertions(+)
kernel/sched/psi.c +6 -0
@@ -972,6 +972,12 @@ void psi_cgroup_free(struct cgroup *cgroreturn ;cancel_delayed_work_sync (&cgroup->psi.avgs_work); +/* +* A psi_schedule_poll_work() call racing the last trigger's +* destruction may have re-armed the timer after psi_trigger_destroy() +* deleted it. Spurious firing while the group is alive is harmless. +*/ +timer_shutdown_sync (&cgroup->psi.poll_timer);free_percpu (cgroup->psi.pcpu);/* All triggers must be removed by now */ WARN_ONCE (cgroup->psi.poll_states,"psi: trigger leak\n" );
Greg Kroah-Hartman
maintainerPATCH 248/272 mm/ptdump: always stabilise against page table freeing using init_mm
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Lorenzo Stoakes (ARM)" <[email protected]>
[ Upstream commit 27c32e5538344b13c1505a08861e04620c125d47 ]
Previous commits have established the invariant that kernel page table freeing is performed while an mmap read lock on init_mm is held, which fixes races between ptdump and kernel page table freeing over init_mm.
However, x86 and arm64 can perform a ptdump over an mm other than init_mm via ptdump_walk_pgd() and since kernel memory ranges are shared across non-kernel mm's, this means that the race still exists for these cases.
Fix this by acquiring a nested mmap write lock for init_mm in ptdump_walk_pgd().
This is safe as we take this after mmap write locking the mm, and nothing acquires the init_mm lock first before locking an arbitrary mm, so no deadlock is possible.
Also update walk_page_range_debug() to assert that init_mm is write locked, add a comment explaining why and remove some redundant code, and eliminate the unnecessary and confusing invocation of walk_kernel_page_table_range().
We can safely remove the non-NULL check for walk.mm, as the mmap lock asserts would NULL pointer deref if it was (and of course no callers do this).
The first point at which ptdump can race kernel page table freeing is commit b6bdb7517c3d ("mm/vmalloc: add interfaces to free unmapped page table"), so we target this in the Fixes tag.
--- mm/pagewalk.c | 8 ++++++++ mm/ptdump.c | 7 +++++++ 2 files changed, 15 insertions(+)
mm/pagewalk.c +8 -0
@@ -505,6 +505,14 @@ int walk_page_range_novma(struct mm_strureturn -EINVAL ;mmap_assert_write_locked (walk.mm); +/* +* x86, arm64 ptdump allow walks of efi mm's and x86 ptdump allows walks +* of arbitrary mm's. +* +* However, they both must also hold the init_mm lock to account for +* concurrent kernel page table freeing. +*/ +mmap_assert_write_locked (&init_mm);return walk_pgd_range (start, end, &walk); }
mm/ptdump.c +7 -0
@@ -146,11 +146,18 @@ void ptdump_walk_pgd(struct ptdump_stateget_online_mems ();mmap_write_lock (mm); +/* To stabilise kernel page tables we must hold the init_mm lock too. */ +if (mm != &init_mm) +mmap_write_lock_nested (&init_mm,SINGLE_DEPTH_NESTING ); +while (range->start != range->end) {walk_page_range_novma (mm, range->start, range->end, &ptdump_ops, pgd, st); range++; } + +if (mm != &init_mm) +mmap_write_unlock (&init_mm);mmap_write_unlock (mm);put_online_mems ();
Greg Kroah-Hartman
maintainerPATCH 249/272 net: add a couple of helpers for iph tot_len
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 058a8f7f73aae1cc22b53fcefec031b9e391b54d ]
This patch adds three APIs to replace the iph->tot_len setting and getting in all places where IPv4 BIG TCP packets may reach, they will be used in the following patches.
Note that iph_totlen() will be used when iph is not in linear data of the skb.
Stable-dep-of: 8a7ed561671a ("net/sched: act_ct: fix sk_buff leak when the header checks reject a packet")
--- include/linux/ip.h | 21 +++++++++++++++++++++ include/net/route.h | 3 --- 2 files changed, 21 insertions(+), 3 deletions(-)
include/linux/ip.h +21 -0
@@ -35,4 +35,25 @@ static inline unsigned int ip_transport_ {return ntohs (ip_hdr (skb)->tot_len) -skb_network_header_len (skb); } + +static inline unsigned int iph_totlen (const struct sk_buff *skb,const struct iphdr *iph) +{ +u32 len =ntohs (iph->tot_len); + +return (len || !skb_is_gso (skb) || !skb_is_gso_tcp (skb)) ? + len : skb->len -skb_network_offset (skb); +} + +static inline unsigned int skb_ip_totlen (const struct sk_buff *skb) +{ +return iph_totlen (skb,ip_hdr (skb)); +} + +/* IPv4 datagram length is stored into 16bit field (tot_len) */ +#define IP_MAX_MTU 0xFFFFU + +static inline void iph_set_totlen (struct iphdr *iph,unsigned int len) +{ + iph->tot_len = len <=IP_MAX_MTU ?htons (len) :0 ; +}#endif /* _LINUX_IP_H */
include/net/route.h +0 -3
@@ -35,9 +35,6 @@#include <linux/cache.h> #include <linux/security.h> -/* IPv4 datagram length is stored into 16bit field (tot_len) */ -#define IP_MAX_MTU 0xFFFFU -#define RTO_ONLINK 0x01#define RT_CONN_FLAGS (sk) (RT_TOS(inet_sk(sk)->tos) | sock_flag(sk, SOCK_LOCALROUTE))
Greg Kroah-Hartman
maintainerPATCH 250/272 openvswitch: use skb_ip_totlen in conntrack
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 ec84c955a0d06cef31664bae328d94be7a3e2f03 ]
IPv4 GSO packets may get processed in ovs_skb_network_trim(), and we need to use skb_ip_totlen() to get iph totlen.
Stable-dep-of: 8a7ed561671a ("net/sched: act_ct: fix sk_buff leak when the header checks reject a packet")
--- net/openvswitch/conntrack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/openvswitch/conntrack.c +1 -1
@@ -1275,7 +1275,7 @@ static int ovs_skb_network_trim(struct sswitch (skb->protocol) {case htons (ETH_P_IP ): - len =ntohs (ip_hdr (skb)->tot_len); + len =skb_ip_totlen (skb);break ;case htons (ETH_P_IPV6 ): len =sizeof (struct ipv6hdr )
Greg Kroah-Hartman
maintainerPATCH 251/272 net: sched: use skb_ip_totlen and iph_totlen
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 043e397e48c58b4442ea5124dc1bdc95367a0a33 ]
There are 1 action and 1 qdisc that may process IPv4 TCP GSO packets and access iph->tot_len, replace them with skb_ip_totlen() and iph_totlen() accordingly.
Note that we don't need to replace the one in tcf_csum_ipv4(), as it will return for TCP GSO packets in tcf_csum_ipv4_tcp().
Stable-dep-of: 8a7ed561671a ("net/sched: act_ct: fix sk_buff leak when the header checks reject a packet")
--- net/sched/act_ct.c | 2 +- net/sched/sch_cake.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
net/sched/act_ct.c +1 -1
@@ -629,7 +629,7 @@ static int tcf_ct_skb_network_trim(strucswitch (family) {case NFPROTO_IPV4 : - len =ntohs (ip_hdr (skb)->tot_len); + len =skb_ip_totlen (skb);break ;case NFPROTO_IPV6 : len =sizeof (struct ipv6hdr )
net/sched/sch_cake.c +1 -1
@@ -1269,7 +1269,7 @@ static struct sk_buff *cake_ack_filter(s iph_check->daddr != iph->daddr)continue ; - seglen =ntohs (iph_check->tot_len) - + seglen =iph_totlen (skb, iph_check) - (4 * iph_check->ihl); }else if (iph_check->version ==6 ) { ipv6h = (struct ipv6hdr *)iph;
Greg Kroah-Hartman
maintainerPATCH 252/272 openvswitch: move key and ovs_cb update out of handle_fragments
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 1b83bf4489cbc47d88976291cc967a17adb8e118 ]
This patch has no functional changes and just moves key and ovs_cb update out of handle_fragments, and skb_clear_hash() and skb->ignore_df change into handle_fragments(), to make it easier to move the duplicate code from handle_fragments() into nf_conntrack_ovs later.
Note that it changes to pass info->family to handle_fragments() instead of key for the packet type check, as info->family is set according to key->eth.type in ovs_ct_copy_action() when creating the action.
Stable-dep-of: 8a7ed561671a ("net/sched: act_ct: fix sk_buff leak when the header checks reject a packet")
--- net/openvswitch/conntrack.c | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-)
net/openvswitch/conntrack.c +25 -12
@@ -494,13 +494,12 @@ static int ovs_ct_helper(struct sk_buff/* Returns 0 on success, -EINPROGRESS if 'skb' is stolen, or other nonzero * value if 'skb' is freed. */ -static int handle_fragments (struct net *net,struct sw_flow_key *key, -u16 zone,struct sk_buff *skb) +static int handle_fragments (struct net *net,struct sk_buff *skb, +u16 zone,u8 family,u8 *proto,u16 *mru) { -struct ovs_skb_cb ovs_cb = *OVS_CB (skb);int err; -if (key->eth.type ==htons (ETH_P_IP )) { +if (family ==NFPROTO_IPV4 ) {enum ip_defrag_users user =IP_DEFRAG_CONNTRACK_IN + zone;memset (IPCB (skb),0 ,sizeof (struct inet_skb_parm ));
@@ -508,9 +507,9 @@ static int handle_fragments(struct net *if (err)return err; - ovs_cb.mru =IPCB (skb)->frag_max_size; + *mru =IPCB (skb)->frag_max_size;#if IS_ENABLED (CONFIG_NF_DEFRAG_IPV6 ) - } else if (key->eth.type == htons(ETH_P_IPV6)) { + } else if (family == NFPROTO_IPV6) {enum ip6_defrag_users user =IP6_DEFRAG_CONNTRACK_IN + zone;memset (IP6CB (skb),0 ,sizeof (struct inet6_skb_parm ));
@@ -521,22 +520,35 @@ static int handle_fragments(struct net *return err; } - key->ip.proto =ipv6_hdr (skb)->nexthdr; - ovs_cb.mru =IP6CB (skb)->frag_max_size; + *proto =ipv6_hdr (skb)->nexthdr; + *mru =IP6CB (skb)->frag_max_size;#endif }else {kfree_skb (skb);return -EPFNOSUPPORT ; } +skb_clear_hash (skb); + skb->ignore_df =1 ; + +return 0 ; +} + +static int ovs_ct_handle_fragments (struct net *net,struct sw_flow_key *key, +u16 zone,int family,struct sk_buff *skb) +{ +struct ovs_skb_cb ovs_cb = *OVS_CB (skb); +int err; + + err =handle_fragments (net, skb, zone, family, &key->ip.proto, &ovs_cb.mru); +if (err) +return err; +/* The key extracted from the fragment that completed this datagram * likely didn't have an L4 header, so regenerate it. */ ovs_flow_key_update_l3l4 (skb, key); - key->ip.frag =OVS_FRAG_TYPE_NONE ; -skb_clear_hash (skb); - skb->ignore_df =1 ; *OVS_CB (skb) = ovs_cb;return 0 ;
@@ -1311,7 +1323,8 @@ int ovs_ct_execute(struct net *net, strureturn err;if (key->ip.frag !=OVS_FRAG_TYPE_NONE ) { - err =handle_fragments (net, key, info->zone.id, skb); + err =ovs_ct_handle_fragments (net, key, info->zone.id, + info->family, skb);if (err)return err; }
Greg Kroah-Hartman
maintainerPATCH 253/272 net/sched: act_ct: fix sk_buff leak when the header checks reject a packet
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hyunjung Ko <[email protected]>
[ Upstream commit 8a7ed561671aa6a911a2de99e59ef670a4d0b1df ]
tcf_ct_handle_fragments() runs its header sanity checks before handing anything to the defragmentation engine:
if (family == NFPROTO_IPV4) err = tcf_ct_ipv4_is_fragment(skb, &frag); else err = tcf_ct_ipv6_is_fragment(skb, &frag); if (err || !frag) return err;
tcf_ct_ipv4_is_fragment() returns -EINVAL or -ENOMEM; tcf_ct_ipv6_is_fragment() adds -EPROTO when ipv6_find_hdr() fails. None of them frees or queues the skb, so on that path the caller still owns it.
tcf_ct_act() however funnels every non-zero return into the ownership-transfer exit:
err = tcf_ct_handle_fragments(net, skb, family, p->zone, &defrag); if (err) goto out_frag; ... out_frag: if (err != -EINPROGRESS) tcf_action_inc_drop_qstats(&c->common); return TC_ACT_CONSUMED;
TC_ACT_CONSUMED means the action took ownership of the skb, so no caller frees it - sch_handle_ingress(), sch_handle_egress() and tcf_qevent_handle() all deliberately skip the free for that verdict. The skb is therefore orphaned: one sk_buff plus its data buffer is leaked per malformed packet, unbounded. Note the drop counter is already incremented for these errors, so the statistics claim a drop that never happens.
Three different ownership states reach out_frag: today - the skb may be queued by the defrag engine (-EINPROGRESS), already freed by nf_ct_handle_fragments(), or still owned by us. Tell the caller which of those it is, and free the packet ourselves in the last case, which restores the TC_ACT_SHOT behaviour that predated the Fixes: commit.
Reproduced on v7.2-rc6 with a 54-byte frame carrying a 40-byte IPv6 header with nexthdr = 0 (hop-by-hop) and nothing after it, on a clsact ingress chain with "action ct". kmemleak reports one leaked 232-byte skbuff_head_cache object plus its 704-byte data buffer per packet; with this patch it reports none.
--- net/sched/act_ct.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-)
net/sched/act_ct.c +25 -4
@@ -696,8 +696,15 @@ static int tcf_ct_ipv6_is_fragment(strucreturn 0 ; } +/* On error, tells the caller whether it still owns @skb and must free it +* itself. @skb is ours only when the header checks below reject the packet +* before it is handed to the defragmentation engine; once nf_ct_handle_ +* fragments() has been called the skb is either queued (-EINPROGRESS) or has +* already been freed by it. +*/ static int tcf_ct_handle_fragments (struct net *net,struct sk_buff *skb, -u8 family,u16 zone,bool *defrag) +u8 family,u16 zone,bool *defrag, +bool *skb_is_ours) {enum ip_conntrack_info ctinfo;struct tc_skb_cb cb;
@@ -714,8 +721,12 @@ static int tcf_ct_handle_fragments(struc err =tcf_ct_ipv4_is_fragment (skb, &frag); else err =tcf_ct_ipv6_is_fragment (skb, &frag); -if (err || !frag) +if (err) { + *skb_is_ours = true;return err; + } +if (!frag) +return 0 ; cb = *tc_skb_cb (skb);
@@ -961,6 +972,7 @@ static int tcf_ct_act(struct sk_buff *skstruct nf_hook_state state;int nh_ofs, err, retval;struct tcf_ct_params *p; +bool skb_is_ours = false;bool skip_add = false;bool defrag = false;struct nf_conn *ct;
@@ -997,9 +1009,18 @@ static int tcf_ct_act(struct sk_buff *sk*/ nh_ofs =skb_network_offset (skb);skb_pull_rcsum (skb, nh_ofs); - err =tcf_ct_handle_fragments (net, skb, family, p->zone, &defrag); -if (err) + err =tcf_ct_handle_fragments (net, skb, family, p->zone, &defrag, + &skb_is_ours); +if (err) { +/* The skb is still ours only when the header checks rejected +* it; returning TC_ACT_CONSUMED for such a packet would leak +* it, since no caller frees an skb it was told it no longer +* owns. +*/ +if (skb_is_ours) + goto drop; goto out_frag; + } err =tcf_ct_skb_network_trim (skb, family);if (err)
Greg Kroah-Hartman
maintainerPATCH 254/272 net: atlantic: free stranded TX buffers on ring deinit
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yangyu Chen <[email protected]>
[ Upstream commit 452636ea5410a96e02ebaaf80b21e3620b98e0dd ]
aq_vec_deinit() drains the TX rings with a single aq_ring_tx_clean() call, which frees at most AQ_CFG_TX_CLEAN_BUDGET (256) descriptors and stops at hw_head, which no longer moves once aq_vec_stop() has stopped the hardware and NAPI. Completed descriptors beyond the budget and everything still posted in [hw_head, sw_tail) keep their skb or xdp_frame when the interface goes down: aq_vec_ring_free() then frees the buffer ring and the references are lost for good.
Today this is a silent memory leak on every interface down under TX/XDP_TX load. With the conversion of the RX path to page_pool posted for net-next it becomes much more visible: XDP_TX frames carry fragment references on the RX ring's page_pool, so a single stranded frame keeps the pool's inflight count above zero forever. page_pool_destroy() then never completes, the pool is leaked together with its pages, and "page_pool_release_retry() stalled pool shutdown" is warned every 60 seconds from that point on, on every ifdown, XDP detach or ring resize under XDP_TX load.
Bring back aq_ring_tx_deinit() as it was before the removal and use it for teardown again, with one extension: TX rings can hold xdp_frames nowadays, so release those too. They are returned with xdp_return_frame() since this runs in process context.
--- drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 25 +++++++++++++++++++++++ drivers/net/ethernet/aquantia/atlantic/aq_ring.h | 1 drivers/net/ethernet/aquantia/atlantic/aq_vec.c | 2 - 3 files changed, 27 insertions(+), 1 deletion(-)
drivers/net/ethernet/aquantia/atlantic/aq_ring.c +25 -0
@@ -314,6 +314,31 @@ bool aq_ring_tx_clean(struct aq_ring_s *return !!budget; } +void aq_ring_tx_deinit (struct aq_ring_s *self) +{ +if (!self) +return ; + +for (; self->sw_head != self->sw_tail; + self->sw_head =aq_ring_next_dx (self, self->sw_head)) { +struct aq_ring_buff_s *buff = &self->buff_ring[self->sw_head]; +struct device *ndev =aq_nic_get_dev (self->aq_nic); + +if (buff->is_mapped) { +if (buff->is_sop) { +dma_unmap_single (ndev, buff->pa, buff->len, +DMA_TO_DEVICE ); + }else { +dma_unmap_page (ndev, buff->pa, buff->len, +DMA_TO_DEVICE ); + } + } + +if (buff->is_eop && buff->skb) +dev_kfree_skb_any (buff->skb); + } +} +static void aq_rx_checksum (struct aq_ring_s *self,struct aq_ring_buff_s *buff,struct sk_buff *skb)
drivers/net/ethernet/aquantia/atlantic/aq_ring.h +1 -0
@@ -182,6 +182,7 @@ void aq_ring_update_queue_state(struct avoid aq_ring_queue_wake (struct aq_ring_s *ring);void aq_ring_queue_stop (struct aq_ring_s *ring);bool aq_ring_tx_clean (struct aq_ring_s *self); +void aq_ring_tx_deinit (struct aq_ring_s *self); int aq_ring_rx_clean(struct aq_ring_s *self, struct napi_struct *napi, int *work_done,
drivers/net/ethernet/aquantia/atlantic/aq_vec.c +1 -1
@@ -270,7 +270,7 @@ void aq_vec_deinit(struct aq_vec_s *selffor (i =0U ; self->tx_rings > i; ++i) { ring = self->ring[i]; -aq_ring_tx_clean (&ring[AQ_VEC_TX_ID ]); +aq_ring_tx_deinit (&ring[AQ_VEC_TX_ID ]);aq_ring_rx_deinit (&ring[AQ_VEC_RX_ID ]); }
Greg Kroah-Hartman
maintainerPATCH 255/272 net/smc: rdma write inline if qp has sufficient inline space
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guangguan Wang <[email protected]>
commit 793a7df63071eb09e5b88addf2a569d7bfd3c973 upstream.
Rdma write with inline flag when sending small packages, whose length is shorter than the qp's max_inline_data, can help reducing latency.
In my test environment, which are 2 VMs running on the same physical host and whose NICs(ConnectX-4Lx) are working on SR-IOV mode, qperf shows 0.5us-0.7us improvement in latency.
Test command:
server: smc_run taskset -c 1 qperf
client: smc_run taskset -c 1 qperf <server ip> -oo \
msg_size:1:2K:*2 -t 30 -vu tcp_lat
The results shown below:
msgsize before after 1B 11.2 us 10.6 us (-0.6 us) 2B 11.2 us 10.7 us (-0.5 us) 4B 11.3 us 10.7 us (-0.6 us) 8B 11.2 us 10.6 us (-0.6 us) 16B 11.3 us 10.7 us (-0.6 us) 32B 11.3 us 10.6 us (-0.7 us) 64B 11.2 us 11.2 us (0 us) 128B 11.2 us 11.2 us (0 us) 256B 11.2 us 11.2 us (0 us) 512B 11.4 us 11.3 us (-0.1 us) 1KB 11.4 us 11.5 us (0.1 us) 2KB 11.5 us 11.5 us (0 us)
Stable-dep-of: 5d9686af2976 ("net: smc: fix splice entry lifetime imbalance in smc_rx_splice")
--- net/smc/smc_tx.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
net/smc/smc_tx.c +12 -5
@@ -333,12 +333,20 @@ static int smcr_tx_rdma_writes(struct smint rc;for (dstchunk =0 ; dstchunk <2 ; dstchunk++) { -struct ib_sge *sge = - wr_rdma_buf->wr_tx_rdma[dstchunk].wr.sg_list; +struct ib_rdma_wr *wr = &wr_rdma_buf->wr_tx_rdma[dstchunk]; +struct ib_sge *sge = wr->wr.sg_list; +u64 base_addr = dma_addr; + +if (dst_len < link->qp_attr.cap.max_inline_data) { + base_addr = (uintptr_t )conn->sndbuf_desc->cpu_addr; + wr->wr.send_flags |=IB_SEND_INLINE ; + }else { + wr->wr.send_flags &= ~IB_SEND_INLINE ; + } num_sges =0 ;for (srcchunk =0 ; srcchunk <2 ; srcchunk++) { - sge[srcchunk].addr = dma_addr + src_off; + sge[srcchunk].addr = base_addr + src_off; sge[srcchunk].length = src_len; num_sges++;
@@ -352,8 +360,7 @@ static int smcr_tx_rdma_writes(struct sm src_len = dst_len - src_len;/* remainder */ src_len_sum += src_len; } - rc =smc_tx_rdma_write (conn, dst_off, num_sges, - &wr_rdma_buf->wr_tx_rdma[dstchunk]); + rc =smc_tx_rdma_write (conn, dst_off, num_sges, wr);if (rc)return rc;if (dst_len_sum == len)
Greg Kroah-Hartman
maintainerPATCH 256/272 net: smc: fix splice entry lifetime imbalance in smc_rx_splice
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daming Li <[email protected]>
commit 5d9686af2976741bbd79b150d1c9e60b81e7f12e upstream.
smc_rx_splice() passes pages to splice_to_pipe() before taking the references that cover the lifetime of each splice entry. In the VM-backed RMB path, splice_to_pipe() may drop unqueued entries through smc_rx_spd_release(), while queued entries are released later via the pipe buffer callback.
The old post-splice accounting also derives the number of queued VM pages from an offset mutated while building the descriptor, and a multi-page splice pairs one sock_hold() with multiple sock_put() calls.
Take the page and socket references for every candidate entry before splice_to_pipe(), and drop the matching private state, page reference, and socket reference from smc_rx_spd_release() for entries that never get queued. This fixes a refcount imbalance that can underflow page refcounts and trigger a use-after-free.
--- net/smc/smc_rx.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
net/smc/smc_rx.c +8 -4
@@ -145,7 +145,12 @@ static const struct pipe_buf_operationsstatic void smc_rx_spd_release (struct splice_pipe_desc *spd,unsigned int i) { +struct smc_spd_priv *priv = (struct smc_spd_priv *)spd->partial[i].private; +struct sock *sk = &priv->smc->sk; + +kfree (priv);put_page (spd->pages[i]); +sock_put (sk); } static int smc_rx_splice(struct pipe_inode_info *pipe, char *src, size_t len,
@@ -165,6 +170,8 @@ static int smc_rx_splice(struct pipe_ino partial.len = len; partial.private = (unsigned long )priv; +get_page (smc->conn.rmb_desc->pages); +sock_hold (&smc->sk); spd.nr_pages_max =1 ; spd.nr_pages =1 ; spd.pages = &smc->conn.rmb_desc->pages;
@@ -173,11 +180,8 @@ static int smc_rx_splice(struct pipe_ino spd.spd_release = smc_rx_spd_release; bytes =splice_to_pipe (pipe, &spd); -if (bytes >0 ) { -sock_hold (&smc->sk); -get_page (smc->conn.rmb_desc->pages); +if (bytes >0 )atomic_add (bytes, &smc->conn.splice_pending); - }return bytes; }
Greg Kroah-Hartman
maintainerPATCH 257/272 arm64: tegra: Add EL2 virtual timer interrupt for Tegra194
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jon Hunter <[email protected]>
[ Upstream commit a7c28483fd57dd0e1487024af70622315320774b ]
Commit d87773de9efe ("clocksource/drivers/arm_arch_timer: Default to EL2 virtual timer when running VHE") updated the ARM arch timer driver to use the virtual timer by default if the CPU is running at EL2 with VHE enabled. If the CPU is running at EL2 with VHE enabled but there is no interrupt provided for the virtual timer, then the following warning is displayed:
arch_timer: [Firmware Bug]: VHE-capable CPU without EL2 virtual timer
interrupt
This warning is observed on Tegra194 platforms. Tegra194 SoC includes NVIDIA Carmel ARM v8.2 CPUs and support an EL2 virtual timer. Fix the above warning by adding the PPI for the EL2 virtual timer interrupt for Tegra194.
--- arch/arm64/boot/dts/nvidia/tegra194.dtsi | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/boot/dts/nvidia/tegra194.dtsi +2 -0
@@ -2586,6 +2586,8 @@ timer { <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, <GIC_PPI 10 + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 15 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; interrupt-parent = <&gic>; always-on;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 258/272 crypto: ccm - Set rfc4309 maxauthsize from child
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herbert Xu <[email protected]>
[ Upstream commit 438f4896f78f69ec73d5f32d2c024193f1223569 ]
Set the maxauthsize of rfc4309 using that of the child algorithm.
--- crypto/ccm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
crypto/ccm.c +1 -1
@@ -753,7 +753,7 @@ static int crypto_rfc4309_create(struct crypto_template *tmpl, inst->alg.ivsize =8 ; inst->alg.chunksize =crypto_aead_alg_chunksize (alg); - inst->alg.maxauthsize =16 ; + inst->alg.maxauthsize =crypto_aead_alg_maxauthsize (alg); inst->alg.base.cra_ctxsize =sizeof (struct crypto_rfc4309_ctx );
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 259/272 netfilter: ipset: fix refcount race between list:set GC and swap
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiang Mei (Microsoft) <[email protected]>
[ Upstream commit 0c88868271653537ed443272dd8e7d13634d214b ]
__ip_set_put_byindex() resolved the index to a set pointer under RCU, then took ip_set_ref_lock in __ip_set_put() to decrement set->ref. ip_set_swap() holds that same lock while swapping both the ip_set_list slots and the two sets' ref counters, so it can interleave between the dereference and the lock acquisition, leaving the caller to decrement a set whose reference already moved to the other index and hit BUG_ON(set->ref == 0). list_set_gc() reaches this from timer softirq, which the nfnl mutex does not serialize against swap: an expiring list:set member calls list_set_del() -> ip_set_put_byindex() while IPSET_CMD_SWAP runs on the referenced sets.
Resolve the index and decrement under ip_set_ref_lock, as ip_set_swap() already does, keeping the refcount tied to the index rather than to a stale set pointer.
kernel BUG at net/netfilter/ipset/ip_set_core.c:685!
Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI RIP: 0010:ip_set_put_byindex (net/netfilter/ipset/ip_set_core.c:870) Call Trace: <IRQ> list_set_del (net/netfilter/ipset/ip_set_list_set.c:159) set_cleanup_entries (net/netfilter/ipset/ip_set_list_set.c:181) list_set_gc (net/netfilter/ipset/ip_set_list_set.c:578) call_timer_fn (kernel/time/timer.c:1748) __run_timers (kernel/time/timer.c:1799 kernel/time/timer.c:2374) run_timer_softirq (kernel/time/timer.c:2405) </IRQ> Kernel panic - not syncing: Fatal exception in interrupt
--- net/netfilter/ipset/ip_set_core.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
net/netfilter/ipset/ip_set_core.c +13 -6
@@ -679,11 +679,18 @@ __ip_set_get(struct ip_set *set) }static void -__ip_set_put (struct ip_set *set) +__ip_set_put_locked (struct ip_set *set) { -write_lock_bh (&ip_set_ref_lock); +lockdep_assert_held (&ip_set_ref_lock);BUG_ON (set->ref ==0 ); set->ref--; +} + +static void +__ip_set_put (struct ip_set *set) +{ +write_lock_bh (&ip_set_ref_lock); +__ip_set_put_locked (set);write_unlock_bh (&ip_set_ref_lock); }
@@ -856,11 +863,11 @@ __ip_set_put_byindex(struct ip_set_net *inst, ip_set_id_t index) {struct ip_set *set; -rcu_read_lock (); - set =rcu_dereference (inst->ip_set_list)[index]; +write_lock_bh (&ip_set_ref_lock); + set =ip_set (inst, index);if (set) -__ip_set_put (set); -rcu_read_unlock (); +__ip_set_put_locked (set); +write_unlock_bh (&ip_set_ref_lock); }void
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 260/272 netfilter: nf_tables_offload: suppress WARN_ON_ONCE for ENOMEM in abort path
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexey Velichayshiy <[email protected]>
[ Upstream commit d02f592064347e0c1e0d84f24941ad338838cc48 ]
In nft_flow_rule_offload_abort(), WARN_ON_ONCE(err) is triggered on every error during rollback, including -ENOMEM. Memory allocation failures are expected under low-memory conditions and do not indicate a kernel bug.
Trace for example:nft_flow_offload_chain() // FLOW_BLOCK_BIND
nft_flow_block_chain()
nft_chain_offload_cmd()
nft_block_offload_cmd()
->ndo_setup_tc()
nsim_setup_tc()
flow_block_cb_setup_simple()
flow_block_cb_alloc() // fails to -ENOMEMThe warning was reproduced on the 5.10 stable kernel under memory pressure via fault injection, but the underlying bug exists in mainline as well, as demonstrated by the ENOMEM trace above. The following splat was triggered during nf_tables transaction processing:
WARNING: CPU: 0 PID: 8567 at net/netfilter/nf_tables_offload.c:532 nft_flow_rule_offload_abort net/netfilter/nf_tables_offload.c:532 [inline] WARNING: CPU: 0 PID: 8567 at net/netfilter/nf_tables_offload.c:532 nft_flow_rule_offload_commit+0x971/0xcd0 net/netfilter/nf_tables_offload.c:591 Modules linked in: CPU: 0 PID: 8567 Comm: syz-executor.0 Not tainted 5.10.260-syzkaller #0 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014 RIP: 0010:nft_flow_rule_offload_abort net/netfilter/nf_tables_offload.c:532 [inline] RIP: 0010:nft_flow_rule_offload_commit+0x971/0xcd0 net/netfilter/nf_tables_offload.c:591 Call Trace: nf_tables_commit+0x3bd/0x4bd0 net/netfilter/nf_tables_api.c:8604 nfnetlink_rcv_batch+0xb1e/0x1f20 net/netfilter/nfnetlink.c:509 nfnetlink_rcv_skb_batch net/netfilter/nfnetlink.c:579 [inline] nfnetlink_rcv+0x3b3/0x420 net/netfilter/nfnetlink.c:597 netlink_unicast_kernel net/netlink/af_netlink.c:1314 [inline] netlink_unicast+0x6cd/0xa00 net/netfilter/af_netlink.c:1340 netlink_sendmsg+0x906/0xe10 net/netfilter/af_netlink.c:1919 sock_sendmsg_nosec net/socket.c:651 [inline] __sock_sendmsg+0x155/0x190 net/socket.c:663 ____sys_sendmsg+0x705/0x870 net/socket.c:2379 ___sys_sendmsg+0x100/0x170 net/socket.c:2433 __sys_sendmsg+0xe9/0x1c0 net/socket.c:2462 do_syscall_64+0x33/0x40 arch/x86/entry/common.c:46 entry_SYSCALL_64_after_hwframe+0x67/0xd1
Change the condition to WARN_ON_ONCE(err && err != -ENOMEM) so that warnings are only emitted for unexpected errors. This aligns with the common kernel practice of not warning on -ENOMEM.
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
--- net/netfilter/nf_tables_offload.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/netfilter/nf_tables_offload.c +1 -1
@@ -550,7 +550,7 @@ static void nft_flow_rule_offload_abort(struct net *net,break ; } -if (WARN_ON_ONCE (err)) +if (WARN_ON_ONCE (err && err != -ENOMEM ))break ; } }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 261/272 netfilter: flowtable: publish GC-visible tuple last
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jérémy Jean <[email protected]>
[ Upstream commit 2014ac62df9d45bb9a004a043e85df7be09ed780 ]
nf_flow_table_iterate() only treats original-direction tuple nodes as owning entries. Publishing the original node first lets GC observe and free a flow while flow_offload_add() is still inserting the reply node. Publish the reply node first and the original node last so GC never sees a partially installed flow.
KASAN can trigger slab-use-after-free read and write reports in the flowtable/rhashtable path (rht_deferred_worker, jhash, flow_offload_del, flow_offload_lookup, etc.).
--- net/netfilter/nf_flow_table_core.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
net/netfilter/nf_flow_table_core.c +4 -3
@@ -279,17 +279,18 @@ int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow) flow->timeout = nf_flowtable_time_stamp +flow_offload_get_timeout (flow); err =rhashtable_insert_fast (&flow_table->rhashtable, - &flow->tuplehash[0 ].node, + &flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY ].node, nf_flow_offload_rhash_params);if (err <0 )return err; +/* GC only iterates original-direction entries; publish original last. */ err =rhashtable_insert_fast (&flow_table->rhashtable, - &flow->tuplehash[1 ].node, + &flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL ].node, nf_flow_offload_rhash_params);if (err <0 ) {rhashtable_remove_fast (&flow_table->rhashtable, - &flow->tuplehash[0 ].node, + &flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY ].node, nf_flow_offload_rhash_params);return err; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 262/272 netfilter: ipset: fix list type element drift bug
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
[ Upstream commit 4cbd69766b35a089664cadb1f613bb85f7ef77a9 ]
If list_set_uadd() calls list_set_replace() to swap an expired entry, the element count remains the same, therefore the increment must be elided.
--- net/netfilter/ipset/ip_set_list_set.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
net/netfilter/ipset/ip_set_list_set.c +5 -2
@@ -301,9 +301,12 @@ list_set_uadd(struct ip_set *set, void *value, const struct ip_set_ext *ext, e->set = set;INIT_LIST_HEAD (&e->list);list_set_init_extensions (set, ext, e); -if (n) +if (n) {list_set_replace (set, e, n); -else if (next) +return 0 ; + } + +if (next)list_add_tail_rcu (&e->list, &next->list);else if (prev)list_add_rcu (&e->list, &prev->list);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 263/272 net: packet: fix wrong transport_header when sending VLAN-tagged frame
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wei Fang <[email protected]>
[ Upstream commit 01fdecc0480d916c799dbee584833a4a37e94d06 ]
In packet_parse_headers(), when processing a VLAN-tagged frame, skb_set_network_header() is called to advance network_header past the VLAN tag to the inner protocol header. skb_probe_transport_header() is then called with skb->protocol still set to the outer VLAN EtherType (e.g. ETH_P_8021Q), while nhoff (derived from skb_network_offset()) already points past the VLAN tag to the inner protocol header.
In __skb_flow_dissect(), proto is initialized to ETH_P_8021Q and nhoff points past the VLAN tag. When the dissector hits case ETH_P_8021Q, it reads a struct vlan_hdr at nhoff via __skb_header_pointer(), but that offset contains the inner protocol header (e.g. an IP header). The bytes are misinterpreted as a VLAN header, yielding a garbage encapsulated EtherType that matches no known protocol. The dissector returns false, so skb_probe_transport_header() never calls skb_set_transport_header(), leaving transport_header at its uninitialized sentinel value (~0U).
Move skb_probe_transport_header() to before skb_set_network_header(). At the time skb_probe_transport_header() is called, network_header still points to the VLAN header, so nhoff correctly points to the VLAN header. The flow dissector can then parse the VLAN header, extract the inner EtherType, and advance nhoff to the inner protocol header, allowing transport_header to be set correctly.
--- net/packet/af_packet.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/packet/af_packet.c +2 -2
@@ -1949,13 +1949,13 @@ static void packet_parse_headers(struct sk_buff *skb, struct socket *sock) sock->type == SOCK_RAW) skb->protocol =dev_parse_header_protocol (skb); +skb_probe_transport_header (skb); +/* Move network header to the right position for VLAN tagged packets */ if (likely (skb->dev->type ==ARPHRD_ETHER ) &ð_type_vlan (skb->protocol) &&vlan_get_protocol_and_depth (skb, skb->protocol, &depth) !=0 )skb_set_network_header (skb, depth); - -skb_probe_transport_header (skb); }/*
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 264/272 ASoC: xilinx: formatter_pcm: pass aud_drv_data to irq handlers
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rosen Penev <[email protected]>
[ Upstream commit f12afefb7b01f94d6d66d397f323a9914edbf70e ]
The irq handlers take a struct device pointer and call dev_get_drvdata() to obtain the driver data. However, the driver data is only set at the end of probe, after devm_request_irq(), so an interrupt taken in between causes the handlers to pass a NULL pointer to readl() and crash.
Pass the private data directly as the devm_request_irq() argument instead of the device pointer, matching what the handlers expect.
--- sound/soc/xilinx/xlnx_formatter_pcm.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
sound/soc/xilinx/xlnx_formatter_pcm.c +4 -6
@@ -281,8 +281,7 @@ static irqreturn_t xlnx_mm2s_irq_handler(int irq, void *arg) {u32 val;void __iomem *reg; -struct device *dev = arg; -struct xlnx_pcm_drv_data *adata =dev_get_drvdata (dev); +struct xlnx_pcm_drv_data *adata = arg; reg = adata->mmio +XLNX_MM2S_OFFSET +XLNX_AUD_STS ; val =readl (reg);
@@ -300,8 +299,7 @@ static irqreturn_t xlnx_s2mm_irq_handler(int irq, void *arg) {u32 val;void __iomem *reg; -struct device *dev = arg; -struct xlnx_pcm_drv_data *adata =dev_get_drvdata (dev); +struct xlnx_pcm_drv_data *adata = arg; reg = adata->mmio +XLNX_S2MM_OFFSET +XLNX_AUD_STS ; val =readl (reg);
@@ -637,7 +635,7 @@ static int xlnx_formatter_pcm_probe(struct platform_device *pdev) } ret =devm_request_irq (dev, aud_drv_data->mm2s_irq, xlnx_mm2s_irq_handler,0 , -"xlnx_formatter_pcm_mm2s_irq" , dev); +"xlnx_formatter_pcm_mm2s_irq" , aud_drv_data);if (ret) {dev_err (dev,"xlnx audio mm2s irq request failed\n" ); goto clk_err;
@@ -664,7 +662,7 @@ static int xlnx_formatter_pcm_probe(struct platform_device *pdev) ret =devm_request_irq (dev, aud_drv_data->s2mm_irq, xlnx_s2mm_irq_handler,0 ,"xlnx_formatter_pcm_s2mm_irq" , - dev); + aud_drv_data);if (ret) {dev_err (dev,"xlnx audio s2mm irq request failed\n" ); goto clk_err;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 265/272 af_packet: Dont send zero-byte data in tpacket_snd().
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 6bcd76c134c55c697148acb5c0194e9666abdf84 ]
syzbot reported a WARNING in __dev_queue_xmit() triggered via tpacket_snd():
skb_assert_len
WARNING: at include/linux/skbuff.h:2753 skb_assert_len WARNING: at __dev_queue_xmit+0x21bc/0x4970 net/core/dev.c:4781 Call Trace: <TASK> dev_queue_xmit include/linux/netdevice.h:3448 [inline] packet_xmit+0x243/0x310 net/packet/af_packet.c:276 tpacket_snd net/packet/af_packet.c:2907 [inline] packet_sendmsg+0x28d6/0x4eb0 net/packet/af_packet.c:3134
When sending 0-byte packets via TPACKET ring buffer on devices with no hard header (e.g. dev->hard_header_len == 0), tpacket_fill_skb() populates an skb with skb->len == 0 and returns 0. tpacket_snd() then forwards this empty skb to packet_xmit(), causing __dev_queue_xmit() to hit skb_assert_len(skb).
Similar checks exist in packet_snd() via commit dc633700f00f ("net/af_packet: check len when min_header_len equals to 0") and in packet_sendmsg_spkt() via commit 6a341729fb31 ("af_packet: Don't send zero-byte data in packet_sendmsg_spkt().").
Return -EINVAL in tpacket_fill_skb() when skb->len is zero to reject zero-length packets in tpacket_snd().
--- net/packet/af_packet.c | 3 +++ 1 file changed, 3 insertions(+)
net/packet/af_packet.c +3 -0
@@ -2653,6 +2653,9 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, len = ((to_write > len_max) ? len_max : to_write); } +if (unlikely (!skb->len)) +return -EINVAL ; +packet_parse_headers (skb, sock);return tp_len;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 266/272 net: ethernet: ti: am65-cpsw-nuss: Fix port_id extraction from SRC TAG
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Siddharth Vadapalli <[email protected]>
[ Upstream commit 36a05d2820077bb3955acb8111e1041d39148037 ]
On the packet reception path, the ID of the MAC Port on which the packet was received, is embedded in the RX DMA Descriptor's metadata. The ID is extracted using the helper function cppi5_desc_get_tags_ids() which fills in the 16-bit Source Tag into the 'port_id' variable. However, it is only the lower 8-bits of the 16-bit Source Tag that represent the MAC Port ID, while the upper 8-bits are Hardware-Reserved and carry an arbitrary value. With the existing logic, sporadic kernel crash is observed due to the subsequent driver code accessing out-of-bound memory because of an invalid port_id.
Hence, fix the port_id extraction logic to use only the lower 8-bits of the Source Tag as the MAC Port ID.
--- drivers/net/ethernet/ti/am65-cpsw-nuss.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/ethernet/ti/am65-cpsw-nuss.c +2 -0
@@ -809,6 +809,8 @@ static int am65_cpsw_nuss_rx_packets(struct am65_cpsw_common *common,k3_udma_glue_rx_cppi5_to_dma_addr (rx_chn->rx_chn, &buf_dma); pkt_len =cppi5_hdesc_get_pktlen (desc_rx);cppi5_desc_get_tags_ids (&desc_rx->hdr, &port_id,NULL ); +/* Port ID is contained in the lower 8-bits of the 16-bit Source Tag */ + port_id &=0xFF ;dev_dbg (dev,"%s rx port_id:%d\n" , __func__, port_id); port =am65_common_get_port (common, port_id); ndev = port->ndev;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 267/272 net/x25: fix use-after-free of the socket by its timers
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baul Lee <[email protected]>
commit 2195424c3da2ef1829a63b807e3a900a90e57d85 upstream.
The x25 timers are armed with mod_timer() and cancelled with timer_delete(), so a pending timer holds no reference on the socket and a cancel does not wait for a callback already running on another CPU.
x25_heartbeat_expiry() also rearms unconditionally, so it can reinstall sk->sk_timer after __x25_destroy_socket() has passed its cancel point. The following __sock_put() frees the socket while the timer is still queued, and the next expiry uses freed memory. KASAN reports a slab-use-after-free on the kmalloc-2k object freed by close().
timer_delete_sync() cannot be used here: x25_heartbeat_expiry() and x25_timer_expiry() both reach the cancels from inside the timer they would wait on, through __x25_destroy_socket() and x25_disconnect().
Arm the timers with sk_reset_timer() and cancel them with sk_stop_timer() so that an armed timer owns a reference, and release it in both expiry handlers. Rearm the heartbeat only while sk_hashed(sk) is still true, since __x25_destroy_socket() unlinks the socket before dropping it. Arm the deferred destroy timer the same way and drop its reference in x25_destroy_timer().
Reproduced on net with KASAN, with the heartbeat period shortened so the window recurs. With this patch the reproducer no longer triggers a report and /proc/net/x25 drains.
Discovered by XBOW, triaged by Baul Lee <[email protected]>
--- net/x25/af_x25.c | 4 ++-- net/x25/x25_timer.c | 25 ++++++++++++++++--------- 2 files changed, 18 insertions(+), 11 deletions(-)
net/x25/af_x25.c +2 -2
@@ -362,6 +362,7 @@ static void x25_destroy_timer(struct timstruct sock *sk =from_timer (sk, t, sk_timer);x25_destroy_socket_from_timer (sk); +sock_put (sk); }/*
@@ -397,9 +398,8 @@ static void __x25_destroy_socket(structif (sk_has_allocations (sk)) {/* Defer: outstanding buffers */ - sk->sk_timer.expires = jiffies +10 *HZ ; sk->sk_timer.function = x25_destroy_timer; -add_timer (&sk->sk_timer); +sk_reset_timer (sk, &sk->sk_timer, jiffies +10 *HZ ); }else {/* drop last reference so sock_put will free */ __sock_put (sk);
net/x25/x25_timer.c +16 -9
@@ -36,45 +36,45 @@ void x25_init_timers(struct sock *sk)void x25_start_heartbeat (struct sock *sk) { -mod_timer (&sk->sk_timer, jiffies +5 *HZ ); +sk_reset_timer (sk, &sk->sk_timer, jiffies +5 *HZ ); }void x25_stop_heartbeat (struct sock *sk) { -del_timer (&sk->sk_timer); +sk_stop_timer (sk, &sk->sk_timer); }void x25_start_t2timer (struct sock *sk) {struct x25_sock *x25 =x25_sk (sk); -mod_timer (&x25->timer, jiffies + x25->t2); +sk_reset_timer (sk, &x25->timer, jiffies + x25->t2); }void x25_start_t21timer (struct sock *sk) {struct x25_sock *x25 =x25_sk (sk); -mod_timer (&x25->timer, jiffies + x25->t21); +sk_reset_timer (sk, &x25->timer, jiffies + x25->t21); }void x25_start_t22timer (struct sock *sk) {struct x25_sock *x25 =x25_sk (sk); -mod_timer (&x25->timer, jiffies + x25->t22); +sk_reset_timer (sk, &x25->timer, jiffies + x25->t22); }void x25_start_t23timer (struct sock *sk) {struct x25_sock *x25 =x25_sk (sk); -mod_timer (&x25->timer, jiffies + x25->t23); +sk_reset_timer (sk, &x25->timer, jiffies + x25->t23); }void x25_stop_timer (struct sock *sk) { -del_timer (&x25_sk (sk)->timer); +sk_stop_timer (sk, &x25_sk (sk)->timer); }unsigned long x25_display_timer (struct sock *sk)
@@ -108,7 +108,7 @@ static void x25_heartbeat_expiry(struct sock_flag(sk, SOCK_DEAD))) {bh_unlock_sock (sk);x25_destroy_socket_from_timer (sk); -return ; + goto out; }break ;
@@ -120,8 +120,14 @@ static void x25_heartbeat_expiry(structbreak ; } restart_heartbeat: -x25_start_heartbeat (sk); +/* Do not rearm once __x25_destroy_socket() has unlinked the socket: +* it is past its cancel point and owns the teardown from there on. +*/ +if (sk_hashed (sk)) +x25_start_heartbeat (sk);bh_unlock_sock (sk); +out: +sock_put (sk); }/*
@@ -166,4 +172,5 @@ static void x25_timer_expiry(struct time }else x25_do_timer_expiry (sk);bh_unlock_sock (sk); +sock_put (sk); }
Greg Kroah-Hartman
maintainerPATCH 268/272 binfmt_misc: use exe_file_deny_write_access() for the interpreter clone
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <[email protected]>
commit fa5990ca8fd917003e526036bcc50413edb9722c upstream.
For MISC_FMT_OPEN_FILE entries load_misc_binary() clones the registered interpreter file and denies write access to the clone via plain deny_write_access(). The clone is installed as bprm->interpreter and later released by the exec machinery through exe_file_allow_write_access() which skips the i_writecount increment for files with FMODE_FSNOTIFY_HSM set.
The deny and allow side can therefore come to different conclusions when pre-content watches are in play: if a pre-content watch is added to the interpreter after registration every subsequent exec through that entry takes a write denial on the clone that is never paired with a write allowance, driving the interpreter inode's i_writecount further down with each exec and leaving the interpreter unwritable even after the entry and all its users are gone.
Take the write denial via exe_file_deny_write_access() so both sides of the pairing base their decision on the same file mode, and propagate failure instead of silently ignoring it: an interpreter that is concurrently open for writing now fails the exec with ETXTBSY, exactly like an interpreter freshly opened via open_exec() would.
--- fs/binfmt_misc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
fs/binfmt_misc.c +8 -2
@@ -220,8 +220,14 @@ static int load_misc_binary(struct linuxif (fmt->flags &MISC_FMT_OPEN_FILE ) { interp_file =file_clone_open (fmt->interp_file); -if (!IS_ERR (interp_file)) -deny_write_access (interp_file); +if (!IS_ERR (interp_file)) { +int err =exe_file_deny_write_access (interp_file); + +if (err) { +fput (interp_file); + interp_file =ERR_PTR (err); + } + } }else { interp_file =open_exec (fmt->interpreter); }
Greg Kroah-Hartman
maintainerPATCH 269/272 udmabuf: Ensure to perform cache synchronisation in begin_cpu_udmabuf()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robert Mader <[email protected]>
commit 1d0e25c1ddf2063c499264fb2ba0fa6a3e4f8a00 upstream.
The message of commit 504e2b4ab97a ("dma-buf/udmabuf: skip redundant cpu sync to fix cacheline EEXIST warning") says:
Quoted 4 lines
The CPU sync at map/unmap time is also redundant for udmabuf:
begin_cpu_udmabuf()andend_cpu_udmabuf()already perform explicit cache synchronization via dma_sync_sgtable_for_cpu/device() when CPU access is requested through the dma-buf interface.
This, however, does not apply to the first time begin_cpu_udmabuf() is called on an udmabuf, in which case the implementation previously relied on get_sg_table() to perform the cache synchronisation.
Ensure to call dma_sync_sgtable_for_cpu() in that case as well.
--- drivers/dma-buf/udmabuf.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/dma-buf/udmabuf.c +5 -4
@@ -127,21 +127,22 @@ static int begin_cpu_udmabuf(struct dma_ {struct udmabuf *ubuf = buf->priv;struct device *dev = ubuf->device->this_device; -int ret =0 ;if (!ubuf->sg) { ubuf->sg =get_sg_table (dev, buf, direction);if (IS_ERR (ubuf->sg)) { +int ret; + ret =PTR_ERR (ubuf->sg); ubuf->sg =NULL ; +return ret; }else { ubuf->sg_dir = direction; } - }else { -dma_sync_sgtable_for_cpu (dev, ubuf->sg, direction); } -return ret; +dma_sync_sgtable_for_cpu (dev, ubuf->sg, direction); +return 0 ; } static int end_cpu_udmabuf(struct dma_buf *buf,
Greg Kroah-Hartman
maintainerPATCH 270/272 drm/vmwgfx: Reserve fence slots on buffer objects in cotables
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zack Rusin <[email protected]>
commit 544ccad739251b21dfa1e7f4b57aa9ea50d2d0f1 upstream.
The buffer objects created by cotables were missing fence reservations. They are created from vmw_validation_res_validate which makes them miss the ttm_eu_reserve_buffers which is called from vmw_validation_bo_reserve.
Cotables are the only resources which create a buffer object in the create callback so make sure the code also reserves the slots.
--- drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c +4 -0
@@ -482,6 +482,10 @@ static int vmw_cotable_resize(struct vmwvmw_bo_unreference (&old_buf); res->id = vcotbl->type; + ret =dma_resv_reserve_fences (bo->base.resv,1 ); +if (unlikely (ret)) + goto out_wait; +/* Release the pin acquired in vmw_bo_init */ ttm_bo_unpin (bo);
Greg Kroah-Hartman
maintainerPATCH 271/272 drm/virtio: Unlock reservations on dma_resv_reserve_fences() error
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Osipenko <[email protected]>
commit 0f877398d30e1df657a31a62f7c7de1869b072b5 upstream.
Unlock reservations on dma_resv_reserve_fences() error to fix recursive locking of the reservations when this error happens.
--- drivers/gpu/drm/virtio/virtgpu_gem.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/gpu/drm/virtio/virtgpu_gem.c +3 -1
@@ -228,8 +228,10 @@ int virtio_gpu_array_lock_resv(struct vifor (i =0 ; i < objs->nents; ++i) { ret =dma_resv_reserve_fences (objs->objs[i]->resv,1 ); -if (ret) +if (ret) { +virtio_gpu_array_unlock_resv (objs);return ret; + } }return ret; }
Greg Kroah-Hartman
maintainerPATCH 272/272 jiffies: Cast to unsigned long in secs_to_jiffies() conversion
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Easwar Hariharan <[email protected]>
commit bb2784d9ab49587ba4fbff37a319fff2924db289 upstream.
While converting users of msecs_to_jiffies(), lkp reported that some range checks would always be true because of the mismatch between the implied int value of secs_to_jiffies() vs the unsigned long return value of the msecs_to_jiffies() calls it was replacing.
Fix this by casting the secs_to_jiffies() input value to unsigned long.
--- include/linux/jiffies.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/jiffies.h +1 -1
@@ -382,7 +382,7 @@ static __always_inline unsigned long mse* * Return: jiffies value */ -#define secs_to_jiffies (_secs) ((_secs) * HZ) +#define secs_to_jiffies (_secs) (unsigned long)((_secs) * HZ)extern unsigned long __usecs_to_jiffies (const unsigned int u);#if !(USEC_PER_SEC %HZ )
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.217 release. There are 272 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sat, 22 Aug 2026 14:51:11 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.217-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.15.y
and the diffstat can be found below.thanks,
greg k-h
On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on BMIPS_GENERIC:
Signature · 1 line
Florian
Hi!
Quoted 4 lines
This is the start of the stable review cycle for the 5.15.217 release. There are 272 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
I see build error with this:
drivers/mmc/host/atmel-mci.c: In function 'atmci_remove':
4340
15:40:55drivers/mmc/host/atmel-mci.c:2632:24: error: 'struct atmel_mci' has no member named 'bh_work' 4341
15:40:55
2632 | cancel_work_sync(&host->bh_work);
4342
15:40:55
| ^~
4343
15:40:55
make[3]: *** [scripts/Makefile.build:289: drivers/mmc/host/atmel-mci.o] Error 1 4344
15:40:55
make[3]: *** Waiting for unfinished jobs....
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/jobs/16011796592
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/pipelines/2776651047
Best regards,
Pavel
# Librecast Test Results
020/020 [ OK ] liblcrq
010/010 [ OK ] libmld
120/120 [ OK ] liblibrecast
CPU/kernel: Linux auntie 5.15.217-rc1-01549-g8f0e17c458e5 #1 SMP Thu Aug 20 19:47:28 -00 2026 x86_64 AMD Ryzen 9 9950X 16-Core Processor AuthenticAMD GNU/Linux
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.217 release. There are 272 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sat, 22 Aug 2026 14:51:11 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.217-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.15.y
and the diffstat can be found below.thanks,
greg k-h
Tested on an amd64 laptop (Lenovo ThinkPad T14 Gen 1). Working well, no regressions observed.
Signature · 1 line
-Barry K. Nathan <[email protected]>
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.217 release. There are 272 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sat, 22 Aug 2026 14:51:11 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.217-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.15.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.217 release. There are 272 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sat, 22 Aug 2026 14:51:11 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.217-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.15.y
and the diffstat can be found below.thanks,
greg k-h
Built and booted successfully on RISC-V RV64 (HiFive Unmatched).
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.217 release. There are 272 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.