Skip to content

Commit ba5d4c1

Browse files
Paulo Alcantarasmfrench
authored andcommitted
cifs: fix file info setting in cifs_open_file()
In cifs_open_file(), @buf must hold a pointer to a cifs_open_info_data structure which is passed by cifs_nt_open(), so assigning @buf directly to @fi was obviously wrong. Fix this by passing a valid FILE_ALL_INFO structure to SMBLegacyOpen() and CIFS_open(), and then copy the set structure to the corresponding cifs_open_info_data::fi field with move_cifs_info_to_smb2() helper. Link: https://bugzilla.kernel.org/show_bug.cgi?id=216889 Fixes: 76894f3 ("cifs: improve symlink handling for smb2+") Signed-off-by: Paulo Alcantara (SUSE) <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 29cf282 commit ba5d4c1

File tree

1 file changed

+28
-26
lines changed

1 file changed

+28
-26
lines changed

fs/cifs/smb1ops.c

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -719,17 +719,25 @@ cifs_mkdir_setinfo(struct inode *inode, const char *full_path,
719719
static int cifs_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32 *oplock,
720720
void *buf)
721721
{
722-
FILE_ALL_INFO *fi = buf;
722+
struct cifs_open_info_data *data = buf;
723+
FILE_ALL_INFO fi = {};
724+
int rc;
723725

724726
if (!(oparms->tcon->ses->capabilities & CAP_NT_SMBS))
725-
return SMBLegacyOpen(xid, oparms->tcon, oparms->path,
726-
oparms->disposition,
727-
oparms->desired_access,
728-
oparms->create_options,
729-
&oparms->fid->netfid, oplock, fi,
730-
oparms->cifs_sb->local_nls,
731-
cifs_remap(oparms->cifs_sb));
732-
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;
733741
}
734742

735743
static void
@@ -1053,7 +1061,7 @@ cifs_make_node(unsigned int xid, struct inode *inode,
10531061
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
10541062
struct inode *newinode = NULL;
10551063
int rc = -EPERM;
1056-
FILE_ALL_INFO *buf = NULL;
1064+
struct cifs_open_info_data buf = {};
10571065
struct cifs_io_parms io_parms;
10581066
__u32 oplock = 0;
10591067
struct cifs_fid fid;
@@ -1085,34 +1093,28 @@ cifs_make_node(unsigned int xid, struct inode *inode,
10851093
cifs_sb->local_nls,
10861094
cifs_remap(cifs_sb));
10871095
if (rc)
1088-
goto out;
1096+
return rc;
10891097

10901098
rc = cifs_get_inode_info_unix(&newinode, full_path,
10911099
inode->i_sb, xid);
10921100

10931101
if (rc == 0)
10941102
d_instantiate(dentry, newinode);
1095-
goto out;
1103+
return rc;
10961104
}
10971105

10981106
/*
10991107
* SMB1 SFU emulation: should work with all servers, but only
11001108
* support block and char device (no socket & fifo)
11011109
*/
11021110
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL))
1103-
goto out;
1111+
return rc;
11041112

11051113
if (!S_ISCHR(mode) && !S_ISBLK(mode))
1106-
goto out;
1114+
return rc;
11071115

11081116
cifs_dbg(FYI, "sfu compat create special file\n");
11091117

1110-
buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
1111-
if (buf == NULL) {
1112-
rc = -ENOMEM;
1113-
goto out;
1114-
}
1115-
11161118
oparms.tcon = tcon;
11171119
oparms.cifs_sb = cifs_sb;
11181120
oparms.desired_access = GENERIC_WRITE;
@@ -1127,21 +1129,21 @@ cifs_make_node(unsigned int xid, struct inode *inode,
11271129
oplock = REQ_OPLOCK;
11281130
else
11291131
oplock = 0;
1130-
rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, buf);
1132+
rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, &buf);
11311133
if (rc)
1132-
goto out;
1134+
return rc;
11331135

11341136
/*
11351137
* BB Do not bother to decode buf since no local inode yet to put
11361138
* timestamps in, but we can reuse it safely.
11371139
*/
11381140

1139-
pdev = (struct win_dev *)buf;
1141+
pdev = (struct win_dev *)&buf.fi;
11401142
io_parms.pid = current->tgid;
11411143
io_parms.tcon = tcon;
11421144
io_parms.offset = 0;
11431145
io_parms.length = sizeof(struct win_dev);
1144-
iov[1].iov_base = buf;
1146+
iov[1].iov_base = &buf.fi;
11451147
iov[1].iov_len = sizeof(struct win_dev);
11461148
if (S_ISCHR(mode)) {
11471149
memcpy(pdev->type, "IntxCHR", 8);
@@ -1160,8 +1162,8 @@ cifs_make_node(unsigned int xid, struct inode *inode,
11601162
d_drop(dentry);
11611163

11621164
/* FIXME: add code here to set EAs */
1163-
out:
1164-
kfree(buf);
1165+
1166+
cifs_free_open_info(&buf);
11651167
return rc;
11661168
}
11671169

0 commit comments

Comments
 (0)