mirror of
https://github.com/torvalds/linux.git
synced 2024-12-28 13:51:44 +00:00
7 smb3 client fixes
-----BEGIN PGP SIGNATURE----- iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAmPB/t0ACgkQiiy9cAdy T1Gvbwv+LIXF5dHNGHDuezecbD8T9sRF2v15Mh7i6SSg7BWeXXebYY4dyrSQ5SHu KqsN2Y3P3A0ZQ3ApzFryImM6BwSpOeyCsVRhl7VCWnMgXcroqc/O6F6/YRFVkUAi iWWZLXM7WFBQGXUbPXaiPc+wCRARrnul9p+48Teyy0CJWiWormQmkznVxeihErDX /pWdQdvJeFcUrIj1H3e4cyJF2hVzRiUGI/eZmBGlDyaK192vYgGYO2AhHnTfd7fU dUJ+/trVw0koyC5/86veHRqCcXzFD44ORkAB46NaCic1K8t+RPhmxgtriiNLcCrQ kEmeub6ayPkuniV88NBEPXaDy0S/cEYHr7GEuZTn4sq+hw//y5KbKN3sa6aLHsMH 46BIHcyTXU59eNJ4lWOjoqD2NiqP2GYFY4PZftB85H1EW8Fchwcsw4WzW0ENpzmi qcWslXDKYjJIZ6NHnBiR/FYI1VdsmoGbDzMhrHreCrWCuIuVaqfrFPMnvE8f5dqY fkfnkqT4 =SdZA -----END PGP SIGNATURE----- Merge tag '6.2-rc3-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6 Pull cifs fixes from Steve French: - memory leak and double free fix - two symlink fixes - minor cleanup fix - two smb1 fixes * tag '6.2-rc3-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6: cifs: Fix uninitialized memory read for smb311 posix symlink create cifs: fix potential memory leaks in session setup cifs: do not query ifaces on smb1 mounts cifs: fix double free on failed kerberos auth cifs: remove redundant assignment to the variable match cifs: fix file info setting in cifs_open_file() cifs: fix file info setting in cifs_query_path_info()
This commit is contained in:
commit
b35ad63eec
@ -278,6 +278,7 @@ build_avpair_blob(struct cifs_ses *ses, const struct nls_table *nls_cp)
|
|||||||
* ( for NTLMSSP_AV_NB_DOMAIN_NAME followed by NTLMSSP_AV_EOL ) +
|
* ( for NTLMSSP_AV_NB_DOMAIN_NAME followed by NTLMSSP_AV_EOL ) +
|
||||||
* unicode length of a netbios domain name
|
* unicode length of a netbios domain name
|
||||||
*/
|
*/
|
||||||
|
kfree_sensitive(ses->auth_key.response);
|
||||||
ses->auth_key.len = size + 2 * dlen;
|
ses->auth_key.len = size + 2 * dlen;
|
||||||
ses->auth_key.response = kzalloc(ses->auth_key.len, GFP_KERNEL);
|
ses->auth_key.response = kzalloc(ses->auth_key.len, GFP_KERNEL);
|
||||||
if (!ses->auth_key.response) {
|
if (!ses->auth_key.response) {
|
||||||
|
@ -2606,11 +2606,14 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx)
|
|||||||
INIT_LIST_HEAD(&tcon->pending_opens);
|
INIT_LIST_HEAD(&tcon->pending_opens);
|
||||||
tcon->status = TID_GOOD;
|
tcon->status = TID_GOOD;
|
||||||
|
|
||||||
/* schedule query interfaces poll */
|
|
||||||
INIT_DELAYED_WORK(&tcon->query_interfaces,
|
INIT_DELAYED_WORK(&tcon->query_interfaces,
|
||||||
smb2_query_server_interfaces);
|
smb2_query_server_interfaces);
|
||||||
queue_delayed_work(cifsiod_wq, &tcon->query_interfaces,
|
if (ses->server->dialect >= SMB30_PROT_ID &&
|
||||||
(SMB_INTERFACE_POLL_INTERVAL * HZ));
|
(ses->server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)) {
|
||||||
|
/* schedule query interfaces poll */
|
||||||
|
queue_delayed_work(cifsiod_wq, &tcon->query_interfaces,
|
||||||
|
(SMB_INTERFACE_POLL_INTERVAL * HZ));
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock(&cifs_tcp_ses_lock);
|
spin_lock(&cifs_tcp_ses_lock);
|
||||||
list_add(&tcon->tcon_list, &ses->tcon_list);
|
list_add(&tcon->tcon_list, &ses->tcon_list);
|
||||||
|
@ -1299,7 +1299,6 @@ static bool target_share_equal(struct TCP_Server_Info *server, const char *s1, c
|
|||||||
* Resolve share's hostname and check if server address matches. Otherwise just ignore it
|
* Resolve share's hostname and check if server address matches. Otherwise just ignore it
|
||||||
* as we could not have upcall to resolve hostname or failed to convert ip address.
|
* as we could not have upcall to resolve hostname or failed to convert ip address.
|
||||||
*/
|
*/
|
||||||
match = true;
|
|
||||||
extract_unc_hostname(s1, &host, &hostlen);
|
extract_unc_hostname(s1, &host, &hostlen);
|
||||||
scnprintf(unc, sizeof(unc), "\\\\%.*s", (int)hostlen, host);
|
scnprintf(unc, sizeof(unc), "\\\\%.*s", (int)hostlen, host);
|
||||||
|
|
||||||
|
@ -428,6 +428,7 @@ smb3_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
|
|||||||
oparms.disposition = FILE_CREATE;
|
oparms.disposition = FILE_CREATE;
|
||||||
oparms.fid = &fid;
|
oparms.fid = &fid;
|
||||||
oparms.reconnect = false;
|
oparms.reconnect = false;
|
||||||
|
oparms.mode = 0644;
|
||||||
|
|
||||||
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL,
|
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
|
@ -815,6 +815,7 @@ int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (tilen) {
|
if (tilen) {
|
||||||
|
kfree_sensitive(ses->auth_key.response);
|
||||||
ses->auth_key.response = kmemdup(bcc_ptr + tioffset, tilen,
|
ses->auth_key.response = kmemdup(bcc_ptr + tioffset, tilen,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!ses->auth_key.response) {
|
if (!ses->auth_key.response) {
|
||||||
@ -1428,6 +1429,7 @@ sess_auth_kerberos(struct sess_data *sess_data)
|
|||||||
goto out_put_spnego_key;
|
goto out_put_spnego_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kfree_sensitive(ses->auth_key.response);
|
||||||
ses->auth_key.response = kmemdup(msg->data, msg->sesskey_len,
|
ses->auth_key.response = kmemdup(msg->data, msg->sesskey_len,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!ses->auth_key.response) {
|
if (!ses->auth_key.response) {
|
||||||
|
@ -562,17 +562,20 @@ static int cifs_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
|
|||||||
if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
|
if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
|
||||||
rc = SMBQueryInformation(xid, tcon, full_path, &fi, cifs_sb->local_nls,
|
rc = SMBQueryInformation(xid, tcon, full_path, &fi, cifs_sb->local_nls,
|
||||||
cifs_remap(cifs_sb));
|
cifs_remap(cifs_sb));
|
||||||
if (!rc)
|
|
||||||
move_cifs_info_to_smb2(&data->fi, &fi);
|
|
||||||
*adjustTZ = true;
|
*adjustTZ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rc && (le32_to_cpu(fi.Attributes) & ATTR_REPARSE)) {
|
if (!rc) {
|
||||||
int tmprc;
|
int tmprc;
|
||||||
int oplock = 0;
|
int oplock = 0;
|
||||||
struct cifs_fid fid;
|
struct cifs_fid fid;
|
||||||
struct cifs_open_parms oparms;
|
struct cifs_open_parms oparms;
|
||||||
|
|
||||||
|
move_cifs_info_to_smb2(&data->fi, &fi);
|
||||||
|
|
||||||
|
if (!(le32_to_cpu(fi.Attributes) & ATTR_REPARSE))
|
||||||
|
return 0;
|
||||||
|
|
||||||
oparms.tcon = tcon;
|
oparms.tcon = tcon;
|
||||||
oparms.cifs_sb = cifs_sb;
|
oparms.cifs_sb = cifs_sb;
|
||||||
oparms.desired_access = FILE_READ_ATTRIBUTES;
|
oparms.desired_access = FILE_READ_ATTRIBUTES;
|
||||||
@ -716,17 +719,25 @@ cifs_mkdir_setinfo(struct inode *inode, const char *full_path,
|
|||||||
static int cifs_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32 *oplock,
|
static int cifs_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32 *oplock,
|
||||||
void *buf)
|
void *buf)
|
||||||
{
|
{
|
||||||
FILE_ALL_INFO *fi = buf;
|
struct cifs_open_info_data *data = buf;
|
||||||
|
FILE_ALL_INFO fi = {};
|
||||||
|
int rc;
|
||||||
|
|
||||||
if (!(oparms->tcon->ses->capabilities & CAP_NT_SMBS))
|
if (!(oparms->tcon->ses->capabilities & CAP_NT_SMBS))
|
||||||
return SMBLegacyOpen(xid, oparms->tcon, oparms->path,
|
rc = SMBLegacyOpen(xid, oparms->tcon, oparms->path,
|
||||||
oparms->disposition,
|
oparms->disposition,
|
||||||
oparms->desired_access,
|
oparms->desired_access,
|
||||||
oparms->create_options,
|
oparms->create_options,
|
||||||
&oparms->fid->netfid, oplock, fi,
|
&oparms->fid->netfid, oplock, &fi,
|
||||||
oparms->cifs_sb->local_nls,
|
oparms->cifs_sb->local_nls,
|
||||||
cifs_remap(oparms->cifs_sb));
|
cifs_remap(oparms->cifs_sb));
|
||||||
return CIFS_open(xid, oparms, oplock, fi);
|
else
|
||||||
|
rc = CIFS_open(xid, oparms, oplock, &fi);
|
||||||
|
|
||||||
|
if (!rc && data)
|
||||||
|
move_cifs_info_to_smb2(&data->fi, &fi);
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1050,7 +1061,7 @@ cifs_make_node(unsigned int xid, struct inode *inode,
|
|||||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||||
struct inode *newinode = NULL;
|
struct inode *newinode = NULL;
|
||||||
int rc = -EPERM;
|
int rc = -EPERM;
|
||||||
FILE_ALL_INFO *buf = NULL;
|
struct cifs_open_info_data buf = {};
|
||||||
struct cifs_io_parms io_parms;
|
struct cifs_io_parms io_parms;
|
||||||
__u32 oplock = 0;
|
__u32 oplock = 0;
|
||||||
struct cifs_fid fid;
|
struct cifs_fid fid;
|
||||||
@ -1082,14 +1093,14 @@ cifs_make_node(unsigned int xid, struct inode *inode,
|
|||||||
cifs_sb->local_nls,
|
cifs_sb->local_nls,
|
||||||
cifs_remap(cifs_sb));
|
cifs_remap(cifs_sb));
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out;
|
return rc;
|
||||||
|
|
||||||
rc = cifs_get_inode_info_unix(&newinode, full_path,
|
rc = cifs_get_inode_info_unix(&newinode, full_path,
|
||||||
inode->i_sb, xid);
|
inode->i_sb, xid);
|
||||||
|
|
||||||
if (rc == 0)
|
if (rc == 0)
|
||||||
d_instantiate(dentry, newinode);
|
d_instantiate(dentry, newinode);
|
||||||
goto out;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1097,19 +1108,13 @@ cifs_make_node(unsigned int xid, struct inode *inode,
|
|||||||
* support block and char device (no socket & fifo)
|
* support block and char device (no socket & fifo)
|
||||||
*/
|
*/
|
||||||
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL))
|
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL))
|
||||||
goto out;
|
return rc;
|
||||||
|
|
||||||
if (!S_ISCHR(mode) && !S_ISBLK(mode))
|
if (!S_ISCHR(mode) && !S_ISBLK(mode))
|
||||||
goto out;
|
return rc;
|
||||||
|
|
||||||
cifs_dbg(FYI, "sfu compat create special file\n");
|
cifs_dbg(FYI, "sfu compat create special file\n");
|
||||||
|
|
||||||
buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
|
|
||||||
if (buf == NULL) {
|
|
||||||
rc = -ENOMEM;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
oparms.tcon = tcon;
|
oparms.tcon = tcon;
|
||||||
oparms.cifs_sb = cifs_sb;
|
oparms.cifs_sb = cifs_sb;
|
||||||
oparms.desired_access = GENERIC_WRITE;
|
oparms.desired_access = GENERIC_WRITE;
|
||||||
@ -1124,21 +1129,21 @@ cifs_make_node(unsigned int xid, struct inode *inode,
|
|||||||
oplock = REQ_OPLOCK;
|
oplock = REQ_OPLOCK;
|
||||||
else
|
else
|
||||||
oplock = 0;
|
oplock = 0;
|
||||||
rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, buf);
|
rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, &buf);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out;
|
return rc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BB Do not bother to decode buf since no local inode yet to put
|
* BB Do not bother to decode buf since no local inode yet to put
|
||||||
* timestamps in, but we can reuse it safely.
|
* timestamps in, but we can reuse it safely.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pdev = (struct win_dev *)buf;
|
pdev = (struct win_dev *)&buf.fi;
|
||||||
io_parms.pid = current->tgid;
|
io_parms.pid = current->tgid;
|
||||||
io_parms.tcon = tcon;
|
io_parms.tcon = tcon;
|
||||||
io_parms.offset = 0;
|
io_parms.offset = 0;
|
||||||
io_parms.length = sizeof(struct win_dev);
|
io_parms.length = sizeof(struct win_dev);
|
||||||
iov[1].iov_base = buf;
|
iov[1].iov_base = &buf.fi;
|
||||||
iov[1].iov_len = sizeof(struct win_dev);
|
iov[1].iov_len = sizeof(struct win_dev);
|
||||||
if (S_ISCHR(mode)) {
|
if (S_ISCHR(mode)) {
|
||||||
memcpy(pdev->type, "IntxCHR", 8);
|
memcpy(pdev->type, "IntxCHR", 8);
|
||||||
@ -1157,8 +1162,8 @@ cifs_make_node(unsigned int xid, struct inode *inode,
|
|||||||
d_drop(dentry);
|
d_drop(dentry);
|
||||||
|
|
||||||
/* FIXME: add code here to set EAs */
|
/* FIXME: add code here to set EAs */
|
||||||
out:
|
|
||||||
kfree(buf);
|
cifs_free_open_info(&buf);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1453,6 +1453,7 @@ SMB2_auth_kerberos(struct SMB2_sess_data *sess_data)
|
|||||||
|
|
||||||
/* keep session key if binding */
|
/* keep session key if binding */
|
||||||
if (!is_binding) {
|
if (!is_binding) {
|
||||||
|
kfree_sensitive(ses->auth_key.response);
|
||||||
ses->auth_key.response = kmemdup(msg->data, msg->sesskey_len,
|
ses->auth_key.response = kmemdup(msg->data, msg->sesskey_len,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!ses->auth_key.response) {
|
if (!ses->auth_key.response) {
|
||||||
@ -1482,8 +1483,11 @@ SMB2_auth_kerberos(struct SMB2_sess_data *sess_data)
|
|||||||
out_put_spnego_key:
|
out_put_spnego_key:
|
||||||
key_invalidate(spnego_key);
|
key_invalidate(spnego_key);
|
||||||
key_put(spnego_key);
|
key_put(spnego_key);
|
||||||
if (rc)
|
if (rc) {
|
||||||
kfree_sensitive(ses->auth_key.response);
|
kfree_sensitive(ses->auth_key.response);
|
||||||
|
ses->auth_key.response = NULL;
|
||||||
|
ses->auth_key.len = 0;
|
||||||
|
}
|
||||||
out:
|
out:
|
||||||
sess_data->result = rc;
|
sess_data->result = rc;
|
||||||
sess_data->func = NULL;
|
sess_data->func = NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user