]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ksmbd: enforce signing required by the session
authorNamjae Jeon <linkinjeon@kernel.org>
Fri, 17 Jul 2026 02:32:00 +0000 (11:32 +0900)
committerSteve French <stfrench@microsoft.com>
Wed, 22 Jul 2026 14:54:03 +0000 (09:54 -0500)
SMB2_FLAGS_SIGNED is controlled by the incoming request and only indicates
that a signature accompanies that request. Do not use it to decide whether a
signing-required session must authenticate the request.

Reject an unsigned plaintext request before dispatch when the session
requires signing. Continue to validate signatures on signed requests,
including when signing is optional. Encrypted requests have already been
authenticated during decryption.

An OPLOCK_BREAK acknowledgment is a session request and is subject to the
same signing rule, so do not exclude it from signed-request detection.

Reported-by: Charles Vosburgh <trilobyte777@gmail.com>
Tested-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/server/server.c
fs/smb/server/smb2pdu.c

index f5baba9348405823cafa48fd8f430c15108cdb9e..960c4c897c11f68c1f87b390311809ce4f8a9f79 100644 (file)
@@ -112,6 +112,7 @@ static int __process_request(struct ksmbd_work *work, struct ksmbd_conn *conn,
 {
        struct smb_version_cmds *cmds;
        u16 command;
+       bool signed_req;
        int ret;
 
        if (check_conn_state(work))
@@ -138,7 +139,14 @@ andx_again:
                return SERVER_HANDLER_ABORT;
        }
 
-       if (work->sess && conn->ops->is_sign_req(work, command)) {
+       signed_req = conn->ops->is_sign_req && conn->ops->is_sign_req(work, command);
+       if (work->sess && work->sess->sign && !work->encrypted &&
+           !signed_req) {
+               conn->ops->set_rsp_status(work, STATUS_ACCESS_DENIED);
+               return SERVER_HANDLER_ABORT;
+       }
+
+       if (work->sess && signed_req) {
                ret = conn->ops->check_sign_req(work);
                if (!ret) {
                        conn->ops->set_rsp_status(work, STATUS_ACCESS_DENIED);
index bec692bca1ca8fa5eccd5d8c4f5d502f516c963b..d54b714cc36cebfded4b3e6928f40a2d50102742 100644 (file)
@@ -9596,8 +9596,7 @@ bool smb2_is_sign_req(struct ksmbd_work *work, unsigned int command)
        struct smb2_hdr *rcv_hdr2 = smb_get_msg(work->request_buf);
 
        if ((rcv_hdr2->Flags & SMB2_FLAGS_SIGNED) &&
-           command != SMB2_NEGOTIATE_HE &&
-           command != SMB2_OPLOCK_BREAK_HE)
+           command != SMB2_NEGOTIATE_HE)
                return true;
 
        return false;