Commit b35ad63e authored by Linus Torvalds's avatar Linus Torvalds

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()
parents 8e768130 a152d05a
...@@ -278,6 +278,7 @@ build_avpair_blob(struct cifs_ses *ses, const struct nls_table *nls_cp) ...@@ -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) ...@@ -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 ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment