diff options
-rw-r--r-- | fs/ksmbd/connection.h | 2 | ||||
-rw-r--r-- | fs/ksmbd/ndr.c | 12 | ||||
-rw-r--r-- | fs/ksmbd/server.c | 20 | ||||
-rw-r--r-- | fs/ksmbd/smb2misc.c | 9 | ||||
-rw-r--r-- | fs/ksmbd/smb2ops.c | 4 | ||||
-rw-r--r-- | fs/ksmbd/smb2pdu.c | 204 | ||||
-rw-r--r-- | fs/ksmbd/smb2pdu.h | 20 | ||||
-rw-r--r-- | fs/ksmbd/transport_rdma.c | 2 | ||||
-rw-r--r-- | fs/ksmbd/transport_rdma.h | 6 | ||||
-rw-r--r-- | fs/ksmbd/transport_tcp.c | 3 |
10 files changed, 182 insertions, 100 deletions
diff --git a/fs/ksmbd/connection.h b/fs/ksmbd/connection.h index 487c2024b0d5..e5403c587a58 100644 --- a/fs/ksmbd/connection.h +++ b/fs/ksmbd/connection.h @@ -109,6 +109,8 @@ struct ksmbd_conn { __le16 cipher_type; __le16 compress_algorithm; bool posix_ext_supported; + bool signing_negotiated; + __le16 signing_algorithm; bool binding; }; diff --git a/fs/ksmbd/ndr.c b/fs/ksmbd/ndr.c index cf0df78259c9..df23dfbaf657 100644 --- a/fs/ksmbd/ndr.c +++ b/fs/ksmbd/ndr.c @@ -65,13 +65,15 @@ static int ndr_write_bytes(struct ndr *n, void *value, size_t sz) return 0; } -static int ndr_write_string(struct ndr *n, void *value, size_t sz) +static int ndr_write_string(struct ndr *n, char *value) { + size_t sz; + + sz = strlen(value) + 1; if (n->length <= n->offset + sz) try_to_realloc_ndr_blob(n, sz); - strncpy(ndr_get_field(n), value, sz); - sz++; + memcpy(ndr_get_field(n), value, sz); n->offset += sz; n->offset = ALIGN(n->offset, 2); return 0; @@ -134,9 +136,9 @@ int ndr_encode_dos_attr(struct ndr *n, struct xattr_dos_attrib *da) if (da->version == 3) { snprintf(hex_attr, 10, "0x%x", da->attr); - ndr_write_string(n, hex_attr, strlen(hex_attr)); + ndr_write_string(n, hex_attr); } else { - ndr_write_string(n, "", strlen("")); + ndr_write_string(n, ""); } ndr_write_int16(n, da->version); ndr_write_int32(n, da->version); diff --git a/fs/ksmbd/server.c b/fs/ksmbd/server.c index a8c59e96a2f7..e6a9f6aa47eb 100644 --- a/fs/ksmbd/server.c +++ b/fs/ksmbd/server.c @@ -101,8 +101,8 @@ static inline int check_conn_state(struct ksmbd_work *work) return 0; } -#define TCP_HANDLER_CONTINUE 0 -#define TCP_HANDLER_ABORT 1 +#define SERVER_HANDLER_CONTINUE 0 +#define SERVER_HANDLER_ABORT 1 static int __process_request(struct ksmbd_work *work, struct ksmbd_conn *conn, u16 *cmd) @@ -112,10 +112,10 @@ static int __process_request(struct ksmbd_work *work, struct ksmbd_conn *conn, int ret; if (check_conn_state(work)) - return TCP_HANDLER_CONTINUE; + return SERVER_HANDLER_CONTINUE; if (ksmbd_verify_smb_message(work)) - return TCP_HANDLER_ABORT; + return SERVER_HANDLER_ABORT; command = conn->ops->get_cmd_val(work); *cmd = command; @@ -123,21 +123,21 @@ static int __process_request(struct ksmbd_work *work, struct ksmbd_conn *conn, andx_again: if (command >= conn->max_cmds) { conn->ops->set_rsp_status(work, STATUS_INVALID_PARAMETER); - return TCP_HANDLER_CONTINUE; + return SERVER_HANDLER_CONTINUE; } cmds = &conn->cmds[command]; if (!cmds->proc) { ksmbd_debug(SMB, "*** not implemented yet cmd = %x\n", command); conn->ops->set_rsp_status(work, STATUS_NOT_IMPLEMENTED); - return TCP_HANDLER_CONTINUE; + return SERVER_HANDLER_CONTINUE; } if (work->sess && conn->ops->is_sign_req(work, command)) { ret = conn->ops->check_sign_req(work); if (!ret) { conn->ops->set_rsp_status(work, STATUS_ACCESS_DENIED); - return TCP_HANDLER_CONTINUE; + return SERVER_HANDLER_CONTINUE; } } @@ -153,8 +153,8 @@ andx_again: } if (work->send_no_response) - return TCP_HANDLER_ABORT; - return TCP_HANDLER_CONTINUE; + return SERVER_HANDLER_ABORT; + return SERVER_HANDLER_CONTINUE; } static void __handle_ksmbd_work(struct ksmbd_work *work, @@ -203,7 +203,7 @@ static void __handle_ksmbd_work(struct ksmbd_work *work, do { rc = __process_request(work, conn, &command); - if (rc == TCP_HANDLER_ABORT) + if (rc == SERVER_HANDLER_ABORT) break; /* diff --git a/fs/ksmbd/smb2misc.c b/fs/ksmbd/smb2misc.c index 4508631c5706..9aa46bb3e10d 100644 --- a/fs/ksmbd/smb2misc.c +++ b/fs/ksmbd/smb2misc.c @@ -385,6 +385,12 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work) } } + if ((work->conn->vals->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU) && + smb2_validate_credit_charge(hdr)) { + work->conn->ops->set_rsp_status(work, STATUS_INVALID_PARAMETER); + return 1; + } + clc_len = smb2_calc_size(hdr); if (len != clc_len) { /* server can return one byte more due to implied bcc[0] */ @@ -423,8 +429,7 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work) return 1; } - return work->conn->vals->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU ? - smb2_validate_credit_charge(hdr) : 0; + return 0; } int smb2_negotiate_request(struct ksmbd_work *work) diff --git a/fs/ksmbd/smb2ops.c b/fs/ksmbd/smb2ops.c index 8262908e467c..197473871aa4 100644 --- a/fs/ksmbd/smb2ops.c +++ b/fs/ksmbd/smb2ops.c @@ -204,6 +204,7 @@ void init_smb2_1_server(struct ksmbd_conn *conn) conn->cmds = smb2_0_server_cmds; conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds); conn->max_credits = SMB2_MAX_CREDITS; + conn->signing_algorithm = SIGNING_ALG_HMAC_SHA256; if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES) conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING; @@ -221,6 +222,7 @@ void init_smb3_0_server(struct ksmbd_conn *conn) conn->cmds = smb2_0_server_cmds; conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds); conn->max_credits = SMB2_MAX_CREDITS; + conn->signing_algorithm = SIGNING_ALG_AES_CMAC; if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES) conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING; @@ -245,6 +247,7 @@ void init_smb3_02_server(struct ksmbd_conn *conn) conn->cmds = smb2_0_server_cmds; conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds); conn->max_credits = SMB2_MAX_CREDITS; + conn->signing_algorithm = SIGNING_ALG_AES_CMAC; if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES) conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING; @@ -269,6 +272,7 @@ int init_smb3_11_server(struct ksmbd_conn *conn) conn->cmds = smb2_0_server_cmds; conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds); conn->max_credits = SMB2_MAX_CREDITS; + conn->signing_algorithm = SIGNING_ALG_AES_CMAC; if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES) conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING; diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c index c1a594599431..7e6e3d8c20e8 100644 --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -786,6 +786,18 @@ static void build_compression_ctxt(struct smb2_compression_ctx *pneg_ctxt, pneg_ctxt->CompressionAlgorithms[0] = comp_algo; } +static void build_sign_cap_ctxt(struct smb2_signing_capabilities *pneg_ctxt, + __le16 sign_algo) +{ + pneg_ctxt->ContextType = SMB2_SIGNING_CAPABILITIES; + pneg_ctxt->DataLength = + cpu_to_le16((sizeof(struct smb2_signing_capabilities) + 2) + - sizeof(struct smb2_neg_context)); + pneg_ctxt->Reserved = cpu_to_le32(0); + pneg_ctxt->SigningAlgorithmCount = cpu_to_le16(1); + pneg_ctxt->SigningAlgorithms[0] = sign_algo; +} + static void build_posix_ctxt(struct smb2_posix_neg_context *pneg_ctxt) { pneg_ctxt->ContextType = SMB2_POSIX_EXTENSIONS_AVAILABLE; @@ -835,10 +847,10 @@ static void assemble_neg_contexts(struct ksmbd_conn *conn, build_encrypt_ctxt((struct smb2_encryption_neg_context *)pneg_ctxt, conn->cipher_type); rsp->NegotiateContextCount = cpu_to_le16(++neg_ctxt_cnt); - ctxt_size += sizeof(struct smb2_encryption_neg_context); + ctxt_size += sizeof(struct smb2_encryption_neg_context) + 2; /* Round to 8 byte boundary */ pneg_ctxt += - round_up(sizeof(struct smb2_encryption_neg_context), + round_up(sizeof(struct smb2_encryption_neg_context) + 2, 8); } @@ -850,9 +862,10 @@ static void assemble_neg_contexts(struct ksmbd_conn *conn, build_compression_ctxt((struct smb2_compression_ctx *)pneg_ctxt, conn->compress_algorithm); rsp->NegotiateContextCount = cpu_to_le16(++neg_ctxt_cnt); - ctxt_size += sizeof(struct smb2_compression_ctx); + ctxt_size += sizeof(struct smb2_compression_ctx) + 2; /* Round to 8 byte boundary */ - pneg_ctxt += round_up(sizeof(struct smb2_compression_ctx), 8); + pneg_ctxt += round_up(sizeof(struct smb2_compression_ctx) + 2, + 8); } if (conn->posix_ext_supported) { @@ -862,6 +875,18 @@ static void assemble_neg_contexts(struct ksmbd_conn *conn, build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt); rsp->NegotiateContextCount = cpu_to_le16(++neg_ctxt_cnt); ctxt_size += sizeof(struct smb2_posix_neg_context); + /* Round to 8 byte boundary */ + pneg_ctxt += round_up(sizeof(struct smb2_posix_neg_context), 8); + } + + if (conn->signing_negotiated) { + ctxt_size = round_up(ctxt_size, 8); + ksmbd_debug(SMB, + "assemble SMB2_SIGNING_CAPABILITIES context\n"); + build_sign_cap_ctxt((struct smb2_signing_capabilities *)pneg_ctxt, + conn->signing_algorithm); + rsp->NegotiateContextCount = cpu_to_le16(++neg_ctxt_cnt); + ctxt_size += sizeof(struct smb2_signing_capabilities) + 2; } inc_rfc1001_len(rsp, ctxt_size); @@ -881,16 +906,23 @@ static __le32 decode_preauth_ctxt(struct ksmbd_conn *conn, return err; } -static int decode_encrypt_ctxt(struct ksmbd_conn *conn, - struct smb2_encryption_neg_context *pneg_ctxt) +static void decode_encrypt_ctxt(struct ksmbd_conn *conn, + struct smb2_encryption_neg_context *pneg_ctxt, + int len_of_ctxts) { - int i; int cph_cnt = le16_to_cpu(pneg_ctxt->CipherCount); + int i, cphs_size = cph_cnt * sizeof(__le16); conn->cipher_type = 0; + if (sizeof(struct smb2_encryption_neg_context) + cphs_size > + len_of_ctxts) { + pr_err("Invalid cipher count(%d)\n", cph_cnt); + return; + } + if (!(server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION)) - goto out; + return; for (i = 0; i < cph_cnt; i++) { if (pneg_ctxt->Ciphers[i] == SMB2_ENCRYPTION_AES128_GCM || @@ -903,90 +935,122 @@ static int decode_encrypt_ctxt(struct ksmbd_conn *conn, break; } } +} -out: - /* - * Return encrypt context size in request. - * So need to plus extra number of ciphers size. - */ - return sizeof(struct smb2_encryption_neg_context) + - ((cph_cnt - 1) * 2); +static void decode_compress_ctxt(struct ksmbd_conn *conn, + struct smb2_compression_ctx *pneg_ctxt) +{ + conn->compress_algorithm = SMB3_COMPRESS_NONE; } -static int decode_compress_ctxt(struct ksmbd_conn *conn, - struct smb2_compression_ctx *pneg_ctxt) +static void decode_sign_cap_ctxt(struct ksmbd_conn *conn, + struct smb2_signing_capabilities *pneg_ctxt, + int len_of_ctxts) { - int algo_cnt = le16_to_cpu(pneg_ctxt->CompressionAlgorithmCount); + int sign_algo_cnt = le16_to_cpu(pneg_ctxt->SigningAlgorithmCount); + int i, sign_alos_size = sign_algo_cnt * sizeof(__le16); - conn->compress_algorithm = SMB3_COMPRESS_NONE; + conn->signing_negotiated = false; - /* - * Return compression context size in request. - * So need to plus extra number of CompressionAlgorithms size. - */ - return sizeof(struct smb2_encryption_neg_context) + - ((algo_cnt - 1) * 2); + if (sizeof(struct smb2_signing_capabilities) + sign_alos_size > + len_of_ctxts) { + pr_err("Invalid signing algorithm count(%d)\n", sign_algo_cnt); + return; + } + + for (i = 0; i < sign_algo_cnt; i++) { + if (pneg_ctxt->SigningAlgorithms[i] == SIGNING_ALG_HMAC_SHA256 || + pneg_ctxt->SigningAlgorithms[i] == SIGNING_ALG_AES_CMAC) { + ksmbd_debug(SMB, "Signing Algorithm ID = 0x%x\n", + pneg_ctxt->SigningAlgorithms[i]); + conn->signing_negotiated = true; + conn->signing_algorithm = + pneg_ctxt->SigningAlgorithms[i]; + break; + } + } } static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn, struct smb2_negotiate_req *req) { - int i = 0; - __le32 status = 0; /* +4 is to account for the RFC1001 len field */ - char *pneg_ctxt = (char *)req + - le32_to_cpu(req->NegotiateContextOffset) + 4; - __le16 *ContextType = (__le16 *)pneg_ctxt; + struct smb2_neg_context *pctx = (struct smb2_neg_context *)((char *)req + 4); + int i = 0, len_of_ctxts; + int offset = le32_to_cpu(req->NegotiateContextOffset); int neg_ctxt_cnt = le16_to_cpu(req->NegotiateContextCount); - int ctxt_size; + int len_of_smb = be32_to_cpu(req->hdr.smb2_buf_length); + __le32 status = STATUS_INVALID_PARAMETER; + + ksmbd_debug(SMB, "decoding %d negotiate contexts\n", neg_ctxt_cnt); + if (len_of_smb <= offset) { + ksmbd_debug(SMB, "Invalid response: negotiate context offset\n"); + return status; + } + + len_of_ctxts = len_of_smb - offset; - ksmbd_debug(SMB, "negotiate context count = %d\n", neg_ctxt_cnt); - status = STATUS_INVALID_PARAMETER; while (i++ < neg_ctxt_cnt) { - if (*ContextType == SMB2_PREAUTH_INTEGRITY_CAPABILITIES) { + int clen; + + /* check that offset is not beyond end of SMB */ + if (len_of_ctxts == 0) + break; + + if (len_of_ctxts < sizeof(struct smb2_neg_context)) + break; + + pctx = (struct smb2_neg_context *)((char *)pctx + offset); + clen = le16_to_cpu(pctx->DataLength); + if (clen + sizeof(struct smb2_neg_context) > len_of_ctxts) + break; + + if (pctx->ContextType == SMB2_PREAUTH_INTEGRITY_CAPABILITIES) { ksmbd_debug(SMB, "deassemble SMB2_PREAUTH_INTEGRITY_CAPABILITIES context\n"); if (conn->preauth_info->Preauth_HashId) break; status = decode_preauth_ctxt(conn, - (struct smb2_preauth_neg_context *)pneg_ctxt); - pneg_ctxt += DIV_ROUND_UP(sizeof(struct smb2_preauth_neg_context), 8) * 8; - } else if (*ContextType == SMB2_ENCRYPTION_CAPABILITIES) { + (struct smb2_preauth_neg_context *)pctx); + if (status != STATUS_SUCCESS) + break; + } else if (pctx->ContextType == SMB2_ENCRYPTION_CAPABILITIES) { ksmbd_debug(SMB, "deassemble SMB2_ENCRYPTION_CAPABILITIES context\n"); if (conn->cipher_type) break; - ctxt_size = decode_encrypt_ctxt(conn, - (struct smb2_encryption_neg_context *)pneg_ctxt); - pneg_ctxt += DIV_ROUND_UP(ctxt_size, 8) * 8; - } else if (*ContextType == SMB2_COMPRESSION_CAPABILITIES) { + decode_encrypt_ctxt(conn, + (struct smb2_encryption_neg_context *)pctx, + len_of_ctxts); + } else if (pctx->ContextType == SMB2_COMPRESSION_CAPABILITIES) { ksmbd_debug(SMB, "deassemble SMB2_COMPRESSION_CAPABILITIES context\n"); if (conn->compress_algorithm) break; - ctxt_size = decode_compress_ctxt(conn, - (struct smb2_compression_ctx *)pneg_ctxt); - pneg_ctxt += DIV_ROUND_UP(ctxt_size, 8) * 8; - } else if (*ContextType == SMB2_NETNAME_NEGOTIATE_CONTEXT_ID) { + decode_compress_ctxt(conn, + (struct smb2_compression_ctx *)pctx); + } else if (pctx->ContextType == SMB2_NETNAME_NEGOTIATE_CONTEXT_ID) { ksmbd_debug(SMB, "deassemble SMB2_NETNAME_NEGOTIATE_CONTEXT_ID context\n"); - ctxt_size = sizeof(struct smb2_netname_neg_context); - ctxt_size += DIV_ROUND_UP(le16_to_cpu(((struct smb2_netname_neg_context *) - pneg_ctxt)->DataLength), 8) * 8; - pneg_ctxt += ctxt_size; - } else if (*ContextType == SMB2_POSIX_EXTENSIONS_AVAILABLE) { + } else if (pctx->ContextType == SMB2_POSIX_EXTENSIONS_AVAILABLE) { ksmbd_debug(SMB, "deassemble SMB2_POSIX_EXTENSIONS_AVAILABLE context\n"); conn->posix_ext_supported = true; - pneg_ctxt += DIV_ROUND_UP(sizeof(struct smb2_posix_neg_context), 8) * 8; + } else if (pctx->ContextType == SMB2_SIGNING_CAPABILITIES) { + ksmbd_debug(SMB, + "deassemble SMB2_SIGNING_CAPABILITIES context\n"); + decode_sign_cap_ctxt(conn, + (struct smb2_signing_capabilities *)pctx, + len_of_ctxts); } - ContextType = (__le16 *)pneg_ctxt; - if (status != STATUS_SUCCESS) - break; + /* offsets must be 8 byte aligned */ + clen = (clen + 7) & ~0x7; + offset = clen + sizeof(struct smb2_neg_context); + len_of_ctxts -= clen + sizeof(struct smb2_neg_context); } return status; } @@ -1338,8 +1402,7 @@ static int ntlm_authenticate(struct ksmbd_work *work) user = session_user(conn, req); if (!user) { ksmbd_debug(SMB, "Unknown user name or an error\n"); - rsp->hdr.Status = STATUS_LOGON_FAILURE; - return -EINVAL; + return -EPERM; } /* Check for previous session */ @@ -1363,8 +1426,7 @@ static int ntlm_authenticate(struct ksmbd_work *work) if (user_guest(sess->user)) { if (conn->sign) { ksmbd_debug(SMB, "Guest login not allowed when signing enabled\n"); - rsp->hdr.Status = STATUS_LOGON_FAILURE; - return -EACCES; + return -EPERM; } rsp->SessionFlags = SMB2_SESSION_FLAG_IS_GUEST_LE; @@ -1377,8 +1439,7 @@ static int ntlm_authenticate(struct ksmbd_work *work) if (rc) { set_user_flag(sess->user, KSMBD_USER_FLAG_BAD_PASSWORD); ksmbd_debug(SMB, "authentication failed\n"); - rsp->hdr.Status = STATUS_LOGON_FAILURE; - return -EINVAL; + return -EPERM; } /* @@ -1403,8 +1464,7 @@ static int ntlm_authenticate(struct ksmbd_work *work) if (rc) { ksmbd_debug(SMB, "SMB3 encryption key generation failed\n"); - rsp->hdr.Status = STATUS_LOGON_FAILURE; - return rc; + return -EINVAL; } sess->enc = true; rsp->SessionFlags = SMB2_SESSION_FLAG_ENCRYPT_DATA_LE; @@ -1434,16 +1494,14 @@ binding_session: rc = conn->ops->generate_signingkey(sess, conn); if (rc) { ksmbd_debug(SMB, "SMB3 signing key generation failed\n"); - rsp->hdr.Status = STATUS_LOGON_FAILURE; - return rc; + return -EINVAL; } } if (conn->dialect > SMB20_PROT_ID) { if (!ksmbd_conn_lookup_dialect(conn)) { pr_err("fail to verify the dialect\n"); - rsp->hdr.Status = STATUS_USER_SESSION_DELETED; - return -EPERM; + return -ENOENT; } } return 0; @@ -1483,8 +1541,7 @@ static int krb5_authenticate(struct ksmbd_work *work) out_blob, &out_len); if (retval) { ksmbd_debug(SMB, "krb5 authentication failed\n"); - rsp->hdr.Status = STATUS_LOGON_FAILURE; - return retval; + return -EINVAL; } rsp->SecurityBufferLength = cpu_to_le16(out_len); inc_rfc1001_len(rsp, out_len - 1); @@ -1499,8 +1556,7 @@ static int krb5_authenticate(struct ksmbd_work *work) if (retval) { ksmbd_debug(SMB, "SMB3 encryption key generation failed\n"); - rsp->hdr.Status = STATUS_LOGON_FAILURE; - return retval; + return -EINVAL; } sess->enc = true; rsp->SessionFlags = SMB2_SESSION_FLAG_ENCRYPT_DATA_LE; @@ -1524,16 +1580,14 @@ static int krb5_authenticate(struct ksmbd_work *work) retval = conn->ops->generate_signingkey(sess, conn); if (retval) { ksmbd_debug(SMB, "SMB3 signing key generation failed\n"); - rsp->hdr.Status = STATUS_LOGON_FAILURE; - return retval; + return -EINVAL; } } if (conn->dialect > SMB20_PROT_ID) { if (!ksmbd_conn_lookup_dialect(conn)) { pr_err("fail to verify the dialect\n"); - rsp->hdr.Status = STATUS_USER_SESSION_DELETED; - return -EPERM; + return -ENOENT; } } return 0; @@ -1709,6 +1763,8 @@ out_err: rsp->hdr.Status = STATUS_REQUEST_NOT_ACCEPTED; else if (rc == -EFAULT) rsp->hdr.Status = STATUS_NETWORK_SESSION_EXPIRED; + else if (rc == -ENOMEM) + rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES; else if (rc) rsp->hdr.Status = STATUS_LOGON_FAILURE; diff --git a/fs/ksmbd/smb2pdu.h b/fs/ksmbd/smb2pdu.h index 0eac40e1ba65..89019f67234c 100644 --- a/fs/ksmbd/smb2pdu.h +++ b/fs/ksmbd/smb2pdu.h @@ -268,6 +268,7 @@ struct preauth_integrity_info { #define SMB2_ENCRYPTION_CAPABILITIES cpu_to_le16(2) #define SMB2_COMPRESSION_CAPABILITIES cpu_to_le16(3) #define SMB2_NETNAME_NEGOTIATE_CONTEXT_ID cpu_to_le16(5) +#define SMB2_SIGNING_CAPABILITIES cpu_to_le16(8) #define SMB2_POSIX_EXTENSIONS_AVAILABLE cpu_to_le16(0x100) struct smb2_neg_context { @@ -299,7 +300,7 @@ struct smb2_encryption_neg_context { __le32 Reserved; /* CipherCount usally 2, but can be 3 when AES256-GCM enabled */ __le16 CipherCount; /* AES-128-GCM and AES-128-CCM by default */ - __le16 Ciphers[1]; + __le16 Ciphers[]; } __packed; #define SMB3_COMPRESS_NONE cpu_to_le16(0x0000) @@ -314,7 +315,7 @@ struct smb2_compression_ctx { __le16 CompressionAlgorithmCount; __u16 Padding; __le32 Reserved1; - __le16 CompressionAlgorithms[1]; + __le16 CompressionAlgorithms[]; } __packed; #define POSIX_CTXT_DATA_LEN 16 @@ -329,7 +330,20 @@ struct smb2_netname_neg_context { __le16 ContextType; /* 0x100 */ __le16 DataLength; __le32 Reserved; - __le16 NetName[0]; /* hostname of target converted to UCS-2 */ + __le16 NetName[]; /* hostname of target converted to UCS-2 */ +} __packed; + +/* Signing algorithms */ +#define SIGNING_ALG_HMAC_SHA256 cpu_to_le16(0) +#define SIGNING_ALG_AES_CMAC cpu_to_le16(1) +#define SIGNING_ALG_AES_GMAC cpu_to_le16(2) + +struct smb2_signing_capabilities { + __le16 ContextType; /* 8 */ + __le16 DataLength; + __le32 Reserved; + __le16 SigningAlgorithmCount; + __le16 SigningAlgorithms[]; } __packed; struct smb2_negotiate_rsp { diff --git a/fs/ksmbd/transport_rdma.c b/fs/ksmbd/transport_rdma.c index f818fe358f31..f2ae6bae83f1 100644 --- a/fs/ksmbd/transport_rdma.c +++ b/fs/ksmbd/transport_rdma.c @@ -58,7 +58,7 @@ /* * User configurable initial values per SMB_DIRECT transport connection - * as defined in [MS-KSMBD] 3.1.1.1 + * as defined in [MS-SMBD] 3.1.1.1 * Those may change after a SMB_DIRECT negotiation */ /* The local peer's maximum number of credits to grant to the peer */ diff --git a/fs/ksmbd/transport_rdma.h b/fs/ksmbd/transport_rdma.h index 72e2574079f3..0fa8adc0776f 100644 --- a/fs/ksmbd/transport_rdma.h +++ b/fs/ksmbd/transport_rdma.h @@ -9,7 +9,7 @@ #define SMB_DIRECT_PORT 5445 -/* SMB DIRECT negotiation request packet [MS-KSMBD] 2.2.1 */ +/* SMB DIRECT negotiation request packet [MS-SMBD] 2.2.1 */ struct smb_direct_negotiate_req { __le16 min_version; __le16 max_version; @@ -20,7 +20,7 @@ struct smb_direct_negotiate_req { __le32 max_fragmented_size; } __packed; -/* SMB DIRECT negotiation response packet [MS-KSMBD] 2.2.2 */ +/* SMB DIRECT negotiation response packet [MS-SMBD] 2.2.2 */ struct smb_direct_negotiate_resp { __le16 min_version; __le16 max_version; @@ -37,7 +37,7 @@ struct smb_direct_negotiate_resp { #define SMB_DIRECT_RESPONSE_REQUESTED 0x0001 -/* SMB DIRECT data transfer packet with payload [MS-KSMBD] 2.2.3 */ +/* SMB DIRECT data transfer packet with payload [MS-SMBD] 2.2.3 */ struct smb_direct_data_transfer { __le16 credits_requested; __le16 credits_granted; diff --git a/fs/ksmbd/transport_tcp.c b/fs/ksmbd/transport_tcp.c index 56ec11ff5a9f..dc15a5ecd2e0 100644 --- a/fs/ksmbd/transport_tcp.c +++ b/fs/ksmbd/transport_tcp.c @@ -381,8 +381,7 @@ static void tcp_destroy_socket(struct socket *ksmbd_socket) ret = kernel_sock_shutdown(ksmbd_socket, SHUT_RDWR); if (ret) pr_err("Failed to shutdown socket: %d\n", ret); - else - sock_release(ksmbd_socket); + sock_release(ksmbd_socket); } /** |