[PATCH] ksmbd: make RDMA encryption diagnostics conditional
Namjae Jeon <[email protected]>
| Newsgroups | org.kernel.vger.linux-cifs |
|---|---|
| Message-ID | <[email protected]> |
The temporary RDMA encryption diagnostics logged every SMB3 request and successful payload operation with pr_err(), which made normal traffic too noisy. Keep only negotiation, RDMA READ preparation, RDMA WRITE transform metadata, crypto completion, and final transfer completion messages as KSMBD_DEBUG_RDMA diagnostics. Keep error reports for malformed metadata, crypto, RDMA transfer, and file write failures at error level. This preserves the diagnostics needed to verify RDMA transform operation without flooding the kernel error log during normal I/O. Signed-off-by: Namjae Jeon <[email protected]> --- fs/smb/server/auth.c | 33 +++++++++++++++--- fs/smb/server/smb2pdu.c | 75 +++++++++++++++++++++++++++++++++-------- 2 files changed, 90 insertions(+), 18 deletions(-) diff --git a/fs/smb/server/auth.c b/fs/smb/server/auth.c index db362c64af8d..9f3151a9f379 100644 --- a/fs/smb/server/auth.c +++ b/fs/smb/server/auth.c @@ -911,26 +911,42 @@ int ksmbd_crypt_rdma(struct ksmbd_conn *conn, const u8 *key, unsigned int iv_len, crypt_len; u8 auth_tag[SMB2_SIGNATURE_SIZE] = {}; u8 *iv = NULL; + u16 cipher = le16_to_cpu(conn->cipher_type); int rc; DECLARE_CRYPTO_WAIT(wait); - if (!buflen || !tag_len || tag_len > SMB2_SIGNATURE_SIZE) + if (!buflen || !tag_len || tag_len > SMB2_SIGNATURE_SIZE) { + pr_err("RDMA %s rejected: cipher=0x%04x payload=%u nonce=%u tag=%u\n", + enc ? "encryption" : "decryption", cipher, buflen, + nonce_len, tag_len); return -EINVAL; + } if (!enc) memcpy(auth_tag, tag, tag_len); if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM || conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) { - if (nonce_len != SMB3_AES_GCM_NONCE) + if (nonce_len != SMB3_AES_GCM_NONCE) { + pr_err("RDMA %s rejected: cipher=0x%04x invalid nonce=%u expected=%u\n", + enc ? "encryption" : "decryption", cipher, + nonce_len, SMB3_AES_GCM_NONCE); return -EINVAL; + } ctx = ksmbd_crypto_ctx_find_gcm(); } else { - if (nonce_len != SMB3_AES_CCM_NONCE) + if (nonce_len != SMB3_AES_CCM_NONCE) { + pr_err("RDMA %s rejected: cipher=0x%04x invalid nonce=%u expected=%u\n", + enc ? "encryption" : "decryption", cipher, + nonce_len, SMB3_AES_CCM_NONCE); return -EINVAL; + } ctx = ksmbd_crypto_ctx_find_ccm(); } - if (!ctx) + if (!ctx) { + pr_err("RDMA %s failed: cipher=0x%04x crypto context unavailable\n", + enc ? "encryption" : "decryption", cipher); return -ENOMEM; + } tfm = (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM || conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) ? @@ -988,6 +1004,15 @@ int ksmbd_crypt_rdma(struct ksmbd_conn *conn, const u8 *key, kfree(sg); aead_request_free(req); ksmbd_release_crypto_ctx(ctx); + if (rc) + pr_err("RDMA %s failed: cipher=0x%04x payload=%u nonce=%u tag=%u rc=%d\n", + enc ? "encryption" : "decryption", cipher, buflen, + nonce_len, tag_len, rc); + else + ksmbd_debug(RDMA, + "RDMA %s completed: cipher=0x%04x payload=%u nonce=%u tag=%u\n", + enc ? "encryption" : "decryption", cipher, buflen, + nonce_len, tag_len); return rc; } diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index b48eff02dbf8..bd74b45ce0e7 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -1904,6 +1904,13 @@ int smb2_handle_negotiate(struct ksmbd_work *work) if (!conn->cipher_type) conn->rdma_transform_ids &= ~BIT(SMB2_RDMA_TRANSFORM_ENCRYPTION); + ksmbd_debug(RDMA, + "RDMA transform negotiation: transport=%s context=%s encryption=%s cipher=0x%04x\n", + conn->transport->ops->rdma_read ? "rdma" : "tcp", + conn->rdma_transform_negotiated ? "present" : "absent", + conn->rdma_transform_ids & + BIT(SMB2_RDMA_TRANSFORM_ENCRYPTION) ? "enabled" : "disabled", + le16_to_cpu(conn->cipher_type)); rc = init_smb3_11_server(conn); if (rc < 0) { @@ -8719,15 +8726,14 @@ static int smb2_prep_rdma_read(struct ksmbd_work *work, u16 transform_type; int err; - if (work->encrypted && - (conn->rdma_transform_ids & BIT(SMB2_RDMA_TRANSFORM_ENCRYPTION))) { - transform_type = SMB2_RDMA_TRANSFORM_TYPE_ENCRYPTION; - nonce_len = (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM || - conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) ? - SMB3_AES_GCM_NONCE : SMB3_AES_CCM_NONCE; - } else { + if (!work->encrypted || + !(conn->rdma_transform_ids & BIT(SMB2_RDMA_TRANSFORM_ENCRYPTION))) return 0; - } + + transform_type = SMB2_RDMA_TRANSFORM_TYPE_ENCRYPTION; + nonce_len = (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM || + conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) ? + SMB3_AES_GCM_NONCE : SMB3_AES_CCM_NONCE; transform = (struct smb2_rdma_transform *)rsp->Buffer; crypto = (struct smb2_rdma_crypto_transform *)(transform + 1); @@ -8747,13 +8753,20 @@ static int smb2_prep_rdma_read(struct ksmbd_work *work, data, datalen, nonce, nonce_len, crypto->Signature, SMB2_SIGNATURE_SIZE, true); - if (err) + if (err) { + pr_err("RDMA READ encryption failed: session=%llu payload=%u rc=%d\n", + work->sess->id, datalen, err); return err; + } transform_len = sizeof(*transform) + sizeof(*crypto) + SMB2_SIGNATURE_SIZE + nonce_len; rsp->Flags = SMB2_READFLAG_RESPONSE_RDMA_TRANSFORM; rsp->DataLength = cpu_to_le32(transform_len); + ksmbd_debug(RDMA, + "RDMA READ encryption prepared: session=%llu cipher=0x%04x payload=%u transform=%u nonce=%u tag=%u\n", + work->sess->id, le16_to_cpu(conn->cipher_type), datalen, + transform_len, nonce_len, SMB2_SIGNATURE_SIZE); return transform_len; } @@ -8830,6 +8843,7 @@ static int smb2_parse_rdma_write_transform(struct ksmbd_work *work, unsigned int offset = le16_to_cpu(req->WriteChannelInfoOffset); unsigned int length = le16_to_cpu(req->WriteChannelInfoLength); unsigned int desc_offset, desc_len, crypto_len, expected_desc_offset; + int err; if (!work->conn->rdma_transform_ids || offset < offsetof(struct smb2_write_req, Buffer) || @@ -8894,8 +8908,18 @@ static int smb2_parse_rdma_write_transform(struct ksmbd_work *work, info->crypto = crypto; info->nonce = crypto->Signature + info->signature_len; info->channel = transform->Channel; - return check_rdma_desc(info->desc, info->desc_len, - le32_to_cpu(req->RemainingBytes)); + err = check_rdma_desc(info->desc, info->desc_len, + le32_to_cpu(req->RemainingBytes)); + if (err) + return err; + + ksmbd_debug(RDMA, + "RDMA WRITE encryption metadata: session=%llu cipher=0x%04x payload=%u channel=0x%x descriptors=%zu nonce=%u tag=%u\n", + work->sess->id, le16_to_cpu(work->conn->cipher_type), + le32_to_cpu(req->RemainingBytes), le32_to_cpu(info->channel), + info->desc_len / sizeof(*info->desc), info->nonce_len, + info->signature_len); + return 0; } /** @@ -9105,6 +9129,15 @@ int smb2_read(struct ksmbd_work *work) remain_bytes = smb2_read_rdma(work, req, aux_payload_buf, nbytes); + if (remain_bytes < 0) + pr_err("RDMA READ transfer failed: session=%llu payload=%zu transform=%d rc=%zd\n", + work->sess ? work->sess->id : 0, nbytes, + rdma_transform_len, remain_bytes); + else + ksmbd_debug(RDMA, + "RDMA READ transfer completed: session=%llu payload=%zu transform=%d\n", + work->sess ? work->sess->id : 0, nbytes, + rdma_transform_len); kvfree(aux_payload_buf); aux_payload_buf = NULL; nbytes = 0; @@ -9269,10 +9302,12 @@ static ssize_t smb2_write_rdma(struct ksmbd_work *work, ret = ksmbd_conn_rdma_read(work->conn, data_buf, length, desc, desc_len); if (ret < 0) { + if (transform) + pr_err("RDMA WRITE encrypted transfer failed: session=%llu payload=%zu rdma_read_rc=%d\n", + work->sess->id, length, ret); kvfree(data_buf); return ret; } - if (transform && transform->type == SMB2_RDMA_TRANSFORM_TYPE_ENCRYPTION) { ret = ksmbd_crypt_rdma(work->conn, @@ -9282,6 +9317,8 @@ static ssize_t smb2_write_rdma(struct ksmbd_work *work, transform->crypto->Signature, transform->signature_len, false); if (ret) { + pr_err("RDMA WRITE decryption failed: session=%llu payload=%zu rc=%d\n", + work->sess->id, length, ret); kvfree(data_buf); return ret == -ENOMEM ? ret : -EBADMSG; } @@ -9289,8 +9326,15 @@ static ssize_t smb2_write_rdma(struct ksmbd_work *work, ret = ksmbd_vfs_write(work, fp, data_buf, length, &offset, sync, &nbytes); kvfree(data_buf); - if (ret < 0) + if (ret < 0) { + if (transform) + pr_err("RDMA WRITE encrypted file write failed: session=%llu payload=%zu rc=%d\n", + work->sess->id, length, ret); return ret; + } + ksmbd_debug(RDMA, + "RDMA WRITE transfer completed: session=%llu payload=%zu transformed=%u written=%zd\n", + work->sess ? work->sess->id : 0, length, !!transform, nbytes); return nbytes; } @@ -9404,8 +9448,11 @@ int smb2_write(struct ksmbd_work *work) if (req->Channel == SMB2_CHANNEL_RDMA_TRANSFORM) { err = smb2_parse_rdma_write_transform(work, req, &rdma_transform); - if (err) + if (err) { + pr_err("RDMA WRITE encryption metadata rejected: session=%llu rc=%d\n", + work->sess ? work->sess->id : 0, err); goto out; + } rdma_desc = rdma_transform.desc; rdma_desc_len = rdma_transform.desc_len; rdma_info = &rdma_transform; -- 2.25.1