aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorRonnie Sahlberg <lsahlber@redhat.com>2019-07-15 20:41:46 -0400
committerSteve French <stfrench@microsoft.com>2019-07-15 22:20:09 -0400
commit88a92c913cef09e70b1744a8877d177aa6cb2189 (patch)
tree963990acacc7764fd1d094cba922547489d866b1 /fs/cifs
parentce465bf94b70f03136171a62b607864f00093b19 (diff)
cifs: fix crash in smb2_compound_op()/smb2_set_next_command()
RHBZ: 1722704 In low memory situations the various SMB2_*_init() functions can fail to allocate a request PDU and thus leave the request iovector as NULL. If we don't check the return code for failure we end up calling smb2_set_next_command() with a NULL iovector causing a crash when it tries to dereference it. CC: Stable <stable@vger.kernel.org> Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/smb2inode.c12
-rw-r--r--fs/cifs/smb2ops.c11
2 files changed, 22 insertions, 1 deletions
diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c
index 278405d26c47..d8d9cdfa30b6 100644
--- a/fs/cifs/smb2inode.c
+++ b/fs/cifs/smb2inode.c
@@ -120,6 +120,8 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
120 SMB2_O_INFO_FILE, 0, 120 SMB2_O_INFO_FILE, 0,
121 sizeof(struct smb2_file_all_info) + 121 sizeof(struct smb2_file_all_info) +
122 PATH_MAX * 2, 0, NULL); 122 PATH_MAX * 2, 0, NULL);
123 if (rc)
124 goto finished;
123 smb2_set_next_command(tcon, &rqst[num_rqst]); 125 smb2_set_next_command(tcon, &rqst[num_rqst]);
124 smb2_set_related(&rqst[num_rqst++]); 126 smb2_set_related(&rqst[num_rqst++]);
125 trace_smb3_query_info_compound_enter(xid, ses->Suid, tcon->tid, 127 trace_smb3_query_info_compound_enter(xid, ses->Suid, tcon->tid,
@@ -147,6 +149,8 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
147 COMPOUND_FID, current->tgid, 149 COMPOUND_FID, current->tgid,
148 FILE_DISPOSITION_INFORMATION, 150 FILE_DISPOSITION_INFORMATION,
149 SMB2_O_INFO_FILE, 0, data, size); 151 SMB2_O_INFO_FILE, 0, data, size);
152 if (rc)
153 goto finished;
150 smb2_set_next_command(tcon, &rqst[num_rqst]); 154 smb2_set_next_command(tcon, &rqst[num_rqst]);
151 smb2_set_related(&rqst[num_rqst++]); 155 smb2_set_related(&rqst[num_rqst++]);
152 trace_smb3_rmdir_enter(xid, ses->Suid, tcon->tid, full_path); 156 trace_smb3_rmdir_enter(xid, ses->Suid, tcon->tid, full_path);
@@ -163,6 +167,8 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
163 COMPOUND_FID, current->tgid, 167 COMPOUND_FID, current->tgid,
164 FILE_END_OF_FILE_INFORMATION, 168 FILE_END_OF_FILE_INFORMATION,
165 SMB2_O_INFO_FILE, 0, data, size); 169 SMB2_O_INFO_FILE, 0, data, size);
170 if (rc)
171 goto finished;
166 smb2_set_next_command(tcon, &rqst[num_rqst]); 172 smb2_set_next_command(tcon, &rqst[num_rqst]);
167 smb2_set_related(&rqst[num_rqst++]); 173 smb2_set_related(&rqst[num_rqst++]);
168 trace_smb3_set_eof_enter(xid, ses->Suid, tcon->tid, full_path); 174 trace_smb3_set_eof_enter(xid, ses->Suid, tcon->tid, full_path);
@@ -180,6 +186,8 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
180 COMPOUND_FID, current->tgid, 186 COMPOUND_FID, current->tgid,
181 FILE_BASIC_INFORMATION, 187 FILE_BASIC_INFORMATION,
182 SMB2_O_INFO_FILE, 0, data, size); 188 SMB2_O_INFO_FILE, 0, data, size);
189 if (rc)
190 goto finished;
183 smb2_set_next_command(tcon, &rqst[num_rqst]); 191 smb2_set_next_command(tcon, &rqst[num_rqst]);
184 smb2_set_related(&rqst[num_rqst++]); 192 smb2_set_related(&rqst[num_rqst++]);
185 trace_smb3_set_info_compound_enter(xid, ses->Suid, tcon->tid, 193 trace_smb3_set_info_compound_enter(xid, ses->Suid, tcon->tid,
@@ -206,6 +214,8 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
206 COMPOUND_FID, current->tgid, 214 COMPOUND_FID, current->tgid,
207 FILE_RENAME_INFORMATION, 215 FILE_RENAME_INFORMATION,
208 SMB2_O_INFO_FILE, 0, data, size); 216 SMB2_O_INFO_FILE, 0, data, size);
217 if (rc)
218 goto finished;
209 smb2_set_next_command(tcon, &rqst[num_rqst]); 219 smb2_set_next_command(tcon, &rqst[num_rqst]);
210 smb2_set_related(&rqst[num_rqst++]); 220 smb2_set_related(&rqst[num_rqst++]);
211 trace_smb3_rename_enter(xid, ses->Suid, tcon->tid, full_path); 221 trace_smb3_rename_enter(xid, ses->Suid, tcon->tid, full_path);
@@ -231,6 +241,8 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
231 COMPOUND_FID, current->tgid, 241 COMPOUND_FID, current->tgid,
232 FILE_LINK_INFORMATION, 242 FILE_LINK_INFORMATION,
233 SMB2_O_INFO_FILE, 0, data, size); 243 SMB2_O_INFO_FILE, 0, data, size);
244 if (rc)
245 goto finished;
234 smb2_set_next_command(tcon, &rqst[num_rqst]); 246 smb2_set_next_command(tcon, &rqst[num_rqst]);
235 smb2_set_related(&rqst[num_rqst++]); 247 smb2_set_related(&rqst[num_rqst++]);
236 trace_smb3_hardlink_enter(xid, ses->Suid, tcon->tid, full_path); 248 trace_smb3_hardlink_enter(xid, ses->Suid, tcon->tid, full_path);
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index e704e04891fb..0cdc4e47ca87 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -2027,6 +2027,10 @@ smb2_set_related(struct smb_rqst *rqst)
2027 struct smb2_sync_hdr *shdr; 2027 struct smb2_sync_hdr *shdr;
2028 2028
2029 shdr = (struct smb2_sync_hdr *)(rqst->rq_iov[0].iov_base); 2029 shdr = (struct smb2_sync_hdr *)(rqst->rq_iov[0].iov_base);
2030 if (shdr == NULL) {
2031 cifs_dbg(FYI, "shdr NULL in smb2_set_related\n");
2032 return;
2033 }
2030 shdr->Flags |= SMB2_FLAGS_RELATED_OPERATIONS; 2034 shdr->Flags |= SMB2_FLAGS_RELATED_OPERATIONS;
2031} 2035}
2032 2036
@@ -2041,6 +2045,12 @@ smb2_set_next_command(struct cifs_tcon *tcon, struct smb_rqst *rqst)
2041 unsigned long len = smb_rqst_len(server, rqst); 2045 unsigned long len = smb_rqst_len(server, rqst);
2042 int i, num_padding; 2046 int i, num_padding;
2043 2047
2048 shdr = (struct smb2_sync_hdr *)(rqst->rq_iov[0].iov_base);
2049 if (shdr == NULL) {
2050 cifs_dbg(FYI, "shdr NULL in smb2_set_next_command\n");
2051 return;
2052 }
2053
2044 /* SMB headers in a compound are 8 byte aligned. */ 2054 /* SMB headers in a compound are 8 byte aligned. */
2045 2055
2046 /* No padding needed */ 2056 /* No padding needed */
@@ -2080,7 +2090,6 @@ smb2_set_next_command(struct cifs_tcon *tcon, struct smb_rqst *rqst)
2080 } 2090 }
2081 2091
2082 finished: 2092 finished:
2083 shdr = (struct smb2_sync_hdr *)(rqst->rq_iov[0].iov_base);
2084 shdr->NextCommand = cpu_to_le32(len); 2093 shdr->NextCommand = cpu_to_le32(len);
2085} 2094}
2086 2095