aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorSteve French <smfrench@gmail.com>2015-09-28 18:21:07 -0400
committerSteve French <smfrench@gmail.com>2015-10-01 23:48:37 -0400
commit646200a041203f440fb6fcf9cacd9efeda9de74c (patch)
tree80389379b139d60e1acdd554f85e9706e0b90257 /fs/cifs
parentff9f84b7d79ddccab4c293c9d3e289f95ae594f7 (diff)
[SMB3] Do not fall back to SMBWriteX in set_file_size error cases
The error paths in set_file_size for cifs and smb3 are incorrect. In the unlikely event that a server did not support set file info of the file size, the code incorrectly falls back to trying SMBWriteX (note that only the original core SMB Write, used for example by DOS, can set the file size this way - this actually does not work for the more recent SMBWriteX). The idea was since the old DOS SMB Write could set the file size if you write zero bytes at that offset then use that if server rejects the normal set file info call. Fortunately the SMBWriteX will never be sent on the wire (except when file size is zero) since the length and offset fields were reversed in the two places in this function that call SMBWriteX causing the fall back path to return an error. It is also important to never call an SMB request from an SMB2/sMB3 session (which theoretically would be possible, and can cause a brief session drop, although the client recovers) so this should be fixed. In practice this path does not happen with modern servers but the error fall back to SMBWriteX is clearly wrong. Removing the calls to SMBWriteX in the error paths in cifs_set_file_size Pointed out by PaX/grsecurity team Signed-off-by: Steve French <steve.french@primarydata.com> Reported-by: PaX Team <pageexec@freemail.hu> CC: Emese Revfy <re.emese@gmail.com> CC: Brad Spengler <spender@grsecurity.net> CC: Stable <stable@vger.kernel.org>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/inode.c34
1 files changed, 0 insertions, 34 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index f621b44cb800..6b66dd5d1540 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -2034,7 +2034,6 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
2034 struct tcon_link *tlink = NULL; 2034 struct tcon_link *tlink = NULL;
2035 struct cifs_tcon *tcon = NULL; 2035 struct cifs_tcon *tcon = NULL;
2036 struct TCP_Server_Info *server; 2036 struct TCP_Server_Info *server;
2037 struct cifs_io_parms io_parms;
2038 2037
2039 /* 2038 /*
2040 * To avoid spurious oplock breaks from server, in the case of 2039 * To avoid spurious oplock breaks from server, in the case of
@@ -2056,18 +2055,6 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
2056 rc = -ENOSYS; 2055 rc = -ENOSYS;
2057 cifsFileInfo_put(open_file); 2056 cifsFileInfo_put(open_file);
2058 cifs_dbg(FYI, "SetFSize for attrs rc = %d\n", rc); 2057 cifs_dbg(FYI, "SetFSize for attrs rc = %d\n", rc);
2059 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
2060 unsigned int bytes_written;
2061
2062 io_parms.netfid = open_file->fid.netfid;
2063 io_parms.pid = open_file->pid;
2064 io_parms.tcon = tcon;
2065 io_parms.offset = 0;
2066 io_parms.length = attrs->ia_size;
2067 rc = CIFSSMBWrite(xid, &io_parms, &bytes_written,
2068 NULL, NULL, 1);
2069 cifs_dbg(FYI, "Wrt seteof rc %d\n", rc);
2070 }
2071 } else 2058 } else
2072 rc = -EINVAL; 2059 rc = -EINVAL;
2073 2060
@@ -2093,28 +2080,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
2093 else 2080 else
2094 rc = -ENOSYS; 2081 rc = -ENOSYS;
2095 cifs_dbg(FYI, "SetEOF by path (setattrs) rc = %d\n", rc); 2082 cifs_dbg(FYI, "SetEOF by path (setattrs) rc = %d\n", rc);
2096 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
2097 __u16 netfid;
2098 int oplock = 0;
2099 2083
2100 rc = SMBLegacyOpen(xid, tcon, full_path, FILE_OPEN,
2101 GENERIC_WRITE, CREATE_NOT_DIR, &netfid,
2102 &oplock, NULL, cifs_sb->local_nls,
2103 cifs_remap(cifs_sb));
2104 if (rc == 0) {
2105 unsigned int bytes_written;
2106
2107 io_parms.netfid = netfid;
2108 io_parms.pid = current->tgid;
2109 io_parms.tcon = tcon;
2110 io_parms.offset = 0;
2111 io_parms.length = attrs->ia_size;
2112 rc = CIFSSMBWrite(xid, &io_parms, &bytes_written, NULL,
2113 NULL, 1);
2114 cifs_dbg(FYI, "wrt seteof rc %d\n", rc);
2115 CIFSSMBClose(xid, tcon, netfid);
2116 }
2117 }
2118 if (tlink) 2084 if (tlink)
2119 cifs_put_tlink(tlink); 2085 cifs_put_tlink(tlink);
2120 2086