mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 02:21:39 -04:00
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.
Fixes: 316cf94a91 ("CIFS: Move trans2 processing to ops struct")
Cc: stable@vger.kernel.org # cifs_check_trans2() is in smb1ops.c on kernels < 7.0
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
This commit is contained in:
committed by
Paulo Alcantara
parent
6343c1da56
commit
730d0bb195
@@ -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*/
|
||||
|
||||
Reference in New Issue
Block a user