6 smb3 server fixes, including one for RDMA, one for improving NTLMSSP auth, one for improved buffer validation, one for stable
-----BEGIN PGP SIGNATURE----- iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAmH/ARYACgkQiiy9cAdy T1GRYAwAp6iS2iyjvB5OXesiqj9b6ejn66dyA51Jaee8CvUx7YCNQVbnoCH3hVZX wHIMfvcGEej7QR8jtAipOdTeMbWlnNAxCC//TZjRgOnpRGe/uVqPEh7c5e1YFbhM UlNuN1zvWfn9n5jZIeeV8z2LuAj9mJCOAD4qjHJtPCh/vgyHzXfSFkC+7Ryc+41I fUvp43rz3xs73+uz4cZOhFGwv0CQxCSvddoUPCioF9JQlx6pkfiJjnoUPrUGtNJN RGjcZ5Er4GNMSeHhETLq83Sua5pagZRJL8F3Z7mpO+6iU97k3nfpZh29WaRDA4dN rtEVcm/juB2hFBgPU9m6QyXCfSnKjEVU59QJrVxHT89FluRW43p1CHCpTaLbPKHA +5emfpkHCreR3qLc17eIX4SmYfoChEeT7f00et5okmhyyyHPFu3adKVV8e4SRsUA sIJDI8oaPkhJgvj5ZZo20avKQ0wPR3m7zA+JjBKgiy8UmhV5Vl3hkdiVKU3r5Q4v TsKqukpl =CJKx -----END PGP SIGNATURE----- Merge tag '5.17-rc3-ksmbd-server-fixes' of git://git.samba.org/ksmbd Pull ksmbd server fixes from Steve French: - NTLMSSP authentication improvement - RDMA (smbdirect) fix allowing broader set of NICs to be supported - improved buffer validation - additional small fixes, including a posix extensions fix for stable * tag '5.17-rc3-ksmbd-server-fixes' of git://git.samba.org/ksmbd: ksmbd: add support for key exchange ksmbd: reduce smb direct max read/write size ksmbd: don't align last entry offset in smb2 query directory ksmbd: fix same UniqueId for dot and dotdot entries ksmbd: smbd: validate buffer descriptor structures ksmbd: fix SMB 3.11 posix extension mount failure
This commit is contained in:
Коммит
555f3d7be9
|
@ -369,8 +369,8 @@ source "fs/ksmbd/Kconfig"
|
|||
|
||||
config SMBFS_COMMON
|
||||
tristate
|
||||
default y if CIFS=y
|
||||
default m if CIFS=m
|
||||
default y if CIFS=y || SMB_SERVER=y
|
||||
default m if CIFS=m || SMB_SERVER=m
|
||||
|
||||
source "fs/coda/Kconfig"
|
||||
source "fs/afs/Kconfig"
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "mgmt/user_config.h"
|
||||
#include "crypto_ctx.h"
|
||||
#include "transport_ipc.h"
|
||||
#include "../smbfs_common/arc4.h"
|
||||
|
||||
/*
|
||||
* Fixed format data defining GSS header and fixed string
|
||||
|
@ -336,6 +337,29 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
|
|||
nt_len - CIFS_ENCPWD_SIZE,
|
||||
domain_name, conn->ntlmssp.cryptkey);
|
||||
kfree(domain_name);
|
||||
|
||||
/* The recovered secondary session key */
|
||||
if (conn->ntlmssp.client_flags & NTLMSSP_NEGOTIATE_KEY_XCH) {
|
||||
struct arc4_ctx *ctx_arc4;
|
||||
unsigned int sess_key_off, sess_key_len;
|
||||
|
||||
sess_key_off = le32_to_cpu(authblob->SessionKey.BufferOffset);
|
||||
sess_key_len = le16_to_cpu(authblob->SessionKey.Length);
|
||||
|
||||
if (blob_len < (u64)sess_key_off + sess_key_len)
|
||||
return -EINVAL;
|
||||
|
||||
ctx_arc4 = kmalloc(sizeof(*ctx_arc4), GFP_KERNEL);
|
||||
if (!ctx_arc4)
|
||||
return -ENOMEM;
|
||||
|
||||
cifs_arc4_setkey(ctx_arc4, sess->sess_key,
|
||||
SMB2_NTLMV2_SESSKEY_SIZE);
|
||||
cifs_arc4_crypt(ctx_arc4, sess->sess_key,
|
||||
(char *)authblob + sess_key_off, sess_key_len);
|
||||
kfree_sensitive(ctx_arc4);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -408,6 +432,9 @@ ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
|
|||
(cflags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
|
||||
flags |= NTLMSSP_NEGOTIATE_EXTENDED_SEC;
|
||||
|
||||
if (cflags & NTLMSSP_NEGOTIATE_KEY_XCH)
|
||||
flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
|
||||
|
||||
chgblob->NegotiateFlags = cpu_to_le32(flags);
|
||||
len = strlen(ksmbd_netbios_name());
|
||||
name = kmalloc(2 + UNICODE_LEN(len), GFP_KERNEL);
|
||||
|
|
|
@ -2688,7 +2688,7 @@ int smb2_open(struct ksmbd_work *work)
|
|||
(struct create_posix *)context;
|
||||
if (le16_to_cpu(context->DataOffset) +
|
||||
le32_to_cpu(context->DataLength) <
|
||||
sizeof(struct create_posix)) {
|
||||
sizeof(struct create_posix) - 4) {
|
||||
rc = -EINVAL;
|
||||
goto err_out1;
|
||||
}
|
||||
|
@ -3422,9 +3422,9 @@ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level,
|
|||
goto free_conv_name;
|
||||
}
|
||||
|
||||
struct_sz = readdir_info_level_struct_sz(info_level);
|
||||
next_entry_offset = ALIGN(struct_sz - 1 + conv_len,
|
||||
KSMBD_DIR_INFO_ALIGNMENT);
|
||||
struct_sz = readdir_info_level_struct_sz(info_level) - 1 + conv_len;
|
||||
next_entry_offset = ALIGN(struct_sz, KSMBD_DIR_INFO_ALIGNMENT);
|
||||
d_info->last_entry_off_align = next_entry_offset - struct_sz;
|
||||
|
||||
if (next_entry_offset > d_info->out_buf_len) {
|
||||
d_info->out_buf_len = 0;
|
||||
|
@ -3976,6 +3976,7 @@ int smb2_query_dir(struct ksmbd_work *work)
|
|||
((struct file_directory_info *)
|
||||
((char *)rsp->Buffer + d_info.last_entry_offset))
|
||||
->NextEntryOffset = 0;
|
||||
d_info.data_count -= d_info.last_entry_off_align;
|
||||
|
||||
rsp->StructureSize = cpu_to_le16(9);
|
||||
rsp->OutputBufferOffset = cpu_to_le16(72);
|
||||
|
@ -6126,13 +6127,26 @@ static int smb2_set_remote_key_for_rdma(struct ksmbd_work *work,
|
|||
__le16 ChannelInfoOffset,
|
||||
__le16 ChannelInfoLength)
|
||||
{
|
||||
unsigned int i, ch_count;
|
||||
|
||||
if (work->conn->dialect == SMB30_PROT_ID &&
|
||||
Channel != SMB2_CHANNEL_RDMA_V1)
|
||||
return -EINVAL;
|
||||
|
||||
if (ChannelInfoOffset == 0 ||
|
||||
le16_to_cpu(ChannelInfoLength) < sizeof(*desc))
|
||||
ch_count = le16_to_cpu(ChannelInfoLength) / sizeof(*desc);
|
||||
if (ksmbd_debug_types & KSMBD_DEBUG_RDMA) {
|
||||
for (i = 0; i < ch_count; i++) {
|
||||
pr_info("RDMA r/w request %#x: token %#x, length %#x\n",
|
||||
i,
|
||||
le32_to_cpu(desc[i].token),
|
||||
le32_to_cpu(desc[i].length));
|
||||
}
|
||||
}
|
||||
if (ch_count != 1) {
|
||||
ksmbd_debug(RDMA, "RDMA multiple buffer descriptors %d are not supported yet\n",
|
||||
ch_count);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
work->need_invalidate_rkey =
|
||||
(Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE);
|
||||
|
@ -6185,9 +6199,15 @@ int smb2_read(struct ksmbd_work *work)
|
|||
|
||||
if (req->Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE ||
|
||||
req->Channel == SMB2_CHANNEL_RDMA_V1) {
|
||||
unsigned int ch_offset = le16_to_cpu(req->ReadChannelInfoOffset);
|
||||
|
||||
if (ch_offset < offsetof(struct smb2_read_req, Buffer)) {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
err = smb2_set_remote_key_for_rdma(work,
|
||||
(struct smb2_buffer_desc_v1 *)
|
||||
&req->Buffer[0],
|
||||
((char *)req + ch_offset),
|
||||
req->Channel,
|
||||
req->ReadChannelInfoOffset,
|
||||
req->ReadChannelInfoLength);
|
||||
|
@ -6428,11 +6448,16 @@ int smb2_write(struct ksmbd_work *work)
|
|||
|
||||
if (req->Channel == SMB2_CHANNEL_RDMA_V1 ||
|
||||
req->Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE) {
|
||||
if (req->Length != 0 || req->DataOffset != 0)
|
||||
return -EINVAL;
|
||||
unsigned int ch_offset = le16_to_cpu(req->WriteChannelInfoOffset);
|
||||
|
||||
if (req->Length != 0 || req->DataOffset != 0 ||
|
||||
ch_offset < offsetof(struct smb2_write_req, Buffer)) {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
err = smb2_set_remote_key_for_rdma(work,
|
||||
(struct smb2_buffer_desc_v1 *)
|
||||
&req->Buffer[0],
|
||||
((char *)req + ch_offset),
|
||||
req->Channel,
|
||||
req->WriteChannelInfoOffset,
|
||||
req->WriteChannelInfoLength);
|
||||
|
|
|
@ -308,14 +308,17 @@ int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work, int info_level,
|
|||
for (i = 0; i < 2; i++) {
|
||||
struct kstat kstat;
|
||||
struct ksmbd_kstat ksmbd_kstat;
|
||||
struct dentry *dentry;
|
||||
|
||||
if (!dir->dot_dotdot[i]) { /* fill dot entry info */
|
||||
if (i == 0) {
|
||||
d_info->name = ".";
|
||||
d_info->name_len = 1;
|
||||
dentry = dir->filp->f_path.dentry;
|
||||
} else {
|
||||
d_info->name = "..";
|
||||
d_info->name_len = 2;
|
||||
dentry = dir->filp->f_path.dentry->d_parent;
|
||||
}
|
||||
|
||||
if (!match_pattern(d_info->name, d_info->name_len,
|
||||
|
@ -327,7 +330,7 @@ int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work, int info_level,
|
|||
ksmbd_kstat.kstat = &kstat;
|
||||
ksmbd_vfs_fill_dentry_attrs(work,
|
||||
user_ns,
|
||||
dir->filp->f_path.dentry->d_parent,
|
||||
dentry,
|
||||
&ksmbd_kstat);
|
||||
rc = fn(conn, info_level, d_info, &ksmbd_kstat);
|
||||
if (rc)
|
||||
|
|
|
@ -80,7 +80,7 @@ static int smb_direct_max_fragmented_recv_size = 1024 * 1024;
|
|||
/* The maximum single-message size which can be received */
|
||||
static int smb_direct_max_receive_size = 8192;
|
||||
|
||||
static int smb_direct_max_read_write_size = 1048512;
|
||||
static int smb_direct_max_read_write_size = 524224;
|
||||
|
||||
static int smb_direct_max_outstanding_rw_ops = 8;
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ struct ksmbd_dir_info {
|
|||
int last_entry_offset;
|
||||
bool hide_dot_file;
|
||||
int flags;
|
||||
int last_entry_off_align;
|
||||
};
|
||||
|
||||
struct ksmbd_readdir_data {
|
||||
|
|
Загрузка…
Ссылка в новой задаче