mirror of
https://github.com/torvalds/linux.git
synced 2024-11-12 23:23:03 +00:00
nine smb3 client fixes
-----BEGIN PGP SIGNATURE----- iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAmb+z50ACgkQiiy9cAdy T1FS9Av+N4943ciID42gNZEL/33t+NuNymFHDeC1H4txMNEi6MZXb+H4HFQMCF22 ZWdb1IIUJ7dUjfX68hD+sIs7o+QsCUIGriyNLZvlg7xo7NIBXED2UVmWfLeiQZyh DVhCC62vVCYCvvyrlLMBKuTIM/mNzRe7JUTpFBN+wiiakLAgf5G/9ifoFyC6cmA3 854V3z5644WM2mPOsLxWr0CkV+pELRWwgvWeMcHXnjjrljjIi6jpCX2jthkEJgkR 6rcFYwfnS74VqfzjZl7sMD4Oc/blaTuNjj0iwZz5ThJMUIN6p/RzUvSN+2qySPqJ 7ENhcElJwr9lslDfL7X412bLRAhma+vduofHW9IPNvD3Q3okXQDBZ/FRHx5q+mZR ziBFCFT/OrotSSy8MZGOl7tD1bs29B1R98hO91qGUzo/rhzNzM93DiGAgYDxVLRE /cw08lQzkFn468MIKHrXV3qKLqAN4Wp8h2tZ80oNAMjc3MwELoKzE5pljQc8vhVI Oh3qN8IE =Ky9w -----END PGP SIGNATURE----- Merge tag 'v6.12-rc1-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6 Pull smb client fixes from Steve French: - statfs fix (e.g. when limited access to root directory of share) - special file handling fixes: fix packet validation to avoid buffer overflow for reparse points, fixes for symlink path parsing (one for reparse points, and one for SFU use case), and fix for cleanup after failed SET_REPARSE operation. - fix for SMB2.1 signing bug introduced by recent patch to NFS symlink path, and NFS reparse point validation - comment cleanup * tag 'v6.12-rc1-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6: cifs: Do not convert delimiter when parsing NFS-style symlinks cifs: Validate content of NFS reparse point buffer cifs: Fix buffer overflow when parsing NFS reparse points smb: client: Correct typos in multiple comments across various files smb: client: use actual path when queryfs cifs: Remove intermediate object of failed create reparse call Revert "smb: client: make SHA-512 TFM ephemeral" smb: Update comments about some reparse point tags cifs: Check for UTF-16 null codepoint in SFU symlink target location
This commit is contained in:
commit
b7a838ee7e
@ -55,7 +55,7 @@ struct smb3_sd {
|
||||
#define ACL_CONTROL_SI 0x0800 /* SACL Auto-Inherited */
|
||||
#define ACL_CONTROL_DI 0x0400 /* DACL Auto-Inherited */
|
||||
#define ACL_CONTROL_SC 0x0200 /* SACL computed through inheritance */
|
||||
#define ACL_CONTROL_DC 0x0100 /* DACL computed through inheritence */
|
||||
#define ACL_CONTROL_DC 0x0100 /* DACL computed through inheritance */
|
||||
#define ACL_CONTROL_SS 0x0080 /* Create server ACL */
|
||||
#define ACL_CONTROL_DT 0x0040 /* DACL provided by trusted source */
|
||||
#define ACL_CONTROL_SD 0x0020 /* SACL defaulted */
|
||||
|
@ -239,7 +239,7 @@ int cifs_verify_signature(struct smb_rqst *rqst,
|
||||
cifs_dbg(FYI, "dummy signature received for smb command 0x%x\n",
|
||||
cifs_pdu->Command);
|
||||
|
||||
/* save off the origiginal signature so we can modify the smb and check
|
||||
/* save off the original signature so we can modify the smb and check
|
||||
its signature against what the server sent */
|
||||
memcpy(server_response_sig, cifs_pdu->Signature.SecuritySignature, 8);
|
||||
|
||||
@ -700,6 +700,7 @@ cifs_crypto_secmech_release(struct TCP_Server_Info *server)
|
||||
cifs_free_hash(&server->secmech.aes_cmac);
|
||||
cifs_free_hash(&server->secmech.hmacsha256);
|
||||
cifs_free_hash(&server->secmech.md5);
|
||||
cifs_free_hash(&server->secmech.sha512);
|
||||
|
||||
if (!SERVER_IS_CHAN(server)) {
|
||||
if (server->secmech.enc) {
|
||||
|
@ -161,7 +161,7 @@ __u32 cifs_lock_secret;
|
||||
|
||||
/*
|
||||
* Bumps refcount for cifs super block.
|
||||
* Note that it should be only called if a referece to VFS super block is
|
||||
* Note that it should be only called if a reference to VFS super block is
|
||||
* already held, e.g. in open-type syscalls context. Otherwise it can race with
|
||||
* atomic_dec_and_test in deactivate_locked_super.
|
||||
*/
|
||||
@ -289,7 +289,7 @@ static void cifs_kill_sb(struct super_block *sb)
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
|
||||
|
||||
/*
|
||||
* We ned to release all dentries for the cached directories
|
||||
* We need to release all dentries for the cached directories
|
||||
* before we kill the sb.
|
||||
*/
|
||||
if (cifs_sb->root) {
|
||||
@ -313,8 +313,17 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
|
||||
struct TCP_Server_Info *server = tcon->ses->server;
|
||||
unsigned int xid;
|
||||
int rc = 0;
|
||||
const char *full_path;
|
||||
void *page;
|
||||
|
||||
xid = get_xid();
|
||||
page = alloc_dentry_path();
|
||||
|
||||
full_path = build_path_from_dentry(dentry, page);
|
||||
if (IS_ERR(full_path)) {
|
||||
rc = PTR_ERR(full_path);
|
||||
goto statfs_out;
|
||||
}
|
||||
|
||||
if (le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength) > 0)
|
||||
buf->f_namelen =
|
||||
@ -330,8 +339,10 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
|
||||
buf->f_ffree = 0; /* unlimited */
|
||||
|
||||
if (server->ops->queryfs)
|
||||
rc = server->ops->queryfs(xid, tcon, cifs_sb, buf);
|
||||
rc = server->ops->queryfs(xid, tcon, full_path, cifs_sb, buf);
|
||||
|
||||
statfs_out:
|
||||
free_dentry_path(page);
|
||||
free_xid(xid);
|
||||
return rc;
|
||||
}
|
||||
|
@ -180,6 +180,7 @@ struct session_key {
|
||||
struct cifs_secmech {
|
||||
struct shash_desc *md5; /* md5 hash function, for CIFS/SMB1 signatures */
|
||||
struct shash_desc *hmacsha256; /* hmac-sha256 hash function, for SMB2 signatures */
|
||||
struct shash_desc *sha512; /* sha512 hash function, for SMB3.1.1 preauth hash */
|
||||
struct shash_desc *aes_cmac; /* block-cipher based MAC function, for SMB3 signatures */
|
||||
|
||||
struct crypto_aead *enc; /* smb3 encryption AEAD TFM (AES-CCM and AES-GCM) */
|
||||
@ -480,7 +481,7 @@ struct smb_version_operations {
|
||||
__u16 net_fid, struct cifsInodeInfo *cifs_inode);
|
||||
/* query remote filesystem */
|
||||
int (*queryfs)(const unsigned int, struct cifs_tcon *,
|
||||
struct cifs_sb_info *, struct kstatfs *);
|
||||
const char *, struct cifs_sb_info *, struct kstatfs *);
|
||||
/* send mandatory brlock to the server */
|
||||
int (*mand_lock)(const unsigned int, struct cifsFileInfo *, __u64,
|
||||
__u64, __u32, int, int, bool);
|
||||
@ -774,7 +775,7 @@ struct TCP_Server_Info {
|
||||
} compression;
|
||||
__u16 signing_algorithm;
|
||||
__le16 cipher_type;
|
||||
/* save initital negprot hash */
|
||||
/* save initial negprot hash */
|
||||
__u8 preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE];
|
||||
bool signing_negotiated; /* true if valid signing context rcvd from server */
|
||||
bool posix_ext_supported;
|
||||
|
@ -781,7 +781,7 @@ typedef struct smb_com_logoff_andx_rsp {
|
||||
__u16 ByteCount;
|
||||
} __attribute__((packed)) LOGOFF_ANDX_RSP;
|
||||
|
||||
typedef union smb_com_tree_disconnect { /* as an altetnative can use flag on
|
||||
typedef union smb_com_tree_disconnect { /* as an alternative can use flag on
|
||||
tree_connect PDU to effect disconnect */
|
||||
/* tdis is probably simplest SMB PDU */
|
||||
struct {
|
||||
@ -2406,7 +2406,7 @@ struct cifs_posix_ace { /* access control entry (ACE) */
|
||||
__le64 cifs_uid; /* or gid */
|
||||
} __attribute__((packed));
|
||||
|
||||
struct cifs_posix_acl { /* access conrol list (ACL) */
|
||||
struct cifs_posix_acl { /* access control list (ACL) */
|
||||
__le16 version;
|
||||
__le16 access_entry_count; /* access ACL - count of entries */
|
||||
__le16 default_entry_count; /* default ACL - count of entries */
|
||||
|
@ -1215,7 +1215,7 @@ openRetry:
|
||||
req->CreateDisposition = cpu_to_le32(disposition);
|
||||
req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
|
||||
|
||||
/* BB Expirement with various impersonation levels and verify */
|
||||
/* BB Experiment with various impersonation levels and verify */
|
||||
req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
|
||||
req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
|
||||
|
||||
@ -3018,7 +3018,7 @@ static void cifs_init_ace(struct cifs_posix_ace *cifs_ace,
|
||||
|
||||
/**
|
||||
* posix_acl_to_cifs - convert ACLs from POSIX ACL to cifs format
|
||||
* @parm_data: ACLs in cifs format to conver to
|
||||
* @parm_data: ACLs in cifs format to convert to
|
||||
* @acl: ACLs in POSIX ACL format to convert from
|
||||
* @acl_type: the type of POSIX ACLs stored in @acl
|
||||
*
|
||||
@ -3995,7 +3995,7 @@ findFirstRetry:
|
||||
name_len =
|
||||
cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
|
||||
PATH_MAX, nls_codepage, remap);
|
||||
/* We can not add the asterik earlier in case
|
||||
/* We can not add the asterisk earlier in case
|
||||
it got remapped to 0xF03A as if it were part of the
|
||||
directory name instead of a wildcard */
|
||||
name_len *= 2;
|
||||
|
@ -2502,7 +2502,7 @@ refind_writable:
|
||||
}
|
||||
}
|
||||
}
|
||||
/* couldn't find useable FH with same pid, try any available */
|
||||
/* couldn't find usable FH with same pid, try any available */
|
||||
if (!any_available) {
|
||||
any_available = true;
|
||||
goto refind_writable;
|
||||
|
@ -260,7 +260,7 @@ struct smb3_fs_context {
|
||||
unsigned int min_offload;
|
||||
unsigned int retrans;
|
||||
bool sockopt_tcp_nodelay:1;
|
||||
/* attribute cache timemout for files and directories in jiffies */
|
||||
/* attribute cache timeout for files and directories in jiffies */
|
||||
unsigned long acregmax;
|
||||
unsigned long acdirmax;
|
||||
/* timeout for deferred close of files in jiffies */
|
||||
|
@ -629,10 +629,16 @@ cifs_sfu_type(struct cifs_fattr *fattr, const char *path,
|
||||
&symlink_len_utf16,
|
||||
&symlink_buf_utf16,
|
||||
&buf_type);
|
||||
/*
|
||||
* Check that read buffer has valid length and does not
|
||||
* contain UTF-16 null codepoint (via UniStrnlen() call)
|
||||
* because Linux cannot process symlink with null byte.
|
||||
*/
|
||||
if ((rc == 0) &&
|
||||
(symlink_len_utf16 > 0) &&
|
||||
(symlink_len_utf16 < fattr->cf_eof-8 + 1) &&
|
||||
(symlink_len_utf16 % 2 == 0)) {
|
||||
(symlink_len_utf16 % 2 == 0) &&
|
||||
(UniStrnlen((wchar_t *)symlink_buf_utf16, symlink_len_utf16/2) == symlink_len_utf16/2)) {
|
||||
fattr->cf_symlink_target =
|
||||
cifs_strndup_from_utf16(symlink_buf_utf16,
|
||||
symlink_len_utf16,
|
||||
|
@ -254,7 +254,7 @@ free_rsp_buf(int resp_buftype, void *rsp)
|
||||
}
|
||||
|
||||
/* NB: MID can not be set if treeCon not passed in, in that
|
||||
case it is responsbility of caller to set the mid */
|
||||
case it is responsibility of caller to set the mid */
|
||||
void
|
||||
header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
|
||||
const struct cifs_tcon *treeCon, int word_count
|
||||
|
@ -1003,7 +1003,7 @@ struct timespec64 cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset)
|
||||
year is 2**7, the last year is 1980+127, which means we need only
|
||||
consider 2 special case years, ie the years 2000 and 2100, and only
|
||||
adjust for the lack of leap year for the year 2100, as 2000 was a
|
||||
leap year (divisable by 400) */
|
||||
leap year (divisible by 400) */
|
||||
if (year >= 120) /* the year 2100 */
|
||||
days = days - 1; /* do not count leap year for the year 2100 */
|
||||
|
||||
|
@ -553,7 +553,7 @@ static void cifs_fill_dirent_std(struct cifs_dirent *de,
|
||||
const FIND_FILE_STANDARD_INFO *info)
|
||||
{
|
||||
de->name = &info->FileName[0];
|
||||
/* one byte length, no endianess conversion */
|
||||
/* one byte length, no endianness conversion */
|
||||
de->namelen = info->FileNameLength;
|
||||
de->resume_key = info->ResumeKey;
|
||||
}
|
||||
@ -815,7 +815,7 @@ static bool emit_cached_dirents(struct cached_dirents *cde,
|
||||
* However, this sequence of ->pos values may have holes
|
||||
* in it, for example dot-dirs returned from the server
|
||||
* are suppressed.
|
||||
* Handle this bu forcing ctx->pos to be the same as the
|
||||
* Handle this by forcing ctx->pos to be the same as the
|
||||
* ->pos of the current dirent we emit from the cache.
|
||||
* This means that when we emit these entries from the cache
|
||||
* we now emit them with the same ->pos value as in the
|
||||
|
@ -320,22 +320,51 @@ static int parse_reparse_posix(struct reparse_posix_data *buf,
|
||||
unsigned int len;
|
||||
u64 type;
|
||||
|
||||
len = le16_to_cpu(buf->ReparseDataLength);
|
||||
if (len < sizeof(buf->InodeType)) {
|
||||
cifs_dbg(VFS, "srv returned malformed nfs buffer\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
len -= sizeof(buf->InodeType);
|
||||
|
||||
switch ((type = le64_to_cpu(buf->InodeType))) {
|
||||
case NFS_SPECFILE_LNK:
|
||||
len = le16_to_cpu(buf->ReparseDataLength);
|
||||
if (len == 0 || (len % 2)) {
|
||||
cifs_dbg(VFS, "srv returned malformed nfs symlink buffer\n");
|
||||
return -EIO;
|
||||
}
|
||||
/*
|
||||
* Check that buffer does not contain UTF-16 null codepoint
|
||||
* because Linux cannot process symlink with null byte.
|
||||
*/
|
||||
if (UniStrnlen((wchar_t *)buf->DataBuffer, len/2) != len/2) {
|
||||
cifs_dbg(VFS, "srv returned null byte in nfs symlink target location\n");
|
||||
return -EIO;
|
||||
}
|
||||
data->symlink_target = cifs_strndup_from_utf16(buf->DataBuffer,
|
||||
len, true,
|
||||
cifs_sb->local_nls);
|
||||
if (!data->symlink_target)
|
||||
return -ENOMEM;
|
||||
convert_delimiter(data->symlink_target, '/');
|
||||
cifs_dbg(FYI, "%s: target path: %s\n",
|
||||
__func__, data->symlink_target);
|
||||
break;
|
||||
case NFS_SPECFILE_CHR:
|
||||
case NFS_SPECFILE_BLK:
|
||||
/* DataBuffer for block and char devices contains two 32-bit numbers */
|
||||
if (len != 8) {
|
||||
cifs_dbg(VFS, "srv returned malformed nfs buffer for type: 0x%llx\n", type);
|
||||
return -EIO;
|
||||
}
|
||||
break;
|
||||
case NFS_SPECFILE_FIFO:
|
||||
case NFS_SPECFILE_SOCK:
|
||||
/* DataBuffer for fifos and sockets is empty */
|
||||
if (len != 0) {
|
||||
cifs_dbg(VFS, "srv returned malformed nfs buffer for type: 0x%llx\n", type);
|
||||
return -EIO;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
cifs_dbg(VFS, "%s: unhandled inode type: 0x%llx\n",
|
||||
@ -482,12 +511,18 @@ bool cifs_reparse_point_to_fattr(struct cifs_sb_info *cifs_sb,
|
||||
u32 tag = data->reparse.tag;
|
||||
|
||||
if (tag == IO_REPARSE_TAG_NFS && buf) {
|
||||
if (le16_to_cpu(buf->ReparseDataLength) < sizeof(buf->InodeType))
|
||||
return false;
|
||||
switch (le64_to_cpu(buf->InodeType)) {
|
||||
case NFS_SPECFILE_CHR:
|
||||
if (le16_to_cpu(buf->ReparseDataLength) != sizeof(buf->InodeType) + 8)
|
||||
return false;
|
||||
fattr->cf_mode |= S_IFCHR;
|
||||
fattr->cf_rdev = reparse_mkdev(buf->DataBuffer);
|
||||
break;
|
||||
case NFS_SPECFILE_BLK:
|
||||
if (le16_to_cpu(buf->ReparseDataLength) != sizeof(buf->InodeType) + 8)
|
||||
return false;
|
||||
fattr->cf_mode |= S_IFBLK;
|
||||
fattr->cf_rdev = reparse_mkdev(buf->DataBuffer);
|
||||
break;
|
||||
|
@ -624,7 +624,7 @@ cifs_ses_add_channel(struct cifs_ses *ses,
|
||||
* to sign packets before we generate the channel signing key
|
||||
* (we sign with the session key)
|
||||
*/
|
||||
rc = smb3_crypto_shash_allocate(chan->server);
|
||||
rc = smb311_crypto_shash_allocate(chan->server);
|
||||
if (rc) {
|
||||
cifs_dbg(VFS, "%s: crypto alloc failed\n", __func__);
|
||||
mutex_unlock(&ses->session_mutex);
|
||||
|
@ -909,7 +909,7 @@ cifs_oplock_response(struct cifs_tcon *tcon, __u64 persistent_fid,
|
||||
|
||||
static int
|
||||
cifs_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
|
||||
const char *path, struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
|
||||
{
|
||||
int rc = -EOPNOTSUPP;
|
||||
|
||||
|
@ -1205,9 +1205,12 @@ struct inode *smb2_get_reparse_inode(struct cifs_open_info_data *data,
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
|
||||
struct cifsFileInfo *cfile;
|
||||
struct inode *new = NULL;
|
||||
int out_buftype[4] = {};
|
||||
struct kvec out_iov[4] = {};
|
||||
struct kvec in_iov[2];
|
||||
int cmds[2];
|
||||
int rc;
|
||||
int i;
|
||||
|
||||
oparms = CIFS_OPARMS(cifs_sb, tcon, full_path,
|
||||
SYNCHRONIZE | DELETE |
|
||||
@ -1228,7 +1231,7 @@ struct inode *smb2_get_reparse_inode(struct cifs_open_info_data *data,
|
||||
cmds[1] = SMB2_OP_POSIX_QUERY_INFO;
|
||||
cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile);
|
||||
rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, &oparms,
|
||||
in_iov, cmds, 2, cfile, NULL, NULL, NULL);
|
||||
in_iov, cmds, 2, cfile, out_iov, out_buftype, NULL);
|
||||
if (!rc) {
|
||||
rc = smb311_posix_get_inode_info(&new, full_path,
|
||||
data, sb, xid);
|
||||
@ -1237,12 +1240,29 @@ struct inode *smb2_get_reparse_inode(struct cifs_open_info_data *data,
|
||||
cmds[1] = SMB2_OP_QUERY_INFO;
|
||||
cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile);
|
||||
rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, &oparms,
|
||||
in_iov, cmds, 2, cfile, NULL, NULL, NULL);
|
||||
in_iov, cmds, 2, cfile, out_iov, out_buftype, NULL);
|
||||
if (!rc) {
|
||||
rc = cifs_get_inode_info(&new, full_path,
|
||||
data, sb, xid, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* If CREATE was successful but SMB2_OP_SET_REPARSE failed then
|
||||
* remove the intermediate object created by CREATE. Otherwise
|
||||
* empty object stay on the server when reparse call failed.
|
||||
*/
|
||||
if (rc &&
|
||||
out_iov[0].iov_base != NULL && out_buftype[0] != CIFS_NO_BUFFER &&
|
||||
((struct smb2_hdr *)out_iov[0].iov_base)->Status == STATUS_SUCCESS &&
|
||||
(out_iov[1].iov_base == NULL || out_buftype[1] == CIFS_NO_BUFFER ||
|
||||
((struct smb2_hdr *)out_iov[1].iov_base)->Status != STATUS_SUCCESS))
|
||||
smb2_unlink(xid, tcon, full_path, cifs_sb, NULL);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(out_buftype); i++)
|
||||
free_rsp_buf(out_buftype[i], out_iov[i].iov_base);
|
||||
|
||||
return rc ? ERR_PTR(rc) : new;
|
||||
}
|
||||
|
||||
|
@ -906,41 +906,41 @@ smb311_update_preauth_hash(struct cifs_ses *ses, struct TCP_Server_Info *server,
|
||||
|| (hdr->Status !=
|
||||
cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))))
|
||||
return 0;
|
||||
ok:
|
||||
rc = cifs_alloc_hash("sha512", &sha512);
|
||||
if (rc) {
|
||||
cifs_dbg(VFS, "%s: Could not allocate SHA512 shash, rc=%d\n", __func__, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
ok:
|
||||
rc = smb311_crypto_shash_allocate(server);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
sha512 = server->secmech.sha512;
|
||||
rc = crypto_shash_init(sha512);
|
||||
if (rc) {
|
||||
cifs_dbg(VFS, "%s: Could not init SHA512 shash, rc=%d\n", __func__, rc);
|
||||
goto err_free;
|
||||
cifs_dbg(VFS, "%s: Could not init sha512 shash\n", __func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = crypto_shash_update(sha512, ses->preauth_sha_hash,
|
||||
SMB2_PREAUTH_HASH_SIZE);
|
||||
if (rc) {
|
||||
cifs_dbg(VFS, "%s: Could not update SHA512 shash, rc=%d\n", __func__, rc);
|
||||
goto err_free;
|
||||
cifs_dbg(VFS, "%s: Could not update sha512 shash\n", __func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
for (i = 0; i < nvec; i++) {
|
||||
rc = crypto_shash_update(sha512, iov[i].iov_base, iov[i].iov_len);
|
||||
if (rc) {
|
||||
cifs_dbg(VFS, "%s: Could not update SHA512 shash, rc=%d\n", __func__, rc);
|
||||
goto err_free;
|
||||
cifs_dbg(VFS, "%s: Could not update sha512 shash\n",
|
||||
__func__);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
rc = crypto_shash_final(sha512, ses->preauth_sha_hash);
|
||||
if (rc) {
|
||||
cifs_dbg(VFS, "%s: Could not finalize SHA12 shash, rc=%d\n", __func__, rc);
|
||||
goto err_free;
|
||||
cifs_dbg(VFS, "%s: Could not finalize sha512 shash\n",
|
||||
__func__);
|
||||
return rc;
|
||||
}
|
||||
err_free:
|
||||
cifs_free_hash(&sha512);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2177,7 +2177,7 @@ smb3_enum_snapshots(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
NULL, 0 /* no input data */, max_response_size,
|
||||
(char **)&retbuf,
|
||||
&ret_data_len);
|
||||
cifs_dbg(FYI, "enum snaphots ioctl returned %d and ret buflen is %d\n",
|
||||
cifs_dbg(FYI, "enum snapshots ioctl returned %d and ret buflen is %d\n",
|
||||
rc, ret_data_len);
|
||||
if (rc)
|
||||
return rc;
|
||||
@ -2838,7 +2838,7 @@ out_free_path:
|
||||
|
||||
static int
|
||||
smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
|
||||
const char *path, struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
|
||||
{
|
||||
struct smb2_query_info_rsp *rsp;
|
||||
struct smb2_fs_full_size_info *info = NULL;
|
||||
@ -2847,7 +2847,7 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
int rc;
|
||||
|
||||
|
||||
rc = smb2_query_info_compound(xid, tcon, "",
|
||||
rc = smb2_query_info_compound(xid, tcon, path,
|
||||
FILE_READ_ATTRIBUTES,
|
||||
FS_FULL_SIZE_INFORMATION,
|
||||
SMB2_O_INFO_FILESYSTEM,
|
||||
@ -2875,28 +2875,33 @@ qfs_exit:
|
||||
|
||||
static int
|
||||
smb311_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
|
||||
const char *path, struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
|
||||
{
|
||||
int rc;
|
||||
__le16 srch_path = 0; /* Null - open root of share */
|
||||
__le16 *utf16_path = NULL;
|
||||
u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
|
||||
struct cifs_open_parms oparms;
|
||||
struct cifs_fid fid;
|
||||
|
||||
if (!tcon->posix_extensions)
|
||||
return smb2_queryfs(xid, tcon, cifs_sb, buf);
|
||||
return smb2_queryfs(xid, tcon, path, cifs_sb, buf);
|
||||
|
||||
oparms = (struct cifs_open_parms) {
|
||||
.tcon = tcon,
|
||||
.path = "",
|
||||
.path = path,
|
||||
.desired_access = FILE_READ_ATTRIBUTES,
|
||||
.disposition = FILE_OPEN,
|
||||
.create_options = cifs_create_options(cifs_sb, 0),
|
||||
.fid = &fid,
|
||||
};
|
||||
|
||||
rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL,
|
||||
utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
|
||||
if (utf16_path == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL,
|
||||
NULL, NULL);
|
||||
kfree(utf16_path);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
@ -3583,7 +3588,7 @@ static long smb3_simple_falloc(struct file *file, struct cifs_tcon *tcon,
|
||||
/*
|
||||
* At this point, we are trying to fallocate an internal
|
||||
* regions of a sparse file. Since smb2 does not have a
|
||||
* fallocate command we have two otions on how to emulate this.
|
||||
* fallocate command we have two options on how to emulate this.
|
||||
* We can either turn the entire file to become non-sparse
|
||||
* which we only do if the fallocate is for virtually
|
||||
* the whole file, or we can overwrite the region with zeroes
|
||||
|
@ -2986,7 +2986,7 @@ replay_again:
|
||||
|
||||
SMB2_close(xid, tcon, rsp->PersistentFileId, rsp->VolatileFileId);
|
||||
|
||||
/* Eventually save off posix specific response info and timestaps */
|
||||
/* Eventually save off posix specific response info and timestamps */
|
||||
|
||||
err_free_rsp_buf:
|
||||
free_rsp_buf(resp_buftype, rsp);
|
||||
@ -4581,7 +4581,7 @@ smb2_readv_callback(struct mid_q_entry *mid)
|
||||
}
|
||||
#ifdef CONFIG_CIFS_SMB_DIRECT
|
||||
/*
|
||||
* If this rdata has a memmory registered, the MR can be freed
|
||||
* If this rdata has a memory registered, the MR can be freed
|
||||
* MR needs to be freed as soon as I/O finishes to prevent deadlock
|
||||
* because they have limited number and are used for future I/Os
|
||||
*/
|
||||
|
@ -291,7 +291,7 @@ extern int smb2_validate_and_copy_iov(unsigned int offset,
|
||||
extern void smb2_copy_fs_info_to_kstatfs(
|
||||
struct smb2_fs_full_size_info *pfs_inf,
|
||||
struct kstatfs *kst);
|
||||
extern int smb3_crypto_shash_allocate(struct TCP_Server_Info *server);
|
||||
extern int smb311_crypto_shash_allocate(struct TCP_Server_Info *server);
|
||||
extern int smb311_update_preauth_hash(struct cifs_ses *ses,
|
||||
struct TCP_Server_Info *server,
|
||||
struct kvec *iov, int nvec);
|
||||
|
@ -26,7 +26,8 @@
|
||||
#include "../common/smb2status.h"
|
||||
#include "smb2glob.h"
|
||||
|
||||
int smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
|
||||
static int
|
||||
smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
|
||||
{
|
||||
struct cifs_secmech *p = &server->secmech;
|
||||
int rc;
|
||||
@ -45,6 +46,33 @@ err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
smb311_crypto_shash_allocate(struct TCP_Server_Info *server)
|
||||
{
|
||||
struct cifs_secmech *p = &server->secmech;
|
||||
int rc = 0;
|
||||
|
||||
rc = cifs_alloc_hash("hmac(sha256)", &p->hmacsha256);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = cifs_alloc_hash("cmac(aes)", &p->aes_cmac);
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
rc = cifs_alloc_hash("sha512", &p->sha512);
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
cifs_free_hash(&p->aes_cmac);
|
||||
cifs_free_hash(&p->hmacsha256);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int smb2_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key)
|
||||
{
|
||||
@ -668,7 +696,7 @@ smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
|
||||
shdr->Command);
|
||||
|
||||
/*
|
||||
* Save off the origiginal signature so we can modify the smb and check
|
||||
* Save off the original signature so we can modify the smb and check
|
||||
* our calculated signature against what the server sent.
|
||||
*/
|
||||
memcpy(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE);
|
||||
|
@ -219,7 +219,7 @@ static int smbd_conn_upcall(
|
||||
|
||||
case RDMA_CM_EVENT_DEVICE_REMOVAL:
|
||||
case RDMA_CM_EVENT_DISCONNECTED:
|
||||
/* This happenes when we fail the negotiation */
|
||||
/* This happens when we fail the negotiation */
|
||||
if (info->transport_status == SMBD_NEGOTIATE_FAILED) {
|
||||
info->transport_status = SMBD_DISCONNECTED;
|
||||
wake_up(&info->conn_wait);
|
||||
@ -1344,7 +1344,7 @@ void smbd_destroy(struct TCP_Server_Info *server)
|
||||
* are not locked by srv_mutex. It is possible some processes are
|
||||
* blocked on transport srv_mutex while holding memory registration.
|
||||
* Release the transport srv_mutex to allow them to hit the failure
|
||||
* path when sending data, and then release memory registartions.
|
||||
* path when sending data, and then release memory registrations.
|
||||
*/
|
||||
log_rdma_event(INFO, "freeing mr list\n");
|
||||
wake_up_interruptible_all(&info->wait_mr);
|
||||
|
@ -111,7 +111,7 @@ struct smbd_connection {
|
||||
/* Used by transport to wait until all MRs are returned */
|
||||
wait_queue_head_t wait_for_mr_cleanup;
|
||||
|
||||
/* Activity accoutning */
|
||||
/* Activity accounting */
|
||||
atomic_t send_pending;
|
||||
wait_queue_head_t wait_send_pending;
|
||||
wait_queue_head_t wait_post_send;
|
||||
|
@ -140,20 +140,21 @@
|
||||
/* Used by the DFS filter See MS-DFSC */
|
||||
#define IO_REPARSE_TAG_DFSR 0x80000012
|
||||
#define IO_REPARSE_TAG_FILTER_MANAGER 0x8000000B
|
||||
/* See section MS-FSCC 2.1.2.4 */
|
||||
/* Native SMB symlinks since Windows Vista, see MS-FSCC 2.1.2.4 */
|
||||
#define IO_REPARSE_TAG_SYMLINK 0xA000000C
|
||||
#define IO_REPARSE_TAG_DEDUP 0x80000013
|
||||
#define IO_REPARSE_APPXSTREAM 0xC0000014
|
||||
/* NFS symlinks, Win 8/SMB3 and later */
|
||||
/* NFS special files used by Windows NFS server since Windows Server 2012, see MS-FSCC 2.1.2.6 */
|
||||
#define IO_REPARSE_TAG_NFS 0x80000014
|
||||
/*
|
||||
* AzureFileSync - see
|
||||
* https://docs.microsoft.com/en-us/azure/storage/files/storage-sync-cloud-tiering
|
||||
*/
|
||||
#define IO_REPARSE_TAG_AZ_FILE_SYNC 0x8000001e
|
||||
/* Native Win32 AF_UNIX sockets since Windows 10 April 2018 Update, used also by WSL */
|
||||
#define IO_REPARSE_TAG_AF_UNIX 0x80000023
|
||||
/* WSL reparse tags */
|
||||
#define IO_REPARSE_TAG_LX_SYMLINK 0xA000001D
|
||||
#define IO_REPARSE_TAG_AF_UNIX 0x80000023
|
||||
#define IO_REPARSE_TAG_LX_FIFO 0x80000024
|
||||
#define IO_REPARSE_TAG_LX_CHR 0x80000025
|
||||
#define IO_REPARSE_TAG_LX_BLK 0x80000026
|
||||
|
Loading…
Reference in New Issue
Block a user