four smb3 server fixes

-----BEGIN PGP SIGNATURE-----
 
 iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAmhAvJsACgkQiiy9cAdy
 T1F0rwv7BYKtOEGcRQSToncJOoqSxRZKPA9ulWgv5a2MVt2L91M0DcITxmQBh/Tg
 OmO1E7i2pYZr+fhDAQZeRp6g0RCfPBaUDPjslXyCwK9dJjGhADRYcg/ci7eYOFsv
 RXiG+3nsR08k03hRqerI76LhuI1OZyH32e14Sa7B35cuT4czxtz8JiTcpvFxfr3W
 rz33svuNJFNhPoFfckyxnIkQAgTvgcXbrTt/zWj2KzhoFWY91UvOdOeh6mU/OG+a
 Zeq+sx1cfG7nib8XXxAtHJkes0uO05HBkzcYcXD2Os1ZYh1tyS19IQejfev0Cqfo
 7BLQpTuoOS7j8eSJsq6bpDUgIP0PTLdleewx6jgeUHCDzs6YeOETlmDeh1ic0Iyi
 LRrMwI4MH8rtHnJnGPStsqus47AlHFd8fSXgi2Y+G0fAMJ5sziMfsbfrleHpqogK
 +3+zISyLbhjADuBAsLwIgQkjvHJp5k1GRDS3qo3Hs3knOjHKWmW3yqfTuaGf0uIq
 SQ9VBTt5
 =DKRi
 -----END PGP SIGNATURE-----

Merge tag '6.16-rc-ksmbd-server-fixes' of git://git.samba.org/ksmbd

Pull smb server updates from Steve French:
 "Four smb3 server fixes:

   - Fix for special character handling when mounting with "posix"

   - Fix for mounts from Mac for fs that don't provide unique inode
     numbers

   - Two cleanup patches (e.g. for crypto calls)"

* tag '6.16-rc-ksmbd-server-fixes' of git://git.samba.org/ksmbd:
  ksmbd: allow a filename to contain special characters on SMB3.1.1 posix extension
  ksmbd: provide zero as a unique ID to the Mac client
  ksmbd: remove unnecessary softdep on crc32
  ksmbd: use SHA-256 library API instead of crypto_shash API
This commit is contained in:
Linus Torvalds 2025-06-04 19:23:37 -07:00
commit d2fec01e89
10 changed files with 53 additions and 93 deletions

View File

@ -11,6 +11,7 @@ config SMB_SERVER
select CRYPTO_HMAC
select CRYPTO_ECB
select CRYPTO_LIB_DES
select CRYPTO_LIB_SHA256
select CRYPTO_SHA256
select CRYPTO_CMAC
select CRYPTO_SHA512

View File

@ -979,40 +979,6 @@ out:
return rc;
}
int ksmbd_gen_sd_hash(struct ksmbd_conn *conn, char *sd_buf, int len,
__u8 *pi_hash)
{
int rc;
struct ksmbd_crypto_ctx *ctx = NULL;
ctx = ksmbd_crypto_ctx_find_sha256();
if (!ctx) {
ksmbd_debug(AUTH, "could not alloc sha256\n");
return -ENOMEM;
}
rc = crypto_shash_init(CRYPTO_SHA256(ctx));
if (rc) {
ksmbd_debug(AUTH, "could not init shashn");
goto out;
}
rc = crypto_shash_update(CRYPTO_SHA256(ctx), sd_buf, len);
if (rc) {
ksmbd_debug(AUTH, "could not update with n\n");
goto out;
}
rc = crypto_shash_final(CRYPTO_SHA256(ctx), pi_hash);
if (rc) {
ksmbd_debug(AUTH, "Could not generate hash err : %d\n", rc);
goto out;
}
out:
ksmbd_release_crypto_ctx(ctx);
return rc;
}
static int ksmbd_get_encryption_key(struct ksmbd_work *work, __u64 ses_id,
int enc, u8 *key)
{

View File

@ -66,6 +66,4 @@ int ksmbd_gen_smb311_encryptionkey(struct ksmbd_conn *conn,
struct ksmbd_session *sess);
int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf,
__u8 *pi_hash);
int ksmbd_gen_sd_hash(struct ksmbd_conn *conn, char *sd_buf, int len,
__u8 *pi_hash);
#endif

View File

@ -108,6 +108,7 @@ struct ksmbd_conn {
__le16 signing_algorithm;
bool binding;
atomic_t refcnt;
bool is_aapl;
};
struct ksmbd_conn_ops {

View File

@ -75,9 +75,6 @@ static struct shash_desc *alloc_shash_desc(int id)
case CRYPTO_SHASH_CMACAES:
tfm = crypto_alloc_shash("cmac(aes)", 0, 0);
break;
case CRYPTO_SHASH_SHA256:
tfm = crypto_alloc_shash("sha256", 0, 0);
break;
case CRYPTO_SHASH_SHA512:
tfm = crypto_alloc_shash("sha512", 0, 0);
break;
@ -198,11 +195,6 @@ struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_cmacaes(void)
return ____crypto_shash_ctx_find(CRYPTO_SHASH_CMACAES);
}
struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_sha256(void)
{
return ____crypto_shash_ctx_find(CRYPTO_SHASH_SHA256);
}
struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_sha512(void)
{
return ____crypto_shash_ctx_find(CRYPTO_SHASH_SHA512);

View File

@ -13,7 +13,6 @@ enum {
CRYPTO_SHASH_HMACMD5 = 0,
CRYPTO_SHASH_HMACSHA256,
CRYPTO_SHASH_CMACAES,
CRYPTO_SHASH_SHA256,
CRYPTO_SHASH_SHA512,
CRYPTO_SHASH_MAX,
};
@ -39,14 +38,12 @@ struct ksmbd_crypto_ctx {
#define CRYPTO_HMACMD5(c) ((c)->desc[CRYPTO_SHASH_HMACMD5])
#define CRYPTO_HMACSHA256(c) ((c)->desc[CRYPTO_SHASH_HMACSHA256])
#define CRYPTO_CMACAES(c) ((c)->desc[CRYPTO_SHASH_CMACAES])
#define CRYPTO_SHA256(c) ((c)->desc[CRYPTO_SHASH_SHA256])
#define CRYPTO_SHA512(c) ((c)->desc[CRYPTO_SHASH_SHA512])
#define CRYPTO_HMACMD5_TFM(c) ((c)->desc[CRYPTO_SHASH_HMACMD5]->tfm)
#define CRYPTO_HMACSHA256_TFM(c)\
((c)->desc[CRYPTO_SHASH_HMACSHA256]->tfm)
#define CRYPTO_CMACAES_TFM(c) ((c)->desc[CRYPTO_SHASH_CMACAES]->tfm)
#define CRYPTO_SHA256_TFM(c) ((c)->desc[CRYPTO_SHASH_SHA256]->tfm)
#define CRYPTO_SHA512_TFM(c) ((c)->desc[CRYPTO_SHASH_SHA512]->tfm)
#define CRYPTO_GCM(c) ((c)->ccmaes[CRYPTO_AEAD_AES_GCM])
@ -57,7 +54,6 @@ struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_hmacmd5(void);
struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_hmacsha256(void);
struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_cmacaes(void);
struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_sha512(void);
struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_sha256(void);
struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_gcm(void);
struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_ccm(void);
void ksmbd_crypto_destroy(void);

View File

@ -631,6 +631,5 @@ MODULE_SOFTDEP("pre: sha512");
MODULE_SOFTDEP("pre: aead2");
MODULE_SOFTDEP("pre: ccm");
MODULE_SOFTDEP("pre: gcm");
MODULE_SOFTDEP("pre: crc32");
module_init(ksmbd_server_init)
module_exit(ksmbd_server_exit)

View File

@ -2874,7 +2874,7 @@ int smb2_open(struct ksmbd_work *work)
int req_op_level = 0, open_flags = 0, may_flags = 0, file_info = 0;
int rc = 0;
int contxt_cnt = 0, query_disk_id = 0;
int maximal_access_ctxt = 0, posix_ctxt = 0;
bool maximal_access_ctxt = false, posix_ctxt = false;
int s_type = 0;
int next_off = 0;
char *name = NULL;
@ -2903,6 +2903,27 @@ int smb2_open(struct ksmbd_work *work)
return create_smb2_pipe(work);
}
if (req->CreateContextsOffset && tcon->posix_extensions) {
context = smb2_find_context_vals(req, SMB2_CREATE_TAG_POSIX, 16);
if (IS_ERR(context)) {
rc = PTR_ERR(context);
goto err_out2;
} else if (context) {
struct create_posix *posix = (struct create_posix *)context;
if (le16_to_cpu(context->DataOffset) +
le32_to_cpu(context->DataLength) <
sizeof(struct create_posix) - 4) {
rc = -EINVAL;
goto err_out2;
}
ksmbd_debug(SMB, "get posix context\n");
posix_mode = le32_to_cpu(posix->Mode);
posix_ctxt = true;
}
}
if (req->NameLength) {
name = smb2_get_name((char *)req + le16_to_cpu(req->NameOffset),
le16_to_cpu(req->NameLength),
@ -2925,9 +2946,11 @@ int smb2_open(struct ksmbd_work *work)
goto err_out2;
}
rc = ksmbd_validate_filename(name);
if (rc < 0)
goto err_out2;
if (posix_ctxt == false) {
rc = ksmbd_validate_filename(name);
if (rc < 0)
goto err_out2;
}
if (ksmbd_share_veto_filename(share, name)) {
rc = -ENOENT;
@ -3085,28 +3108,6 @@ int smb2_open(struct ksmbd_work *work)
rc = -EBADF;
goto err_out2;
}
if (tcon->posix_extensions) {
context = smb2_find_context_vals(req,
SMB2_CREATE_TAG_POSIX, 16);
if (IS_ERR(context)) {
rc = PTR_ERR(context);
goto err_out2;
} else if (context) {
struct create_posix *posix =
(struct create_posix *)context;
if (le16_to_cpu(context->DataOffset) +
le32_to_cpu(context->DataLength) <
sizeof(struct create_posix) - 4) {
rc = -EINVAL;
goto err_out2;
}
ksmbd_debug(SMB, "get posix context\n");
posix_mode = le32_to_cpu(posix->Mode);
posix_ctxt = 1;
}
}
}
if (ksmbd_override_fsids(work)) {
@ -3539,6 +3540,15 @@ int smb2_open(struct ksmbd_work *work)
ksmbd_debug(SMB, "get query on disk id context\n");
query_disk_id = 1;
}
if (conn->is_aapl == false) {
context = smb2_find_context_vals(req, SMB2_CREATE_AAPL, 4);
if (IS_ERR(context)) {
rc = PTR_ERR(context);
goto err_out1;
} else if (context)
conn->is_aapl = true;
}
}
rc = ksmbd_vfs_getattr(&path, &stat);
@ -3978,7 +3988,10 @@ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level,
if (dinfo->EaSize)
dinfo->ExtFileAttributes = FILE_ATTRIBUTE_REPARSE_POINT_LE;
dinfo->Reserved = 0;
dinfo->UniqueId = cpu_to_le64(ksmbd_kstat->kstat->ino);
if (conn->is_aapl)
dinfo->UniqueId = 0;
else
dinfo->UniqueId = cpu_to_le64(ksmbd_kstat->kstat->ino);
if (d_info->hide_dot_file && d_info->name[0] == '.')
dinfo->ExtFileAttributes |= FILE_ATTRIBUTE_HIDDEN_LE;
memcpy(dinfo->FileName, conv_name, conv_len);
@ -3995,7 +4008,10 @@ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level,
smb2_get_reparse_tag_special_file(ksmbd_kstat->kstat->mode);
if (fibdinfo->EaSize)
fibdinfo->ExtFileAttributes = FILE_ATTRIBUTE_REPARSE_POINT_LE;
fibdinfo->UniqueId = cpu_to_le64(ksmbd_kstat->kstat->ino);
if (conn->is_aapl)
fibdinfo->UniqueId = 0;
else
fibdinfo->UniqueId = cpu_to_le64(ksmbd_kstat->kstat->ino);
fibdinfo->ShortNameLength = 0;
fibdinfo->Reserved = 0;
fibdinfo->Reserved2 = cpu_to_le16(0);

View File

@ -63,6 +63,9 @@ struct preauth_integrity_info {
#define SMB2_SESSION_TIMEOUT (10 * HZ)
/* Apple Defined Contexts */
#define SMB2_CREATE_AAPL "AAPL"
struct create_durable_req_v2 {
struct create_context_hdr ccontext;
__u8 Name[8];

View File

@ -4,6 +4,7 @@
* Copyright (C) 2018 Samsung Electronics Co., Ltd.
*/
#include <crypto/sha2.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/filelock.h>
@ -1476,11 +1477,7 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn,
acl.sd_buf = (char *)pntsd;
acl.sd_size = len;
rc = ksmbd_gen_sd_hash(conn, acl.sd_buf, acl.sd_size, acl.hash);
if (rc) {
pr_err("failed to generate hash for ndr acl\n");
return rc;
}
sha256(acl.sd_buf, acl.sd_size, acl.hash);
smb_acl = ksmbd_vfs_make_xattr_posix_acl(idmap, inode,
ACL_TYPE_ACCESS);
@ -1495,12 +1492,7 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn,
goto out;
}
rc = ksmbd_gen_sd_hash(conn, acl_ndr.data, acl_ndr.offset,
acl.posix_acl_hash);
if (rc) {
pr_err("failed to generate hash for ndr acl\n");
goto out;
}
sha256(acl_ndr.data, acl_ndr.offset, acl.posix_acl_hash);
rc = ndr_encode_v4_ntacl(&sd_ndr, &acl);
if (rc) {
@ -1557,11 +1549,7 @@ int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn,
goto out_free;
}
rc = ksmbd_gen_sd_hash(conn, acl_ndr.data, acl_ndr.offset, cmp_hash);
if (rc) {
pr_err("failed to generate hash for ndr acl\n");
goto out_free;
}
sha256(acl_ndr.data, acl_ndr.offset, cmp_hash);
if (memcmp(cmp_hash, acl.posix_acl_hash, XATTR_SD_HASH_SIZE)) {
pr_err("hash value diff\n");