Skip to content

Commit b35ad63

Browse files
committed
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()
2 parents 8e76813 + a152d05 commit b35ad63

File tree

7 files changed

+49
-34
lines changed

7 files changed

+49
-34
lines changed

fs/cifs/cifsencrypt.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ build_avpair_blob(struct cifs_ses *ses, const struct nls_table *nls_cp)
278278
* ( for NTLMSSP_AV_NB_DOMAIN_NAME followed by NTLMSSP_AV_EOL ) +
279279
* unicode length of a netbios domain name
280280
*/
281+
kfree_sensitive(ses->auth_key.response);
281282
ses->auth_key.len = size + 2 * dlen;
282283
ses->auth_key.response = kzalloc(ses->auth_key.len, GFP_KERNEL);
283284
if (!ses->auth_key.response) {

fs/cifs/connect.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2606,11 +2606,14 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx)
26062606
INIT_LIST_HEAD(&tcon->pending_opens);
26072607
tcon->status = TID_GOOD;
26082608

2609-
/* schedule query interfaces poll */
26102609
INIT_DELAYED_WORK(&tcon->query_interfaces,
26112610
smb2_query_server_interfaces);
2612-
queue_delayed_work(cifsiod_wq, &tcon->query_interfaces,
2613-
(SMB_INTERFACE_POLL_INTERVAL * HZ));
2611+
if (ses->server->dialect >= SMB30_PROT_ID &&
2612+
(ses->server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)) {
2613+
/* schedule query interfaces poll */
2614+
queue_delayed_work(cifsiod_wq, &tcon->query_interfaces,
2615+
(SMB_INTERFACE_POLL_INTERVAL * HZ));
2616+
}
26142617

26152618
spin_lock(&cifs_tcp_ses_lock);
26162619
list_add(&tcon->tcon_list, &ses->tcon_list);

fs/cifs/dfs_cache.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1299,7 +1299,6 @@ static bool target_share_equal(struct TCP_Server_Info *server, const char *s1, c
12991299
* Resolve share's hostname and check if server address matches. Otherwise just ignore it
13001300
* as we could not have upcall to resolve hostname or failed to convert ip address.
13011301
*/
1302-
match = true;
13031302
extract_unc_hostname(s1, &host, &hostlen);
13041303
scnprintf(unc, sizeof(unc), "\\\\%.*s", (int)hostlen, host);
13051304

fs/cifs/link.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,7 @@ smb3_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
428428
oparms.disposition = FILE_CREATE;
429429
oparms.fid = &fid;
430430
oparms.reconnect = false;
431+
oparms.mode = 0644;
431432

432433
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL,
433434
NULL, NULL);

fs/cifs/sess.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,7 @@ int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
815815
return -EINVAL;
816816
}
817817
if (tilen) {
818+
kfree_sensitive(ses->auth_key.response);
818819
ses->auth_key.response = kmemdup(bcc_ptr + tioffset, tilen,
819820
GFP_KERNEL);
820821
if (!ses->auth_key.response) {
@@ -1428,6 +1429,7 @@ sess_auth_kerberos(struct sess_data *sess_data)
14281429
goto out_put_spnego_key;
14291430
}
14301431

1432+
kfree_sensitive(ses->auth_key.response);
14311433
ses->auth_key.response = kmemdup(msg->data, msg->sesskey_len,
14321434
GFP_KERNEL);
14331435
if (!ses->auth_key.response) {

fs/cifs/smb1ops.c

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -562,17 +562,20 @@ static int cifs_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
562562
if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
563563
rc = SMBQueryInformation(xid, tcon, full_path, &fi, cifs_sb->local_nls,
564564
cifs_remap(cifs_sb));
565-
if (!rc)
566-
move_cifs_info_to_smb2(&data->fi, &fi);
567565
*adjustTZ = true;
568566
}
569567

570-
if (!rc && (le32_to_cpu(fi.Attributes) & ATTR_REPARSE)) {
568+
if (!rc) {
571569
int tmprc;
572570
int oplock = 0;
573571
struct cifs_fid fid;
574572
struct cifs_open_parms oparms;
575573

574+
move_cifs_info_to_smb2(&data->fi, &fi);
575+
576+
if (!(le32_to_cpu(fi.Attributes) & ATTR_REPARSE))
577+
return 0;
578+
576579
oparms.tcon = tcon;
577580
oparms.cifs_sb = cifs_sb;
578581
oparms.desired_access = FILE_READ_ATTRIBUTES;
@@ -716,17 +719,25 @@ cifs_mkdir_setinfo(struct inode *inode, const char *full_path,
716719
static int cifs_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32 *oplock,
717720
void *buf)
718721
{
719-
FILE_ALL_INFO *fi = buf;
722+
struct cifs_open_info_data *data = buf;
723+
FILE_ALL_INFO fi = {};
724+
int rc;
720725

721726
if (!(oparms->tcon->ses->capabilities & CAP_NT_SMBS))
722-
return SMBLegacyOpen(xid, oparms->tcon, oparms->path,
723-
oparms->disposition,
724-
oparms->desired_access,
725-
oparms->create_options,
726-
&oparms->fid->netfid, oplock, fi,
727-
oparms->cifs_sb->local_nls,
728-
cifs_remap(oparms->cifs_sb));
729-
return CIFS_open(xid, oparms, oplock, fi);
727+
rc = SMBLegacyOpen(xid, oparms->tcon, oparms->path,
728+
oparms->disposition,
729+
oparms->desired_access,
730+
oparms->create_options,
731+
&oparms->fid->netfid, oplock, &fi,
732+
oparms->cifs_sb->local_nls,
733+
cifs_remap(oparms->cifs_sb));
734+
else
735+
rc = CIFS_open(xid, oparms, oplock, &fi);
736+
737+
if (!rc && data)
738+
move_cifs_info_to_smb2(&data->fi, &fi);
739+
740+
return rc;
730741
}
731742

732743
static void
@@ -1050,7 +1061,7 @@ cifs_make_node(unsigned int xid, struct inode *inode,
10501061
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
10511062
struct inode *newinode = NULL;
10521063
int rc = -EPERM;
1053-
FILE_ALL_INFO *buf = NULL;
1064+
struct cifs_open_info_data buf = {};
10541065
struct cifs_io_parms io_parms;
10551066
__u32 oplock = 0;
10561067
struct cifs_fid fid;
@@ -1082,34 +1093,28 @@ cifs_make_node(unsigned int xid, struct inode *inode,
10821093
cifs_sb->local_nls,
10831094
cifs_remap(cifs_sb));
10841095
if (rc)
1085-
goto out;
1096+
return rc;
10861097

10871098
rc = cifs_get_inode_info_unix(&newinode, full_path,
10881099
inode->i_sb, xid);
10891100

10901101
if (rc == 0)
10911102
d_instantiate(dentry, newinode);
1092-
goto out;
1103+
return rc;
10931104
}
10941105

10951106
/*
10961107
* SMB1 SFU emulation: should work with all servers, but only
10971108
* support block and char device (no socket & fifo)
10981109
*/
10991110
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL))
1100-
goto out;
1111+
return rc;
11011112

11021113
if (!S_ISCHR(mode) && !S_ISBLK(mode))
1103-
goto out;
1114+
return rc;
11041115

11051116
cifs_dbg(FYI, "sfu compat create special file\n");
11061117

1107-
buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
1108-
if (buf == NULL) {
1109-
rc = -ENOMEM;
1110-
goto out;
1111-
}
1112-
11131118
oparms.tcon = tcon;
11141119
oparms.cifs_sb = cifs_sb;
11151120
oparms.desired_access = GENERIC_WRITE;
@@ -1124,21 +1129,21 @@ cifs_make_node(unsigned int xid, struct inode *inode,
11241129
oplock = REQ_OPLOCK;
11251130
else
11261131
oplock = 0;
1127-
rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, buf);
1132+
rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, &buf);
11281133
if (rc)
1129-
goto out;
1134+
return rc;
11301135

11311136
/*
11321137
* BB Do not bother to decode buf since no local inode yet to put
11331138
* timestamps in, but we can reuse it safely.
11341139
*/
11351140

1136-
pdev = (struct win_dev *)buf;
1141+
pdev = (struct win_dev *)&buf.fi;
11371142
io_parms.pid = current->tgid;
11381143
io_parms.tcon = tcon;
11391144
io_parms.offset = 0;
11401145
io_parms.length = sizeof(struct win_dev);
1141-
iov[1].iov_base = buf;
1146+
iov[1].iov_base = &buf.fi;
11421147
iov[1].iov_len = sizeof(struct win_dev);
11431148
if (S_ISCHR(mode)) {
11441149
memcpy(pdev->type, "IntxCHR", 8);
@@ -1157,8 +1162,8 @@ cifs_make_node(unsigned int xid, struct inode *inode,
11571162
d_drop(dentry);
11581163

11591164
/* FIXME: add code here to set EAs */
1160-
out:
1161-
kfree(buf);
1165+
1166+
cifs_free_open_info(&buf);
11621167
return rc;
11631168
}
11641169

fs/cifs/smb2pdu.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1453,6 +1453,7 @@ SMB2_auth_kerberos(struct SMB2_sess_data *sess_data)
14531453

14541454
/* keep session key if binding */
14551455
if (!is_binding) {
1456+
kfree_sensitive(ses->auth_key.response);
14561457
ses->auth_key.response = kmemdup(msg->data, msg->sesskey_len,
14571458
GFP_KERNEL);
14581459
if (!ses->auth_key.response) {
@@ -1482,8 +1483,11 @@ SMB2_auth_kerberos(struct SMB2_sess_data *sess_data)
14821483
out_put_spnego_key:
14831484
key_invalidate(spnego_key);
14841485
key_put(spnego_key);
1485-
if (rc)
1486+
if (rc) {
14861487
kfree_sensitive(ses->auth_key.response);
1488+
ses->auth_key.response = NULL;
1489+
ses->auth_key.len = 0;
1490+
}
14871491
out:
14881492
sess_data->result = rc;
14891493
sess_data->func = NULL;

0 commit comments

Comments
 (0)