FAILED: patch "[PATCH] smb: client: fix UAF and buffer leak in cifs_check_trans2()" failed to apply to 5.10-stable tree
Subsystems (5)
[email protected]
maintainerThe patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.10.y
git checkout FETCH_HEAD
git cherry-pick -x 730d0bb19507b9e19c2fe5343109ac618e2fbce5
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026090305-henchman-snipping-25aa@gregkh' --subject-prefix 'PATCH 5.10.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 730d0bb19507b9e19c2fe5343109ac618e2fbce5 Mon Sep 17 00:00:00 2001
From: Frank Sorenson <[email protected]>
Date: Wed, 12 Aug 2026 21:39:51 -0500
Subject: [PATCH] smb: client: fix UAF and buffer leak in cifs_check_trans2()
for malformed secondary T2
When a valid primary TRANSACT2 response has been received (mid->resp_buf set, mid->multiRsp true) and a subsequent secondary response causes cifs_check_trans2() to return false -- either because the SMB header is invalid (malformed != 0) or because check2ndT2() rejects the PDU -- handle_mid() overwrites mid->resp_buf with the new buffer (leaking the primary buffer) and, because mid->multiRsp is set, skips the server->smallbuf/bigbuf NULL-out. When the user thread frees mid->resp_buf, server->smallbuf or server->bigbuf is left dangling; the demux thread reuses it for the next packet, resulting in a use-after-free.
Combine both early-exit conditions and, when mid->multiRsp is already set, abort the pending transaction inline: set multiEnd, call dequeue_mid() with malformed=true, and return true so handle_mid() exits without touching mid->resp_buf or the server buffer pointers.
fs/smb/client/smb1transport.c +11 -3
@@ -449,10 +449,18 @@ bool cifs_check_trans2(struct mid_q_entry *mid, struct TCP_Server_Info *server, char *buf, int malformed) { - if (malformed) - return false; -if (check2ndT2 (buf) <=0 ) + if (malformed || check2ndT2(buf) <= 0) { + /* mid->multiRsp blocks the server buf detach in handle_mid(); + * returning false here would leak resp_buf and leave a dangling + * server->smallbuf/bigbuf after the user thread frees resp_buf. + */ + if (mid->multiRsp) { + mid->multiEnd = true; +dequeue_mid (server, mid, true); +return true; + }return false; + } mid->multiRsp = true;if (mid->resp_buf) {/* merge response - fix up 1st*/
Sasha Levin
maintainerPATCH 1/3 cifs: Remove the server pointer from smb_message
From: David Howells <[email protected]>
[ Upstream commit 87fba18abbb8433a47045c785f2edc027e4d2bc5 ]
Remove the server pointer from smb_message and instead pass it down to all the things that access it.
[ sashal: Reduced backport -- upstream 87fba18abbb84 touches 12 file(s), this
backport carries 5. Not backported here:
fs/smb/client/cifsfs.c
fs/smb/client/cifsglob.h
fs/smb/client/cifsproto.h
fs/smb/client/cifssmb.c
fs/smb/client/cifstransport.c
fs/smb/client/connect.c
fs/smb/client/netmisc.c
fs/smb/client/smb1ops.c
... and 4 more
This note is generated from the file lists only; see the resolution record for the reasoning. ]
Stable-dep-of: 730d0bb19507 ("smb: client: fix UAF and buffer leak in cifs_check_trans2() for malformed secondary T2")
--- fs/cifs/cifsproto.h | 3 ++- fs/cifs/cifssmb.c | 4 ++-- fs/cifs/connect.c | 5 +++-- fs/cifs/smb1ops.c | 2 +- fs/cifs/smb2ops.c | 14 +++++++------- 5 files changed, 15 insertions(+), 13 deletions(-)
fs/cifs/cifsproto.h +2 -1
@@ -227,7 +227,8 @@ extern unsigned int setup_authusers_ACE(struct cifs_ace *pace);extern unsigned int setup_special_mode_ACE (struct cifs_ace *pace,__u64 nmode);extern unsigned int setup_special_user_owner_ACE (struct cifs_ace *pace); -extern void dequeue_mid (struct mid_q_entry *mid,bool malformed); +extern void dequeue_mid (struct TCP_Server_Info *server, +struct mid_q_entry *mid,bool malformed);extern int cifs_read_from_socket (struct TCP_Server_Info *server,char *buf,unsigned int to_read); extern ssize_t cifs_discard_from_socket(struct TCP_Server_Info *server,
fs/cifs/cifssmb.c +2 -2
@@ -1470,7 +1470,7 @@ __cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid,int length; length =cifs_discard_remaining_data (server); -dequeue_mid (mid, malformed); +dequeue_mid (server, mid, malformed); mid->resp_buf = server->smallbuf; server->smallbuf =NULL ;return length;
@@ -1609,7 +1609,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)if (server->total_read < buflen)return cifs_readv_discard (server, mid); -dequeue_mid (mid, false); +dequeue_mid (server, mid, false); mid->resp_buf = server->smallbuf; server->smallbuf =NULL ;return length;
fs/cifs/connect.c +3 -2
@@ -822,7 +822,8 @@ is_smb_response(struct TCP_Server_Info *server, unsigned char type) }void -dequeue_mid (struct mid_q_entry *mid,bool malformed) +dequeue_mid (struct TCP_Server_Info *server,struct mid_q_entry *mid, +bool malformed) {#ifdef CONFIG_CIFS_STATS2 mid->when_received = jiffies;
@@ -877,7 +878,7 @@ handle_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server,else server->smallbuf =NULL ; } -dequeue_mid (mid, malformed); +dequeue_mid (server, mid, malformed); }static void clean_demultiplex_info (struct TCP_Server_Info *server)
fs/cifs/smb1ops.c +1 -1
@@ -391,7 +391,7 @@ cifs_check_trans2(struct mid_q_entry *mid, struct TCP_Server_Info *server,return true;/* All parts received or packet is malformed. */ mid->multiEnd = true; -dequeue_mid (mid, malformed); +dequeue_mid (server, mid, malformed);return true; }if (!server->large_buf) {
fs/cifs/smb2ops.c +7 -7
@@ -4662,7 +4662,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,if (is_offloaded) mid->mid_state =MID_RESPONSE_RECEIVED ;else -dequeue_mid (mid, false); +dequeue_mid (server, mid, false);return 0 ; }
@@ -4689,7 +4689,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,if (is_offloaded) mid->mid_state =MID_RESPONSE_MALFORMED ;else -dequeue_mid (mid, rdata->result); +dequeue_mid (server, mid, rdata->result);return 0 ; }
@@ -4708,7 +4708,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,if (is_offloaded) mid->mid_state =MID_RESPONSE_MALFORMED ;else -dequeue_mid (mid, rdata->result); +dequeue_mid (server, mid, rdata->result);return 0 ; }
@@ -4718,7 +4718,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,if (is_offloaded) mid->mid_state =MID_RESPONSE_MALFORMED ;else -dequeue_mid (mid, rdata->result); +dequeue_mid (server, mid, rdata->result);return 0 ; }
@@ -4728,7 +4728,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,if (is_offloaded) mid->mid_state =MID_RESPONSE_MALFORMED ;else -dequeue_mid (mid, rdata->result); +dequeue_mid (server, mid, rdata->result);return 0 ; }
@@ -4746,7 +4746,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,if (is_offloaded) mid->mid_state =MID_RESPONSE_MALFORMED ;else -dequeue_mid (mid, rdata->result); +dequeue_mid (server, mid, rdata->result);return 0 ; }
@@ -4760,7 +4760,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,if (is_offloaded) mid->mid_state =MID_RESPONSE_RECEIVED ;else -dequeue_mid (mid, false); +dequeue_mid (server, mid, false);return length; }
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/3 cifs: SMB1 split: Create smb1proto.h for SMB1 declarations
From: David Howells <[email protected]>
[ Upstream commit 86c666506ea2c42649879eeac7f29e7bedef2f23 ]
[ sashal: Reduced backport -- upstream 86c666506ea2c touches 3 file(s), this
backport carries 8. Not backported here:
fs/smb/client/cifsglob.h
fs/smb/client/cifsproto.h
fs/smb/client/smb1proto.h
This note is generated from the file lists only; see the resolution record for the reasoning. ]
Stable-dep-of: 730d0bb19507 ("smb: client: fix UAF and buffer leak in cifs_check_trans2() for malformed secondary T2")
--- fs/cifs/Makefile | 2 +- fs/cifs/cifsglob.h | 2 - fs/cifs/cifsproto.h | 11 +-- fs/cifs/fs_context.c | 1 + fs/cifs/smb1ops.c | 171 -------------------------------- fs/cifs/smb1proto.h | 40 ++++++++ fs/cifs/smb1transport.c | 3 + fs/smb/client/smb1transport.c | 180 ++++++++++++++++++++++++++++++++++ 8 files changed, 226 insertions(+), 184 deletions(-) create mode 100644 fs/cifs/smb1proto.h create mode 100644 fs/cifs/smb1transport.c create mode 100644 fs/smb/client/smb1transport.c
fs/cifs/Makefile +1 -1
@@ -8,7 +8,7 @@ obj-$(CONFIG_CIFS) += cifs.o cifs-y := trace.o cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o \ inode.o link.o misc.o netmisc.o smbencrypt.o transport.o asn1.o \ cifs_unicode.o nterr.o cifsencrypt.o \ - readdir.o ioctl.o sess.o export.o smb1ops.o winucase.o \ + readdir.o ioctl.o sess.o export.o smb1ops.o smb1transport.o winucase.o \ smb2ops.o smb2maperror.o smb2transport.o \ smb2misc.o smb2pdu.o smb2inode.o smb2file.o cifsacl.o fs_context.o
fs/cifs/cifsglob.h +0 -2
@@ -1990,8 +1990,6 @@ extern mempool_t *cifs_mid_poolp;#define SMB1_VERSION_STRING "1.0"#define SMB20_VERSION_STRING "2.0"#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY -extern struct smb_version_operations smb1_operations; -extern struct smb_version_values smb1_values;extern struct smb_version_operations smb20_operations;extern struct smb_version_values smb20_values;#endif /* CIFS_ALLOW_INSECURE_LEGACY */
fs/cifs/cifsproto.h +1 -10
@@ -25,6 +25,7 @@#ifdef CONFIG_CIFS_DFS_UPCALL #include "dfs_cache.h" #endif +#include "smb1proto.h" struct statfs ;struct smb_vol ;
@@ -373,16 +374,6 @@ extern int CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon, struct cifsFileInfo *cfile, __u64 size, bool set_allocation); -struct cifs_unix_set_info_args { -__u64 ctime; -__u64 atime; -__u64 mtime; -__u64 mode; -kuid_t uid; -kgid_t gid; -dev_t device; -}; - extern int CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon, const struct cifs_unix_set_info_args *args,
fs/cifs/fs_context.c +1 -0
@@ -9,6 +9,7 @@#include "cifsglob.h" #include "cifs_debug.h" #include "fs_context.h" +#include "smb1proto.h" static const match_table_t cifs_smb_version_tokens = { { Smb_1,SMB1_VERSION_STRING },
fs/cifs/smb1ops.c +0 -171
183 lines not on this page · raw message
fs/cifs/smb1proto.h new file +40 -0
@@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: LGPL-2.1 */ +/* +* +* Copyright (c) International Business Machines Corp., 2002,2008 +* Author(s): Steve French ([email protected]) +* +*/ +#ifndef _SMB1PROTO_H +#define _SMB1PROTO_H + +struct cifs_unix_set_info_args { +__u64 ctime; +__u64 atime; +__u64 mtime; +__u64 mode; +kuid_t uid; +kgid_t gid; +dev_t device; +}; + +/* +* smb1transport.c +*/ +bool cifs_check_trans2 (struct mid_q_entry *mid,struct TCP_Server_Info *server, +char *buf,int malformed); + +#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY + +/* +* cifssmb.c +*/ + +/* +* smb1ops.c +*/ +extern struct smb_version_operations smb1_operations; +extern struct smb_version_values smb1_values; + +#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ +#endif /* _SMB1PROTO_H */
fs/cifs/smb1transport.c new file +3 -0
@@ -0,0 +1,3 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include "../smb/client/smb1transport.c"
fs/smb/client/smb1transport.c new file +180 -0
180 lines not on this page · raw message
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 3/3 smb: client: fix UAF and buffer leak in cifs_check_trans2() for malformed secondary T2
In reply to Sasha LevinFrom: Frank Sorenson <[email protected]>
[ Upstream commit 730d0bb19507b9e19c2fe5343109ac618e2fbce5 ]
When a valid primary TRANSACT2 response has been received (mid->resp_buf set, mid->multiRsp true) and a subsequent secondary response causes cifs_check_trans2() to return false -- either because the SMB header is invalid (malformed != 0) or because check2ndT2() rejects the PDU -- handle_mid() overwrites mid->resp_buf with the new buffer (leaking the primary buffer) and, because mid->multiRsp is set, skips the server->smallbuf/bigbuf NULL-out. When the user thread frees mid->resp_buf, server->smallbuf or server->bigbuf is left dangling; the demux thread reuses it for the next packet, resulting in a use-after-free.
Combine both early-exit conditions and, when mid->multiRsp is already set, abort the pending transaction inline: set multiEnd, call dequeue_mid() with malformed=true, and return true so handle_mid() exits without touching mid->resp_buf or the server buffer pointers.
--- fs/smb/client/smb1transport.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
fs/smb/client/smb1transport.c +11 -3
@@ -152,10 +152,18 @@ bool cifs_check_trans2(struct mid_q_entry *mid, struct TCP_Server_Info *server, char *buf, int malformed) { - if (malformed) - return false; -if (check2ndT2 (buf) <=0 ) + if (malformed || check2ndT2(buf) <= 0) { + /* mid->multiRsp blocks the server buf detach in handle_mid(); + * returning false here would leak resp_buf and leave a dangling + * server->smallbuf/bigbuf after the user thread frees resp_buf. + */ + if (mid->multiRsp) { + mid->multiEnd = true; +dequeue_mid (server, mid, true); +return true; + }return false; + } mid->multiRsp = true;if (mid->resp_buf) {/* merge response - fix up 1st*/
Signature · 1 line
2.53.0