[PATCH] ksmbd: validate share path for batch oplock reconnects

From: Sung Byeongchan

Date: Wed Oct 07 2026 - 03:59:14 EST


Durable reconnects backed by a lease reach
ksmbd_validate_name_reconnect(), which rejects reconnecting an open through
a different share root. Batch oplock reconnects return immediately after
checking the oplock level and therefore skip that validation.

An authenticated client which owns a disconnected durable batch-oplock
handle can present its valid reconnect context on another tree. The
preserved open is then rebound to that tree even when the client can no
longer connect to the source share.

Route successful batch-oplock reconnects through the same name and
share-root validation as lease reconnects. Keep invalid oplock levels on
the existing error path.

This was found by source review with AI assistance. In two independent
boots, a same-owner client was denied a new tree connect to the source
share, but reconnected its durable handle on an unrelated read-only share
and read the source file. Routing the batch-oplock path through the
validator rejected the cross-share reconnect and preserved same-share
reconnects.

Fixes: c8efcc786146 ("ksmbd: add support for durable handles v1/v2")
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: LLM
Signed-off-by: Sung Byeongchan <tjdqudcks0424@xxxxxxxxx>
---
fs/smb/server/oplock.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c
index 25ff8408f0ba2..70b7b085d4fdc 100644
--- a/fs/smb/server/oplock.c
+++ b/fs/smb/server/oplock.c
@@ -2489,9 +2489,10 @@ int smb2_check_durable_oplock(struct ksmbd_conn *conn,
if (opinfo->level != SMB2_OPLOCK_LEVEL_BATCH) {
pr_err("oplock level is not equal to SMB2_OPLOCK_LEVEL_BATCH\n");
ret = -EBADF;
+ goto out;
}

- goto out;
+ goto validate_name;
}

if (memcmp(conn->ClientGUID, fp->client_guid,
@@ -2528,6 +2529,7 @@ int smb2_check_durable_oplock(struct ksmbd_conn *conn,
goto out;
}

+validate_name:
if (!ksmbd_inode_pending_delete(fp))
ret = ksmbd_validate_name_reconnect(share, fp, name);
out:
--
2.43.0