From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B64C84FC34A; Tue, 13 Oct 2026 12:19:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791893997; cv=none; b=IrEIyE4J54TuLXw1+kUSxI8Ne8hMnM+0HYoBdvY9FIo8WfKUDiM3RgrOhIHoj++mZcRX9zuf7RBF+ygut+hX7kXfw6awlOZVwRjuwqnz1/ypkFYt+sfHzyKPkSyQZlBYal8ukK4+BRIvPxYBNOj9GVG8uaVINI/Efjtr/7dw/oo= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791893997; c=relaxed/simple; bh=JgZizbR6rOWwgFITNZCjP5X+EdpFeH2sORbi0tlDaz4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BEi3ad6Ivyi0uZST4tXWfGbdvAqnPDYTh369z/8vqAC+k7eAnHlFtHtm4frN2AkUWllTpJXXy9lfVjFZXAa91+rCYMD+cbxUeSWpyPeI3CCqISeuMlzX/SeNMWlJQiauonBdtNxp80O20y7c13FJSfqeCaeoL1Mx4DW/IJHhhDw= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=y5OzpiHf; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="y5OzpiHf" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DD82D1F000FF; Tue, 13 Oct 2026 12:19:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1791893995; bh=XjxbyVfbFowMYb099B6G08iwvebTkDeOUcxmkeRkxJU=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=y5OzpiHfCxrgCg2Vs95aCEN5I/DNRgzMULxhv9GBQUq1r+fSCIantJnFQW0oSQJU/ aE/1+b3TrMG6KU4eKwdmSLwleeYWv42Uzy7Jzp1DZp4QRhdFM4n3yUbgO2Q/Cy2qGD VdaPaf4EPSBt5kvNfZEvMGe/e5iMftabEhl29stM= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Ilan Dudnik , Namjae Jeon , Sasha Levin Subject: [PATCH 6.18 412/621] ksmbd: defer publishing granted locks to prevent UAF/double-free race Date: Tue, 13 Oct 2026 13:36:47 +0200 Message-ID: <20261013112930.613290651@linuxfoundation.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261013112920.855194808@linuxfoundation.org> References: <20261013112920.855194808@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Ilan Dudnik [ Upstream commit 29f74f0f2e6df3b393b7b66e810136d0c64e3c59 ] In smb2_lock(), mid-batch granted locks are published to connection-wide (conn->lock_list) and file-wide (fp->lock_list) lists immediately upon vfs_lock_file() success, while also remaining tracked on the stack-local rollback_list. If a subsequent element in the same SMB2_LOCK request array fails validation or execution, the thread jumps to out: and walks rollback_list to undo previously granted locks. However, because the granted lock was already published to conn->lock_list, a concurrent UNLOCK request on the same connection can find the lock object and kfree() it before the rollback loop executes. When the granting thread subsequently walks rollback_list, it dereferences and frees the already-freed ksmbd_lock structure, resulting in a Use-After-Free and Double-Free (on both ksmbd_lock and struct file_lock). Fix this by deferring the publication of granted locks to conn->lock_list and fp->lock_list until after the entire array of lock elements has been processed without error. Mid-batch grants remain tracked exclusively on the request-local rollback_list until the whole batch succeeds, eliminating the race window. Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3") Signed-off-by: Ilan Dudnik Signed-off-by: Namjae Jeon Signed-off-by: Sasha Levin --- fs/smb/server/smb2pdu.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 6860d5229e1a9..100ff90b05190 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -7864,16 +7864,10 @@ int smb2_lock(struct ksmbd_work *work) rsp->hdr.Status = STATUS_RANGE_NOT_LOCKED; kfree(smb_lock); - goto out2; + /* rollback_list may still hold earlier grants */ + goto out; } else if (!rc) { list_add(&smb_lock->llist, &rollback_list); - smb_lock->conn = ksmbd_conn_get(work->conn); - spin_lock(&work->conn->llist_lock); - list_add_tail(&smb_lock->clist, - &work->conn->lock_list); - list_add_tail(&smb_lock->flist, - &fp->lock_list); - spin_unlock(&work->conn->llist_lock); ksmbd_debug(SMB, "successful in taking lock\n"); } else { locks_free_lock(flock); @@ -7895,6 +7889,19 @@ int smb2_lock(struct ksmbd_work *work) if (err) goto out; + /* publish only once the whole batch has committed */ + if (!list_empty(&rollback_list)) { + spin_lock(&work->conn->llist_lock); + list_for_each_entry(smb_lock, &rollback_list, llist) { + smb_lock->conn = ksmbd_conn_get(work->conn); + list_add_tail(&smb_lock->clist, + &work->conn->lock_list); + list_add_tail(&smb_lock->flist, + &fp->lock_list); + } + spin_unlock(&work->conn->llist_lock); + } + ksmbd_fd_put(work, fp); return 0; @@ -7922,15 +7929,6 @@ int smb2_lock(struct ksmbd_work *work) } list_del(&smb_lock->llist); - conn = smb_lock->conn; - spin_lock(&conn->llist_lock); - if (!list_empty(&smb_lock->flist)) - list_del(&smb_lock->flist); - list_del(&smb_lock->clist); - smb_lock->conn = NULL; - spin_unlock(&conn->llist_lock); - ksmbd_conn_put(conn); - smb2_free_lock(smb_lock->fl); if (rlock) locks_free_lock(rlock); -- 2.53.0