smb2misc.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  1. /*
  2. * fs/cifs/smb2misc.c
  3. *
  4. * Copyright (C) International Business Machines Corp., 2002,2011
  5. * Etersoft, 2012
  6. * Author(s): Steve French (sfrench@us.ibm.com)
  7. * Pavel Shilovsky (pshilovsky@samba.org) 2012
  8. *
  9. * This library is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU Lesser General Public License as published
  11. * by the Free Software Foundation; either version 2.1 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
  17. * the GNU Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public License
  20. * along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22. */
  23. #include <linux/ctype.h>
  24. #include "smb2pdu.h"
  25. #include "cifsglob.h"
  26. #include "cifsproto.h"
  27. #include "smb2proto.h"
  28. #include "cifs_debug.h"
  29. #include "cifs_unicode.h"
  30. #include "smb2status.h"
  31. static int
  32. check_smb2_hdr(struct smb2_hdr *hdr, __u64 mid)
  33. {
  34. __u64 wire_mid = le64_to_cpu(hdr->MessageId);
  35. /*
  36. * Make sure that this really is an SMB, that it is a response,
  37. * and that the message ids match.
  38. */
  39. if ((hdr->ProtocolId == SMB2_PROTO_NUMBER) &&
  40. (mid == wire_mid)) {
  41. if (hdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR)
  42. return 0;
  43. else {
  44. /* only one valid case where server sends us request */
  45. if (hdr->Command == SMB2_OPLOCK_BREAK)
  46. return 0;
  47. else
  48. cifs_dbg(VFS, "Received Request not response\n");
  49. }
  50. } else { /* bad signature or mid */
  51. if (hdr->ProtocolId != SMB2_PROTO_NUMBER)
  52. cifs_dbg(VFS, "Bad protocol string signature header %x\n",
  53. le32_to_cpu(hdr->ProtocolId));
  54. if (mid != wire_mid)
  55. cifs_dbg(VFS, "Mids do not match: %llu and %llu\n",
  56. mid, wire_mid);
  57. }
  58. cifs_dbg(VFS, "Bad SMB detected. The Mid=%llu\n", wire_mid);
  59. return 1;
  60. }
  61. /*
  62. * The following table defines the expected "StructureSize" of SMB2 responses
  63. * in order by SMB2 command. This is similar to "wct" in SMB/CIFS responses.
  64. *
  65. * Note that commands are defined in smb2pdu.h in le16 but the array below is
  66. * indexed by command in host byte order
  67. */
  68. static const __le16 smb2_rsp_struct_sizes[NUMBER_OF_SMB2_COMMANDS] = {
  69. /* SMB2_NEGOTIATE */ cpu_to_le16(65),
  70. /* SMB2_SESSION_SETUP */ cpu_to_le16(9),
  71. /* SMB2_LOGOFF */ cpu_to_le16(4),
  72. /* SMB2_TREE_CONNECT */ cpu_to_le16(16),
  73. /* SMB2_TREE_DISCONNECT */ cpu_to_le16(4),
  74. /* SMB2_CREATE */ cpu_to_le16(89),
  75. /* SMB2_CLOSE */ cpu_to_le16(60),
  76. /* SMB2_FLUSH */ cpu_to_le16(4),
  77. /* SMB2_READ */ cpu_to_le16(17),
  78. /* SMB2_WRITE */ cpu_to_le16(17),
  79. /* SMB2_LOCK */ cpu_to_le16(4),
  80. /* SMB2_IOCTL */ cpu_to_le16(49),
  81. /* BB CHECK this ... not listed in documentation */
  82. /* SMB2_CANCEL */ cpu_to_le16(0),
  83. /* SMB2_ECHO */ cpu_to_le16(4),
  84. /* SMB2_QUERY_DIRECTORY */ cpu_to_le16(9),
  85. /* SMB2_CHANGE_NOTIFY */ cpu_to_le16(9),
  86. /* SMB2_QUERY_INFO */ cpu_to_le16(9),
  87. /* SMB2_SET_INFO */ cpu_to_le16(2),
  88. /* BB FIXME can also be 44 for lease break */
  89. /* SMB2_OPLOCK_BREAK */ cpu_to_le16(24)
  90. };
  91. int
  92. smb2_check_message(char *buf, unsigned int length, struct TCP_Server_Info *srvr)
  93. {
  94. struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
  95. struct smb2_pdu *pdu = (struct smb2_pdu *)hdr;
  96. __u64 mid;
  97. __u32 len = get_rfc1002_length(buf);
  98. __u32 clc_len; /* calculated length */
  99. int command;
  100. /* BB disable following printk later */
  101. cifs_dbg(FYI, "%s length: 0x%x, smb_buf_length: 0x%x\n",
  102. __func__, length, len);
  103. /*
  104. * Add function to do table lookup of StructureSize by command
  105. * ie Validate the wct via smb2_struct_sizes table above
  106. */
  107. if (hdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) {
  108. struct smb2_transform_hdr *thdr =
  109. (struct smb2_transform_hdr *)buf;
  110. struct cifs_ses *ses = NULL;
  111. struct list_head *tmp;
  112. /* decrypt frame now that it is completely read in */
  113. spin_lock(&cifs_tcp_ses_lock);
  114. list_for_each(tmp, &srvr->smb_ses_list) {
  115. ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
  116. if (ses->Suid == thdr->SessionId)
  117. break;
  118. ses = NULL;
  119. }
  120. spin_unlock(&cifs_tcp_ses_lock);
  121. if (ses == NULL) {
  122. cifs_dbg(VFS, "no decryption - session id not found\n");
  123. return 1;
  124. }
  125. }
  126. mid = le64_to_cpu(hdr->MessageId);
  127. if (length < sizeof(struct smb2_pdu)) {
  128. if ((length >= sizeof(struct smb2_hdr)) && (hdr->Status != 0)) {
  129. pdu->StructureSize2 = 0;
  130. /*
  131. * As with SMB/CIFS, on some error cases servers may
  132. * not return wct properly
  133. */
  134. return 0;
  135. } else {
  136. cifs_dbg(VFS, "Length less than SMB header size\n");
  137. }
  138. return 1;
  139. }
  140. if (len > CIFSMaxBufSize + MAX_SMB2_HDR_SIZE - 4) {
  141. cifs_dbg(VFS, "SMB length greater than maximum, mid=%llu\n",
  142. mid);
  143. return 1;
  144. }
  145. if (check_smb2_hdr(hdr, mid))
  146. return 1;
  147. if (hdr->StructureSize != SMB2_HEADER_STRUCTURE_SIZE) {
  148. cifs_dbg(VFS, "Illegal structure size %u\n",
  149. le16_to_cpu(hdr->StructureSize));
  150. return 1;
  151. }
  152. command = le16_to_cpu(hdr->Command);
  153. if (command >= NUMBER_OF_SMB2_COMMANDS) {
  154. cifs_dbg(VFS, "Illegal SMB2 command %d\n", command);
  155. return 1;
  156. }
  157. if (smb2_rsp_struct_sizes[command] != pdu->StructureSize2) {
  158. if (command != SMB2_OPLOCK_BREAK_HE && (hdr->Status == 0 ||
  159. pdu->StructureSize2 != SMB2_ERROR_STRUCTURE_SIZE2)) {
  160. /* error packets have 9 byte structure size */
  161. cifs_dbg(VFS, "Illegal response size %u for command %d\n",
  162. le16_to_cpu(pdu->StructureSize2), command);
  163. return 1;
  164. } else if (command == SMB2_OPLOCK_BREAK_HE && (hdr->Status == 0)
  165. && (le16_to_cpu(pdu->StructureSize2) != 44)
  166. && (le16_to_cpu(pdu->StructureSize2) != 36)) {
  167. /* special case for SMB2.1 lease break message */
  168. cifs_dbg(VFS, "Illegal response size %d for oplock break\n",
  169. le16_to_cpu(pdu->StructureSize2));
  170. return 1;
  171. }
  172. }
  173. if (4 + len != length) {
  174. cifs_dbg(VFS, "Total length %u RFC1002 length %u mismatch mid %llu\n",
  175. length, 4 + len, mid);
  176. return 1;
  177. }
  178. clc_len = smb2_calc_size(hdr);
  179. if (4 + len != clc_len) {
  180. cifs_dbg(FYI, "Calculated size %u length %u mismatch mid %llu\n",
  181. clc_len, 4 + len, mid);
  182. /* create failed on symlink */
  183. if (command == SMB2_CREATE_HE &&
  184. hdr->Status == STATUS_STOPPED_ON_SYMLINK)
  185. return 0;
  186. /* Windows 7 server returns 24 bytes more */
  187. if (clc_len + 20 == len && command == SMB2_OPLOCK_BREAK_HE)
  188. return 0;
  189. /* server can return one byte more due to implied bcc[0] */
  190. if (clc_len == 4 + len + 1)
  191. return 0;
  192. /*
  193. * MacOS server pads after SMB2.1 write response with 3 bytes
  194. * of junk. Other servers match RFC1001 len to actual
  195. * SMB2/SMB3 frame length (header + smb2 response specific data)
  196. * Log the server error (once), but allow it and continue
  197. * since the frame is parseable.
  198. */
  199. if (clc_len < 4 /* RFC1001 header size */ + len) {
  200. printk_once(KERN_WARNING
  201. "SMB2 server sent bad RFC1001 len %d not %d\n",
  202. len, clc_len - 4);
  203. return 0;
  204. }
  205. return 1;
  206. }
  207. return 0;
  208. }
  209. /*
  210. * The size of the variable area depends on the offset and length fields
  211. * located in different fields for various SMB2 responses. SMB2 responses
  212. * with no variable length info, show an offset of zero for the offset field.
  213. */
  214. static const bool has_smb2_data_area[NUMBER_OF_SMB2_COMMANDS] = {
  215. /* SMB2_NEGOTIATE */ true,
  216. /* SMB2_SESSION_SETUP */ true,
  217. /* SMB2_LOGOFF */ false,
  218. /* SMB2_TREE_CONNECT */ false,
  219. /* SMB2_TREE_DISCONNECT */ false,
  220. /* SMB2_CREATE */ true,
  221. /* SMB2_CLOSE */ false,
  222. /* SMB2_FLUSH */ false,
  223. /* SMB2_READ */ true,
  224. /* SMB2_WRITE */ false,
  225. /* SMB2_LOCK */ false,
  226. /* SMB2_IOCTL */ true,
  227. /* SMB2_CANCEL */ false, /* BB CHECK this not listed in documentation */
  228. /* SMB2_ECHO */ false,
  229. /* SMB2_QUERY_DIRECTORY */ true,
  230. /* SMB2_CHANGE_NOTIFY */ true,
  231. /* SMB2_QUERY_INFO */ true,
  232. /* SMB2_SET_INFO */ false,
  233. /* SMB2_OPLOCK_BREAK */ false
  234. };
  235. /*
  236. * Returns the pointer to the beginning of the data area. Length of the data
  237. * area and the offset to it (from the beginning of the smb are also returned.
  238. */
  239. char *
  240. smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr)
  241. {
  242. *off = 0;
  243. *len = 0;
  244. /* error responses do not have data area */
  245. if (hdr->Status && hdr->Status != STATUS_MORE_PROCESSING_REQUIRED &&
  246. (((struct smb2_err_rsp *)hdr)->StructureSize) ==
  247. SMB2_ERROR_STRUCTURE_SIZE2)
  248. return NULL;
  249. /*
  250. * Following commands have data areas so we have to get the location
  251. * of the data buffer offset and data buffer length for the particular
  252. * command.
  253. */
  254. switch (hdr->Command) {
  255. case SMB2_NEGOTIATE:
  256. *off = le16_to_cpu(
  257. ((struct smb2_negotiate_rsp *)hdr)->SecurityBufferOffset);
  258. *len = le16_to_cpu(
  259. ((struct smb2_negotiate_rsp *)hdr)->SecurityBufferLength);
  260. break;
  261. case SMB2_SESSION_SETUP:
  262. *off = le16_to_cpu(
  263. ((struct smb2_sess_setup_rsp *)hdr)->SecurityBufferOffset);
  264. *len = le16_to_cpu(
  265. ((struct smb2_sess_setup_rsp *)hdr)->SecurityBufferLength);
  266. break;
  267. case SMB2_CREATE:
  268. *off = le32_to_cpu(
  269. ((struct smb2_create_rsp *)hdr)->CreateContextsOffset);
  270. *len = le32_to_cpu(
  271. ((struct smb2_create_rsp *)hdr)->CreateContextsLength);
  272. break;
  273. case SMB2_QUERY_INFO:
  274. *off = le16_to_cpu(
  275. ((struct smb2_query_info_rsp *)hdr)->OutputBufferOffset);
  276. *len = le32_to_cpu(
  277. ((struct smb2_query_info_rsp *)hdr)->OutputBufferLength);
  278. break;
  279. case SMB2_READ:
  280. *off = ((struct smb2_read_rsp *)hdr)->DataOffset;
  281. *len = le32_to_cpu(((struct smb2_read_rsp *)hdr)->DataLength);
  282. break;
  283. case SMB2_QUERY_DIRECTORY:
  284. *off = le16_to_cpu(
  285. ((struct smb2_query_directory_rsp *)hdr)->OutputBufferOffset);
  286. *len = le32_to_cpu(
  287. ((struct smb2_query_directory_rsp *)hdr)->OutputBufferLength);
  288. break;
  289. case SMB2_IOCTL:
  290. *off = le32_to_cpu(
  291. ((struct smb2_ioctl_rsp *)hdr)->OutputOffset);
  292. *len = le32_to_cpu(((struct smb2_ioctl_rsp *)hdr)->OutputCount);
  293. break;
  294. case SMB2_CHANGE_NOTIFY:
  295. default:
  296. /* BB FIXME for unimplemented cases above */
  297. cifs_dbg(VFS, "no length check for command\n");
  298. break;
  299. }
  300. /*
  301. * Invalid length or offset probably means data area is invalid, but
  302. * we have little choice but to ignore the data area in this case.
  303. */
  304. if (*off > 4096) {
  305. cifs_dbg(VFS, "offset %d too large, data area ignored\n", *off);
  306. *len = 0;
  307. *off = 0;
  308. } else if (*off < 0) {
  309. cifs_dbg(VFS, "negative offset %d to data invalid ignore data area\n",
  310. *off);
  311. *off = 0;
  312. *len = 0;
  313. } else if (*len < 0) {
  314. cifs_dbg(VFS, "negative data length %d invalid, data area ignored\n",
  315. *len);
  316. *len = 0;
  317. } else if (*len > 128 * 1024) {
  318. cifs_dbg(VFS, "data area larger than 128K: %d\n", *len);
  319. *len = 0;
  320. }
  321. /* return pointer to beginning of data area, ie offset from SMB start */
  322. if ((*off != 0) && (*len != 0))
  323. return (char *)(&hdr->ProtocolId) + *off;
  324. else
  325. return NULL;
  326. }
  327. /*
  328. * Calculate the size of the SMB message based on the fixed header
  329. * portion, the number of word parameters and the data portion of the message.
  330. */
  331. unsigned int
  332. smb2_calc_size(void *buf)
  333. {
  334. struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
  335. struct smb2_pdu *pdu = (struct smb2_pdu *)hdr;
  336. int offset; /* the offset from the beginning of SMB to data area */
  337. int data_length; /* the length of the variable length data area */
  338. /* Structure Size has already been checked to make sure it is 64 */
  339. int len = 4 + le16_to_cpu(pdu->hdr.StructureSize);
  340. /*
  341. * StructureSize2, ie length of fixed parameter area has already
  342. * been checked to make sure it is the correct length.
  343. */
  344. len += le16_to_cpu(pdu->StructureSize2);
  345. if (has_smb2_data_area[le16_to_cpu(hdr->Command)] == false)
  346. goto calc_size_exit;
  347. smb2_get_data_area_len(&offset, &data_length, hdr);
  348. cifs_dbg(FYI, "SMB2 data length %d offset %d\n", data_length, offset);
  349. if (data_length > 0) {
  350. /*
  351. * Check to make sure that data area begins after fixed area,
  352. * Note that last byte of the fixed area is part of data area
  353. * for some commands, typically those with odd StructureSize,
  354. * so we must add one to the calculation (and 4 to account for
  355. * the size of the RFC1001 hdr.
  356. */
  357. if (offset + 4 + 1 < len) {
  358. cifs_dbg(VFS, "data area offset %d overlaps SMB2 header %d\n",
  359. offset + 4 + 1, len);
  360. data_length = 0;
  361. } else {
  362. len = 4 + offset + data_length;
  363. }
  364. }
  365. calc_size_exit:
  366. cifs_dbg(FYI, "SMB2 len %d\n", len);
  367. return len;
  368. }
  369. /* Note: caller must free return buffer */
  370. __le16 *
  371. cifs_convert_path_to_utf16(const char *from, struct cifs_sb_info *cifs_sb)
  372. {
  373. int len;
  374. const char *start_of_path;
  375. __le16 *to;
  376. int map_type;
  377. if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SFM_CHR)
  378. map_type = SFM_MAP_UNI_RSVD;
  379. else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
  380. map_type = SFU_MAP_UNI_RSVD;
  381. else
  382. map_type = NO_MAP_UNI_RSVD;
  383. /* Windows doesn't allow paths beginning with \ */
  384. if (from[0] == '\\')
  385. start_of_path = from + 1;
  386. else
  387. start_of_path = from;
  388. to = cifs_strndup_to_utf16(start_of_path, PATH_MAX, &len,
  389. cifs_sb->local_nls, map_type);
  390. return to;
  391. }
  392. __le32
  393. smb2_get_lease_state(struct cifsInodeInfo *cinode)
  394. {
  395. __le32 lease = 0;
  396. if (CIFS_CACHE_WRITE(cinode))
  397. lease |= SMB2_LEASE_WRITE_CACHING;
  398. if (CIFS_CACHE_HANDLE(cinode))
  399. lease |= SMB2_LEASE_HANDLE_CACHING;
  400. if (CIFS_CACHE_READ(cinode))
  401. lease |= SMB2_LEASE_READ_CACHING;
  402. return lease;
  403. }
  404. struct smb2_lease_break_work {
  405. struct work_struct lease_break;
  406. struct tcon_link *tlink;
  407. __u8 lease_key[16];
  408. __le32 lease_state;
  409. };
  410. static void
  411. cifs_ses_oplock_break(struct work_struct *work)
  412. {
  413. struct smb2_lease_break_work *lw = container_of(work,
  414. struct smb2_lease_break_work, lease_break);
  415. int rc;
  416. rc = SMB2_lease_break(0, tlink_tcon(lw->tlink), lw->lease_key,
  417. lw->lease_state);
  418. cifs_dbg(FYI, "Lease release rc %d\n", rc);
  419. cifs_put_tlink(lw->tlink);
  420. kfree(lw);
  421. }
  422. static bool
  423. smb2_tcon_has_lease(struct cifs_tcon *tcon, struct smb2_lease_break *rsp,
  424. struct smb2_lease_break_work *lw)
  425. {
  426. bool found;
  427. __u8 lease_state;
  428. struct list_head *tmp;
  429. struct cifsFileInfo *cfile;
  430. struct TCP_Server_Info *server = tcon->ses->server;
  431. struct cifs_pending_open *open;
  432. struct cifsInodeInfo *cinode;
  433. int ack_req = le32_to_cpu(rsp->Flags &
  434. SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED);
  435. lease_state = le32_to_cpu(rsp->NewLeaseState);
  436. list_for_each(tmp, &tcon->openFileList) {
  437. cfile = list_entry(tmp, struct cifsFileInfo, tlist);
  438. cinode = CIFS_I(d_inode(cfile->dentry));
  439. if (memcmp(cinode->lease_key, rsp->LeaseKey,
  440. SMB2_LEASE_KEY_SIZE))
  441. continue;
  442. cifs_dbg(FYI, "found in the open list\n");
  443. cifs_dbg(FYI, "lease key match, lease break 0x%x\n",
  444. le32_to_cpu(rsp->NewLeaseState));
  445. server->ops->set_oplock_level(cinode, lease_state, 0, NULL);
  446. if (ack_req)
  447. cfile->oplock_break_cancelled = false;
  448. else
  449. cfile->oplock_break_cancelled = true;
  450. queue_work(cifsoplockd_wq, &cfile->oplock_break);
  451. kfree(lw);
  452. return true;
  453. }
  454. found = false;
  455. list_for_each_entry(open, &tcon->pending_opens, olist) {
  456. if (memcmp(open->lease_key, rsp->LeaseKey,
  457. SMB2_LEASE_KEY_SIZE))
  458. continue;
  459. if (!found && ack_req) {
  460. found = true;
  461. memcpy(lw->lease_key, open->lease_key,
  462. SMB2_LEASE_KEY_SIZE);
  463. lw->tlink = cifs_get_tlink(open->tlink);
  464. queue_work(cifsiod_wq, &lw->lease_break);
  465. }
  466. cifs_dbg(FYI, "found in the pending open list\n");
  467. cifs_dbg(FYI, "lease key match, lease break 0x%x\n",
  468. le32_to_cpu(rsp->NewLeaseState));
  469. open->oplock = lease_state;
  470. }
  471. return found;
  472. }
  473. static bool
  474. smb2_is_valid_lease_break(char *buffer)
  475. {
  476. struct smb2_lease_break *rsp = (struct smb2_lease_break *)buffer;
  477. struct list_head *tmp, *tmp1, *tmp2;
  478. struct TCP_Server_Info *server;
  479. struct cifs_ses *ses;
  480. struct cifs_tcon *tcon;
  481. struct smb2_lease_break_work *lw;
  482. lw = kmalloc(sizeof(struct smb2_lease_break_work), GFP_KERNEL);
  483. if (!lw)
  484. return false;
  485. INIT_WORK(&lw->lease_break, cifs_ses_oplock_break);
  486. lw->lease_state = rsp->NewLeaseState;
  487. cifs_dbg(FYI, "Checking for lease break\n");
  488. /* look up tcon based on tid & uid */
  489. spin_lock(&cifs_tcp_ses_lock);
  490. list_for_each(tmp, &cifs_tcp_ses_list) {
  491. server = list_entry(tmp, struct TCP_Server_Info, tcp_ses_list);
  492. list_for_each(tmp1, &server->smb_ses_list) {
  493. ses = list_entry(tmp1, struct cifs_ses, smb_ses_list);
  494. list_for_each(tmp2, &ses->tcon_list) {
  495. tcon = list_entry(tmp2, struct cifs_tcon,
  496. tcon_list);
  497. spin_lock(&tcon->open_file_lock);
  498. cifs_stats_inc(
  499. &tcon->stats.cifs_stats.num_oplock_brks);
  500. if (smb2_tcon_has_lease(tcon, rsp, lw)) {
  501. spin_unlock(&tcon->open_file_lock);
  502. spin_unlock(&cifs_tcp_ses_lock);
  503. return true;
  504. }
  505. spin_unlock(&tcon->open_file_lock);
  506. }
  507. }
  508. }
  509. spin_unlock(&cifs_tcp_ses_lock);
  510. kfree(lw);
  511. cifs_dbg(FYI, "Can not process lease break - no lease matched\n");
  512. return false;
  513. }
  514. bool
  515. smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
  516. {
  517. struct smb2_oplock_break *rsp = (struct smb2_oplock_break *)buffer;
  518. struct list_head *tmp, *tmp1, *tmp2;
  519. struct cifs_ses *ses;
  520. struct cifs_tcon *tcon;
  521. struct cifsInodeInfo *cinode;
  522. struct cifsFileInfo *cfile;
  523. cifs_dbg(FYI, "Checking for oplock break\n");
  524. if (rsp->hdr.Command != SMB2_OPLOCK_BREAK)
  525. return false;
  526. if (rsp->StructureSize !=
  527. smb2_rsp_struct_sizes[SMB2_OPLOCK_BREAK_HE]) {
  528. if (le16_to_cpu(rsp->StructureSize) == 44)
  529. return smb2_is_valid_lease_break(buffer);
  530. else
  531. return false;
  532. }
  533. cifs_dbg(FYI, "oplock level 0x%x\n", rsp->OplockLevel);
  534. /* look up tcon based on tid & uid */
  535. spin_lock(&cifs_tcp_ses_lock);
  536. list_for_each(tmp, &server->smb_ses_list) {
  537. ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
  538. list_for_each(tmp1, &ses->tcon_list) {
  539. tcon = list_entry(tmp1, struct cifs_tcon, tcon_list);
  540. cifs_stats_inc(&tcon->stats.cifs_stats.num_oplock_brks);
  541. spin_lock(&tcon->open_file_lock);
  542. list_for_each(tmp2, &tcon->openFileList) {
  543. cfile = list_entry(tmp2, struct cifsFileInfo,
  544. tlist);
  545. if (rsp->PersistentFid !=
  546. cfile->fid.persistent_fid ||
  547. rsp->VolatileFid !=
  548. cfile->fid.volatile_fid)
  549. continue;
  550. cifs_dbg(FYI, "file id match, oplock break\n");
  551. cinode = CIFS_I(d_inode(cfile->dentry));
  552. spin_lock(&cfile->file_info_lock);
  553. if (!CIFS_CACHE_WRITE(cinode) &&
  554. rsp->OplockLevel == SMB2_OPLOCK_LEVEL_NONE)
  555. cfile->oplock_break_cancelled = true;
  556. else
  557. cfile->oplock_break_cancelled = false;
  558. set_bit(CIFS_INODE_PENDING_OPLOCK_BREAK,
  559. &cinode->flags);
  560. /*
  561. * Set flag if the server downgrades the oplock
  562. * to L2 else clear.
  563. */
  564. if (rsp->OplockLevel)
  565. set_bit(
  566. CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2,
  567. &cinode->flags);
  568. else
  569. clear_bit(
  570. CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2,
  571. &cinode->flags);
  572. spin_unlock(&cfile->file_info_lock);
  573. queue_work(cifsoplockd_wq,
  574. &cfile->oplock_break);
  575. spin_unlock(&tcon->open_file_lock);
  576. spin_unlock(&cifs_tcp_ses_lock);
  577. return true;
  578. }
  579. spin_unlock(&tcon->open_file_lock);
  580. spin_unlock(&cifs_tcp_ses_lock);
  581. cifs_dbg(FYI, "No matching file for oplock break\n");
  582. return true;
  583. }
  584. }
  585. spin_unlock(&cifs_tcp_ses_lock);
  586. cifs_dbg(FYI, "Can not process oplock break for non-existent connection\n");
  587. return false;
  588. }
  589. void
  590. smb2_cancelled_close_fid(struct work_struct *work)
  591. {
  592. struct close_cancelled_open *cancelled = container_of(work,
  593. struct close_cancelled_open, work);
  594. cifs_dbg(VFS, "Close unmatched open\n");
  595. SMB2_close(0, cancelled->tcon, cancelled->fid.persistent_fid,
  596. cancelled->fid.volatile_fid);
  597. cifs_put_tcon(cancelled->tcon);
  598. kfree(cancelled);
  599. }
  600. int
  601. smb2_handle_cancelled_mid(char *buffer, struct TCP_Server_Info *server)
  602. {
  603. struct smb2_hdr *hdr = (struct smb2_hdr *)buffer;
  604. struct smb2_create_rsp *rsp = (struct smb2_create_rsp *)buffer;
  605. struct cifs_tcon *tcon;
  606. struct close_cancelled_open *cancelled;
  607. if (hdr->Command != SMB2_CREATE || hdr->Status != STATUS_SUCCESS)
  608. return 0;
  609. cancelled = kzalloc(sizeof(*cancelled), GFP_KERNEL);
  610. if (!cancelled)
  611. return -ENOMEM;
  612. tcon = smb2_find_smb_tcon(server, hdr->SessionId, hdr->TreeId);
  613. if (!tcon) {
  614. kfree(cancelled);
  615. return -ENOENT;
  616. }
  617. cancelled->fid.persistent_fid = rsp->PersistentFileId;
  618. cancelled->fid.volatile_fid = rsp->VolatileFileId;
  619. cancelled->tcon = tcon;
  620. INIT_WORK(&cancelled->work, smb2_cancelled_close_fid);
  621. queue_work(cifsiod_wq, &cancelled->work);
  622. return 0;
  623. }