aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifssmb.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/cifssmb.c')
-rw-r--r--fs/cifs/cifssmb.c377
1 files changed, 207 insertions, 170 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index df959bae6728..83df937b814e 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -339,12 +339,13 @@ static int validate_t2(struct smb_t2_rsp *pSMB)
339 get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024) 339 get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
340 goto vt2_err; 340 goto vt2_err;
341 341
342 /* check that bcc is at least as big as parms + data */
343 /* check that bcc is less than negotiated smb buffer */
344 total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount); 342 total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
345 if (total_size >= 512) 343 if (total_size >= 512)
346 goto vt2_err; 344 goto vt2_err;
347 345
346 /* check that bcc is at least as big as parms + data, and that it is
347 * less than negotiated smb buffer
348 */
348 total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount); 349 total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
349 if (total_size > get_bcc(&pSMB->hdr) || 350 if (total_size > get_bcc(&pSMB->hdr) ||
350 total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) 351 total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
@@ -357,6 +358,13 @@ vt2_err:
357 return -EINVAL; 358 return -EINVAL;
358} 359}
359 360
361static inline void inc_rfc1001_len(void *pSMB, int count)
362{
363 struct smb_hdr *hdr = (struct smb_hdr *)pSMB;
364
365 be32_add_cpu(&hdr->smb_buf_length, count);
366}
367
360int 368int
361CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) 369CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
362{ 370{
@@ -409,7 +417,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
409 count += strlen(protocols[i].name) + 1; 417 count += strlen(protocols[i].name) + 1;
410 /* null at end of source and target buffers anyway */ 418 /* null at end of source and target buffers anyway */
411 } 419 }
412 pSMB->hdr.smb_buf_length += count; 420 inc_rfc1001_len(pSMB, count);
413 pSMB->ByteCount = cpu_to_le16(count); 421 pSMB->ByteCount = cpu_to_le16(count);
414 422
415 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, 423 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
@@ -541,10 +549,6 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
541 server->secType = RawNTLMSSP; 549 server->secType = RawNTLMSSP;
542 else if (secFlags & CIFSSEC_MAY_LANMAN) 550 else if (secFlags & CIFSSEC_MAY_LANMAN)
543 server->secType = LANMAN; 551 server->secType = LANMAN;
544/* #ifdef CONFIG_CIFS_EXPERIMENTAL
545 else if (secFlags & CIFSSEC_MAY_PLNTXT)
546 server->secType = ??
547#endif */
548 else { 552 else {
549 rc = -EOPNOTSUPP; 553 rc = -EOPNOTSUPP;
550 cERROR(1, "Invalid security type"); 554 cERROR(1, "Invalid security type");
@@ -578,7 +582,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
578 582
579 if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) && 583 if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) &&
580 (server->capabilities & CAP_EXTENDED_SECURITY)) { 584 (server->capabilities & CAP_EXTENDED_SECURITY)) {
581 count = pSMBr->ByteCount; 585 count = get_bcc(&pSMBr->hdr);
582 if (count < 16) { 586 if (count < 16) {
583 rc = -EIO; 587 rc = -EIO;
584 goto neg_err_exit; 588 goto neg_err_exit;
@@ -732,9 +736,9 @@ CIFSSMBEcho(struct TCP_Server_Info *server)
732 smb->hdr.Tid = 0xffff; 736 smb->hdr.Tid = 0xffff;
733 smb->hdr.WordCount = 1; 737 smb->hdr.WordCount = 1;
734 put_unaligned_le16(1, &smb->EchoCount); 738 put_unaligned_le16(1, &smb->EchoCount);
735 put_bcc_le(1, &smb->hdr); 739 put_bcc(1, &smb->hdr);
736 smb->Data[0] = 'a'; 740 smb->Data[0] = 'a';
737 smb->hdr.smb_buf_length += 3; 741 inc_rfc1001_len(smb, 3);
738 742
739 rc = cifs_call_async(server, (struct smb_hdr *)smb, 743 rc = cifs_call_async(server, (struct smb_hdr *)smb,
740 cifs_echo_callback, server); 744 cifs_echo_callback, server);
@@ -852,7 +856,7 @@ PsxDelete:
852 pSMB->TotalParameterCount = pSMB->ParameterCount; 856 pSMB->TotalParameterCount = pSMB->ParameterCount;
853 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK); 857 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
854 pSMB->Reserved4 = 0; 858 pSMB->Reserved4 = 0;
855 pSMB->hdr.smb_buf_length += byte_count; 859 inc_rfc1001_len(pSMB, byte_count);
856 pSMB->ByteCount = cpu_to_le16(byte_count); 860 pSMB->ByteCount = cpu_to_le16(byte_count);
857 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 861 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
858 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 862 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -898,7 +902,7 @@ DelFileRetry:
898 pSMB->SearchAttributes = 902 pSMB->SearchAttributes =
899 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM); 903 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
900 pSMB->BufferFormat = 0x04; 904 pSMB->BufferFormat = 0x04;
901 pSMB->hdr.smb_buf_length += name_len + 1; 905 inc_rfc1001_len(pSMB, name_len + 1);
902 pSMB->ByteCount = cpu_to_le16(name_len + 1); 906 pSMB->ByteCount = cpu_to_le16(name_len + 1);
903 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 907 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
904 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 908 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -942,7 +946,7 @@ RmDirRetry:
942 } 946 }
943 947
944 pSMB->BufferFormat = 0x04; 948 pSMB->BufferFormat = 0x04;
945 pSMB->hdr.smb_buf_length += name_len + 1; 949 inc_rfc1001_len(pSMB, name_len + 1);
946 pSMB->ByteCount = cpu_to_le16(name_len + 1); 950 pSMB->ByteCount = cpu_to_le16(name_len + 1);
947 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 951 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
948 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 952 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -985,7 +989,7 @@ MkDirRetry:
985 } 989 }
986 990
987 pSMB->BufferFormat = 0x04; 991 pSMB->BufferFormat = 0x04;
988 pSMB->hdr.smb_buf_length += name_len + 1; 992 inc_rfc1001_len(pSMB, name_len + 1);
989 pSMB->ByteCount = cpu_to_le16(name_len + 1); 993 pSMB->ByteCount = cpu_to_le16(name_len + 1);
990 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 994 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
991 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 995 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -1063,7 +1067,7 @@ PsxCreat:
1063 pSMB->TotalParameterCount = pSMB->ParameterCount; 1067 pSMB->TotalParameterCount = pSMB->ParameterCount;
1064 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN); 1068 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
1065 pSMB->Reserved4 = 0; 1069 pSMB->Reserved4 = 0;
1066 pSMB->hdr.smb_buf_length += byte_count; 1070 inc_rfc1001_len(pSMB, byte_count);
1067 pSMB->ByteCount = cpu_to_le16(byte_count); 1071 pSMB->ByteCount = cpu_to_le16(byte_count);
1068 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1072 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1069 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1073 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -1075,7 +1079,7 @@ PsxCreat:
1075 cFYI(1, "copying inode info"); 1079 cFYI(1, "copying inode info");
1076 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 1080 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1077 1081
1078 if (rc || (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP))) { 1082 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
1079 rc = -EIO; /* bad smb */ 1083 rc = -EIO; /* bad smb */
1080 goto psx_create_err; 1084 goto psx_create_err;
1081 } 1085 }
@@ -1096,7 +1100,7 @@ PsxCreat:
1096 pRetData->Type = cpu_to_le32(-1); /* unknown */ 1100 pRetData->Type = cpu_to_le32(-1); /* unknown */
1097 cFYI(DBG2, "unknown type"); 1101 cFYI(DBG2, "unknown type");
1098 } else { 1102 } else {
1099 if (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP) 1103 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
1100 + sizeof(FILE_UNIX_BASIC_INFO)) { 1104 + sizeof(FILE_UNIX_BASIC_INFO)) {
1101 cERROR(1, "Open response data too small"); 1105 cERROR(1, "Open response data too small");
1102 pRetData->Type = cpu_to_le32(-1); 1106 pRetData->Type = cpu_to_le32(-1);
@@ -1228,7 +1232,7 @@ OldOpenRetry:
1228 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY); 1232 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
1229 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition)); 1233 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
1230 count += name_len; 1234 count += name_len;
1231 pSMB->hdr.smb_buf_length += count; 1235 inc_rfc1001_len(pSMB, count);
1232 1236
1233 pSMB->ByteCount = cpu_to_le16(count); 1237 pSMB->ByteCount = cpu_to_le16(count);
1234 /* long_op set to 1 to allow for oplock break timeouts */ 1238 /* long_op set to 1 to allow for oplock break timeouts */
@@ -1341,7 +1345,7 @@ openRetry:
1341 SECURITY_CONTEXT_TRACKING | SECURITY_EFFECTIVE_ONLY; 1345 SECURITY_CONTEXT_TRACKING | SECURITY_EFFECTIVE_ONLY;
1342 1346
1343 count += name_len; 1347 count += name_len;
1344 pSMB->hdr.smb_buf_length += count; 1348 inc_rfc1001_len(pSMB, count);
1345 1349
1346 pSMB->ByteCount = cpu_to_le16(count); 1350 pSMB->ByteCount = cpu_to_le16(count);
1347 /* long_op set to 1 to allow for oplock break timeouts */ 1351 /* long_op set to 1 to allow for oplock break timeouts */
@@ -1426,7 +1430,7 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
1426 } 1430 }
1427 1431
1428 iov[0].iov_base = (char *)pSMB; 1432 iov[0].iov_base = (char *)pSMB;
1429 iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; 1433 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1430 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */, 1434 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
1431 &resp_buf_type, CIFS_LOG_ERROR); 1435 &resp_buf_type, CIFS_LOG_ERROR);
1432 cifs_stats_inc(&tcon->num_reads); 1436 cifs_stats_inc(&tcon->num_reads);
@@ -1560,7 +1564,7 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
1560 1564
1561 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF); 1565 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
1562 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16); 1566 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1563 pSMB->hdr.smb_buf_length += byte_count; 1567 inc_rfc1001_len(pSMB, byte_count);
1564 1568
1565 if (wct == 14) 1569 if (wct == 14)
1566 pSMB->ByteCount = cpu_to_le16(byte_count); 1570 pSMB->ByteCount = cpu_to_le16(byte_count);
@@ -1644,11 +1648,12 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1644 1648
1645 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF); 1649 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
1646 pSMB->DataLengthHigh = cpu_to_le16(count >> 16); 1650 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
1647 smb_hdr_len = pSMB->hdr.smb_buf_length + 1; /* hdr + 1 byte pad */ 1651 /* header + 1 byte pad */
1652 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
1648 if (wct == 14) 1653 if (wct == 14)
1649 pSMB->hdr.smb_buf_length += count+1; 1654 inc_rfc1001_len(pSMB, count + 1);
1650 else /* wct == 12 */ 1655 else /* wct == 12 */
1651 pSMB->hdr.smb_buf_length += count+5; /* smb data starts later */ 1656 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
1652 if (wct == 14) 1657 if (wct == 14)
1653 pSMB->ByteCount = cpu_to_le16(count + 1); 1658 pSMB->ByteCount = cpu_to_le16(count + 1);
1654 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ { 1659 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
@@ -1748,7 +1753,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1748 /* oplock break */ 1753 /* oplock break */
1749 count = 0; 1754 count = 0;
1750 } 1755 }
1751 pSMB->hdr.smb_buf_length += count; 1756 inc_rfc1001_len(pSMB, count);
1752 pSMB->ByteCount = cpu_to_le16(count); 1757 pSMB->ByteCount = cpu_to_le16(count);
1753 1758
1754 if (waitFlag) { 1759 if (waitFlag) {
@@ -1839,14 +1844,14 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1839 pSMB->Fid = smb_file_id; 1844 pSMB->Fid = smb_file_id;
1840 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK); 1845 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
1841 pSMB->Reserved4 = 0; 1846 pSMB->Reserved4 = 0;
1842 pSMB->hdr.smb_buf_length += byte_count; 1847 inc_rfc1001_len(pSMB, byte_count);
1843 pSMB->ByteCount = cpu_to_le16(byte_count); 1848 pSMB->ByteCount = cpu_to_le16(byte_count);
1844 if (waitFlag) { 1849 if (waitFlag) {
1845 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, 1850 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
1846 (struct smb_hdr *) pSMBr, &bytes_returned); 1851 (struct smb_hdr *) pSMBr, &bytes_returned);
1847 } else { 1852 } else {
1848 iov[0].iov_base = (char *)pSMB; 1853 iov[0].iov_base = (char *)pSMB;
1849 iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; 1854 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
1850 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */, 1855 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
1851 &resp_buf_type, timeout); 1856 &resp_buf_type, timeout);
1852 pSMB = NULL; /* request buf already freed by SendReceive2. Do 1857 pSMB = NULL; /* request buf already freed by SendReceive2. Do
@@ -1862,7 +1867,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1862 __u16 data_count; 1867 __u16 data_count;
1863 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 1868 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
1864 1869
1865 if (rc || (pSMBr->ByteCount < sizeof(struct cifs_posix_lock))) { 1870 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
1866 rc = -EIO; /* bad smb */ 1871 rc = -EIO; /* bad smb */
1867 goto plk_err_exit; 1872 goto plk_err_exit;
1868 } 1873 }
@@ -2012,7 +2017,7 @@ renameRetry:
2012 } 2017 }
2013 2018
2014 count = 1 /* 1st signature byte */ + name_len + name_len2; 2019 count = 1 /* 1st signature byte */ + name_len + name_len2;
2015 pSMB->hdr.smb_buf_length += count; 2020 inc_rfc1001_len(pSMB, count);
2016 pSMB->ByteCount = cpu_to_le16(count); 2021 pSMB->ByteCount = cpu_to_le16(count);
2017 2022
2018 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2023 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -2092,7 +2097,7 @@ int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon,
2092 pSMB->InformationLevel = 2097 pSMB->InformationLevel =
2093 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION); 2098 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
2094 pSMB->Reserved4 = 0; 2099 pSMB->Reserved4 = 0;
2095 pSMB->hdr.smb_buf_length += byte_count; 2100 inc_rfc1001_len(pSMB, byte_count);
2096 pSMB->ByteCount = cpu_to_le16(byte_count); 2101 pSMB->ByteCount = cpu_to_le16(byte_count);
2097 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB, 2102 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
2098 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2103 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -2159,7 +2164,7 @@ copyRetry:
2159 } 2164 }
2160 2165
2161 count = 1 /* 1st signature byte */ + name_len + name_len2; 2166 count = 1 /* 1st signature byte */ + name_len + name_len2;
2162 pSMB->hdr.smb_buf_length += count; 2167 inc_rfc1001_len(pSMB, count);
2163 pSMB->ByteCount = cpu_to_le16(count); 2168 pSMB->ByteCount = cpu_to_le16(count);
2164 2169
2165 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2170 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -2249,7 +2254,7 @@ createSymLinkRetry:
2249 pSMB->DataOffset = cpu_to_le16(offset); 2254 pSMB->DataOffset = cpu_to_le16(offset);
2250 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK); 2255 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
2251 pSMB->Reserved4 = 0; 2256 pSMB->Reserved4 = 0;
2252 pSMB->hdr.smb_buf_length += byte_count; 2257 inc_rfc1001_len(pSMB, byte_count);
2253 pSMB->ByteCount = cpu_to_le16(byte_count); 2258 pSMB->ByteCount = cpu_to_le16(byte_count);
2254 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2259 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2255 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2260 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -2335,7 +2340,7 @@ createHardLinkRetry:
2335 pSMB->DataOffset = cpu_to_le16(offset); 2340 pSMB->DataOffset = cpu_to_le16(offset);
2336 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK); 2341 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
2337 pSMB->Reserved4 = 0; 2342 pSMB->Reserved4 = 0;
2338 pSMB->hdr.smb_buf_length += byte_count; 2343 inc_rfc1001_len(pSMB, byte_count);
2339 pSMB->ByteCount = cpu_to_le16(byte_count); 2344 pSMB->ByteCount = cpu_to_le16(byte_count);
2340 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2345 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2341 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2346 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -2406,7 +2411,7 @@ winCreateHardLinkRetry:
2406 } 2411 }
2407 2412
2408 count = 1 /* string type byte */ + name_len + name_len2; 2413 count = 1 /* string type byte */ + name_len + name_len2;
2409 pSMB->hdr.smb_buf_length += count; 2414 inc_rfc1001_len(pSMB, count);
2410 pSMB->ByteCount = cpu_to_le16(count); 2415 pSMB->ByteCount = cpu_to_le16(count);
2411 2416
2412 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2417 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -2477,7 +2482,7 @@ querySymLinkRetry:
2477 pSMB->ParameterCount = pSMB->TotalParameterCount; 2482 pSMB->ParameterCount = pSMB->TotalParameterCount;
2478 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK); 2483 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
2479 pSMB->Reserved4 = 0; 2484 pSMB->Reserved4 = 0;
2480 pSMB->hdr.smb_buf_length += byte_count; 2485 inc_rfc1001_len(pSMB, byte_count);
2481 pSMB->ByteCount = cpu_to_le16(byte_count); 2486 pSMB->ByteCount = cpu_to_le16(byte_count);
2482 2487
2483 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2488 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -2489,7 +2494,7 @@ querySymLinkRetry:
2489 2494
2490 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 2495 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2491 /* BB also check enough total bytes returned */ 2496 /* BB also check enough total bytes returned */
2492 if (rc || (pSMBr->ByteCount < 2)) 2497 if (rc || get_bcc(&pSMBr->hdr) < 2)
2493 rc = -EIO; 2498 rc = -EIO;
2494 else { 2499 else {
2495 bool is_unicode; 2500 bool is_unicode;
@@ -2516,7 +2521,17 @@ querySymLinkRetry:
2516 return rc; 2521 return rc;
2517} 2522}
2518 2523
2519#ifdef CONFIG_CIFS_EXPERIMENTAL 2524#ifdef CONFIG_CIFS_SYMLINK_EXPERIMENTAL
2525/*
2526 * Recent Windows versions now create symlinks more frequently
2527 * and they use the "reparse point" mechanism below. We can of course
2528 * do symlinks nicely to Samba and other servers which support the
2529 * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
2530 * "MF" symlinks optionally, but for recent Windows we really need to
2531 * reenable the code below and fix the cifs_symlink callers to handle this.
2532 * In the interim this code has been moved to its own config option so
2533 * it is not compiled in by default until callers fixed up and more tested.
2534 */
2520int 2535int
2521CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, 2536CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
2522 const unsigned char *searchName, 2537 const unsigned char *searchName,
@@ -2561,14 +2576,14 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
2561 } else { /* decode response */ 2576 } else { /* decode response */
2562 __u32 data_offset = le32_to_cpu(pSMBr->DataOffset); 2577 __u32 data_offset = le32_to_cpu(pSMBr->DataOffset);
2563 __u32 data_count = le32_to_cpu(pSMBr->DataCount); 2578 __u32 data_count = le32_to_cpu(pSMBr->DataCount);
2564 if ((pSMBr->ByteCount < 2) || (data_offset > 512)) { 2579 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
2565 /* BB also check enough total bytes returned */ 2580 /* BB also check enough total bytes returned */
2566 rc = -EIO; /* bad smb */ 2581 rc = -EIO; /* bad smb */
2567 goto qreparse_out; 2582 goto qreparse_out;
2568 } 2583 }
2569 if (data_count && (data_count < 2048)) { 2584 if (data_count && (data_count < 2048)) {
2570 char *end_of_smb = 2 /* sizeof byte count */ + 2585 char *end_of_smb = 2 /* sizeof byte count */ +
2571 pSMBr->ByteCount + (char *)&pSMBr->ByteCount; 2586 get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
2572 2587
2573 struct reparse_data *reparse_buf = 2588 struct reparse_data *reparse_buf =
2574 (struct reparse_data *) 2589 (struct reparse_data *)
@@ -2618,7 +2633,7 @@ qreparse_out:
2618 2633
2619 return rc; 2634 return rc;
2620} 2635}
2621#endif /* CIFS_EXPERIMENTAL */ 2636#endif /* CIFS_SYMLINK_EXPERIMENTAL */ /* BB temporarily unused */
2622 2637
2623#ifdef CONFIG_CIFS_POSIX 2638#ifdef CONFIG_CIFS_POSIX
2624 2639
@@ -2814,7 +2829,7 @@ queryAclRetry:
2814 pSMB->ParameterCount = pSMB->TotalParameterCount; 2829 pSMB->ParameterCount = pSMB->TotalParameterCount;
2815 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL); 2830 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
2816 pSMB->Reserved4 = 0; 2831 pSMB->Reserved4 = 0;
2817 pSMB->hdr.smb_buf_length += byte_count; 2832 inc_rfc1001_len(pSMB, byte_count);
2818 pSMB->ByteCount = cpu_to_le16(byte_count); 2833 pSMB->ByteCount = cpu_to_le16(byte_count);
2819 2834
2820 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2835 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -2826,8 +2841,8 @@ queryAclRetry:
2826 /* decode response */ 2841 /* decode response */
2827 2842
2828 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 2843 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2829 if (rc || (pSMBr->ByteCount < 2))
2830 /* BB also check enough total bytes returned */ 2844 /* BB also check enough total bytes returned */
2845 if (rc || get_bcc(&pSMBr->hdr) < 2)
2831 rc = -EIO; /* bad smb */ 2846 rc = -EIO; /* bad smb */
2832 else { 2847 else {
2833 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 2848 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
@@ -2908,7 +2923,7 @@ setAclRetry:
2908 pSMB->ParameterCount = cpu_to_le16(params); 2923 pSMB->ParameterCount = cpu_to_le16(params);
2909 pSMB->TotalParameterCount = pSMB->ParameterCount; 2924 pSMB->TotalParameterCount = pSMB->ParameterCount;
2910 pSMB->Reserved4 = 0; 2925 pSMB->Reserved4 = 0;
2911 pSMB->hdr.smb_buf_length += byte_count; 2926 inc_rfc1001_len(pSMB, byte_count);
2912 pSMB->ByteCount = cpu_to_le16(byte_count); 2927 pSMB->ByteCount = cpu_to_le16(byte_count);
2913 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2928 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2914 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2929 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -2966,7 +2981,7 @@ GetExtAttrRetry:
2966 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS); 2981 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
2967 pSMB->Pad = 0; 2982 pSMB->Pad = 0;
2968 pSMB->Fid = netfid; 2983 pSMB->Fid = netfid;
2969 pSMB->hdr.smb_buf_length += byte_count; 2984 inc_rfc1001_len(pSMB, byte_count);
2970 pSMB->t2.ByteCount = cpu_to_le16(byte_count); 2985 pSMB->t2.ByteCount = cpu_to_le16(byte_count);
2971 2986
2972 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2987 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -2976,8 +2991,8 @@ GetExtAttrRetry:
2976 } else { 2991 } else {
2977 /* decode response */ 2992 /* decode response */
2978 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 2993 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2979 if (rc || (pSMBr->ByteCount < 2))
2980 /* BB also check enough total bytes returned */ 2994 /* BB also check enough total bytes returned */
2995 if (rc || get_bcc(&pSMBr->hdr) < 2)
2981 /* If rc should we check for EOPNOSUPP and 2996 /* If rc should we check for EOPNOSUPP and
2982 disable the srvino flag? or in caller? */ 2997 disable the srvino flag? or in caller? */
2983 rc = -EIO; /* bad smb */ 2998 rc = -EIO; /* bad smb */
@@ -3052,6 +3067,7 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata,
3052 char *end_of_smb; 3067 char *end_of_smb;
3053 __u32 data_count, data_offset, parm_count, parm_offset; 3068 __u32 data_count, data_offset, parm_count, parm_offset;
3054 struct smb_com_ntransact_rsp *pSMBr; 3069 struct smb_com_ntransact_rsp *pSMBr;
3070 u16 bcc;
3055 3071
3056 *pdatalen = 0; 3072 *pdatalen = 0;
3057 *pparmlen = 0; 3073 *pparmlen = 0;
@@ -3061,8 +3077,8 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata,
3061 3077
3062 pSMBr = (struct smb_com_ntransact_rsp *)buf; 3078 pSMBr = (struct smb_com_ntransact_rsp *)buf;
3063 3079
3064 /* ByteCount was converted from little endian in SendReceive */ 3080 bcc = get_bcc(&pSMBr->hdr);
3065 end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount + 3081 end_of_smb = 2 /* sizeof byte count */ + bcc +
3066 (char *)&pSMBr->ByteCount; 3082 (char *)&pSMBr->ByteCount;
3067 3083
3068 data_offset = le32_to_cpu(pSMBr->DataOffset); 3084 data_offset = le32_to_cpu(pSMBr->DataOffset);
@@ -3088,7 +3104,7 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata,
3088 *ppdata, data_count, (data_count + *ppdata), 3104 *ppdata, data_count, (data_count + *ppdata),
3089 end_of_smb, pSMBr); 3105 end_of_smb, pSMBr);
3090 return -EINVAL; 3106 return -EINVAL;
3091 } else if (parm_count + data_count > pSMBr->ByteCount) { 3107 } else if (parm_count + data_count > bcc) {
3092 cFYI(1, "parm count and data count larger than SMB"); 3108 cFYI(1, "parm count and data count larger than SMB");
3093 return -EINVAL; 3109 return -EINVAL;
3094 } 3110 }
@@ -3124,9 +3140,9 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
3124 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP | 3140 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
3125 CIFS_ACL_DACL); 3141 CIFS_ACL_DACL);
3126 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */ 3142 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
3127 pSMB->hdr.smb_buf_length += 11; 3143 inc_rfc1001_len(pSMB, 11);
3128 iov[0].iov_base = (char *)pSMB; 3144 iov[0].iov_base = (char *)pSMB;
3129 iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; 3145 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
3130 3146
3131 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, 3147 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3132 0); 3148 0);
@@ -3235,10 +3251,9 @@ setCifsAclRetry:
3235 memcpy((char *) &pSMBr->hdr.Protocol + data_offset, 3251 memcpy((char *) &pSMBr->hdr.Protocol + data_offset,
3236 (char *) pntsd, 3252 (char *) pntsd,
3237 acllen); 3253 acllen);
3238 pSMB->hdr.smb_buf_length += (byte_count + data_count); 3254 inc_rfc1001_len(pSMB, byte_count + data_count);
3239
3240 } else 3255 } else
3241 pSMB->hdr.smb_buf_length += byte_count; 3256 inc_rfc1001_len(pSMB, byte_count);
3242 3257
3243 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3258 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3244 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3259 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -3289,7 +3304,7 @@ QInfRetry:
3289 } 3304 }
3290 pSMB->BufferFormat = 0x04; 3305 pSMB->BufferFormat = 0x04;
3291 name_len++; /* account for buffer type byte */ 3306 name_len++; /* account for buffer type byte */
3292 pSMB->hdr.smb_buf_length += (__u16) name_len; 3307 inc_rfc1001_len(pSMB, (__u16)name_len);
3293 pSMB->ByteCount = cpu_to_le16(name_len); 3308 pSMB->ByteCount = cpu_to_le16(name_len);
3294 3309
3295 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3310 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -3364,7 +3379,7 @@ QFileInfoRetry:
3364 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO); 3379 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3365 pSMB->Pad = 0; 3380 pSMB->Pad = 0;
3366 pSMB->Fid = netfid; 3381 pSMB->Fid = netfid;
3367 pSMB->hdr.smb_buf_length += byte_count; 3382 inc_rfc1001_len(pSMB, byte_count);
3368 3383
3369 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3384 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3370 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3385 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -3375,7 +3390,7 @@ QFileInfoRetry:
3375 3390
3376 if (rc) /* BB add auto retry on EOPNOTSUPP? */ 3391 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3377 rc = -EIO; 3392 rc = -EIO;
3378 else if (pSMBr->ByteCount < 40) 3393 else if (get_bcc(&pSMBr->hdr) < 40)
3379 rc = -EIO; /* bad smb */ 3394 rc = -EIO; /* bad smb */
3380 else if (pFindData) { 3395 else if (pFindData) {
3381 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3396 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
@@ -3451,7 +3466,7 @@ QPathInfoRetry:
3451 else 3466 else
3452 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO); 3467 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
3453 pSMB->Reserved4 = 0; 3468 pSMB->Reserved4 = 0;
3454 pSMB->hdr.smb_buf_length += byte_count; 3469 inc_rfc1001_len(pSMB, byte_count);
3455 pSMB->ByteCount = cpu_to_le16(byte_count); 3470 pSMB->ByteCount = cpu_to_le16(byte_count);
3456 3471
3457 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3472 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -3463,9 +3478,9 @@ QPathInfoRetry:
3463 3478
3464 if (rc) /* BB add auto retry on EOPNOTSUPP? */ 3479 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3465 rc = -EIO; 3480 rc = -EIO;
3466 else if (!legacy && (pSMBr->ByteCount < 40)) 3481 else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
3467 rc = -EIO; /* bad smb */ 3482 rc = -EIO; /* bad smb */
3468 else if (legacy && (pSMBr->ByteCount < 24)) 3483 else if (legacy && get_bcc(&pSMBr->hdr) < 24)
3469 rc = -EIO; /* 24 or 26 expected but we do not read 3484 rc = -EIO; /* 24 or 26 expected but we do not read
3470 last field */ 3485 last field */
3471 else if (pFindData) { 3486 else if (pFindData) {
@@ -3532,7 +3547,7 @@ UnixQFileInfoRetry:
3532 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC); 3547 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
3533 pSMB->Pad = 0; 3548 pSMB->Pad = 0;
3534 pSMB->Fid = netfid; 3549 pSMB->Fid = netfid;
3535 pSMB->hdr.smb_buf_length += byte_count; 3550 inc_rfc1001_len(pSMB, byte_count);
3536 3551
3537 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3552 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3538 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3553 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -3541,7 +3556,7 @@ UnixQFileInfoRetry:
3541 } else { /* decode response */ 3556 } else { /* decode response */
3542 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3557 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3543 3558
3544 if (rc || (pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO))) { 3559 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
3545 cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n" 3560 cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n"
3546 "Unix Extensions can be disabled on mount " 3561 "Unix Extensions can be disabled on mount "
3547 "by specifying the nosfu mount option."); 3562 "by specifying the nosfu mount option.");
@@ -3617,7 +3632,7 @@ UnixQPathInfoRetry:
3617 pSMB->ParameterCount = pSMB->TotalParameterCount; 3632 pSMB->ParameterCount = pSMB->TotalParameterCount;
3618 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC); 3633 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
3619 pSMB->Reserved4 = 0; 3634 pSMB->Reserved4 = 0;
3620 pSMB->hdr.smb_buf_length += byte_count; 3635 inc_rfc1001_len(pSMB, byte_count);
3621 pSMB->ByteCount = cpu_to_le16(byte_count); 3636 pSMB->ByteCount = cpu_to_le16(byte_count);
3622 3637
3623 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3638 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -3627,7 +3642,7 @@ UnixQPathInfoRetry:
3627 } else { /* decode response */ 3642 } else { /* decode response */
3628 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3643 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3629 3644
3630 if (rc || (pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO))) { 3645 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
3631 cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n" 3646 cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n"
3632 "Unix Extensions can be disabled on mount " 3647 "Unix Extensions can be disabled on mount "
3633 "by specifying the nosfu mount option."); 3648 "by specifying the nosfu mount option.");
@@ -3731,7 +3746,7 @@ findFirstRetry:
3731 3746
3732 /* BB what should we set StorageType to? Does it matter? BB */ 3747 /* BB what should we set StorageType to? Does it matter? BB */
3733 pSMB->SearchStorageType = 0; 3748 pSMB->SearchStorageType = 0;
3734 pSMB->hdr.smb_buf_length += byte_count; 3749 inc_rfc1001_len(pSMB, byte_count);
3735 pSMB->ByteCount = cpu_to_le16(byte_count); 3750 pSMB->ByteCount = cpu_to_le16(byte_count);
3736 3751
3737 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3752 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -3860,7 +3875,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
3860 byte_count = params + 1 /* pad */ ; 3875 byte_count = params + 1 /* pad */ ;
3861 pSMB->TotalParameterCount = cpu_to_le16(params); 3876 pSMB->TotalParameterCount = cpu_to_le16(params);
3862 pSMB->ParameterCount = pSMB->TotalParameterCount; 3877 pSMB->ParameterCount = pSMB->TotalParameterCount;
3863 pSMB->hdr.smb_buf_length += byte_count; 3878 inc_rfc1001_len(pSMB, byte_count);
3864 pSMB->ByteCount = cpu_to_le16(byte_count); 3879 pSMB->ByteCount = cpu_to_le16(byte_count);
3865 3880
3866 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3881 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -4022,7 +4037,7 @@ GetInodeNumberRetry:
4022 pSMB->ParameterCount = pSMB->TotalParameterCount; 4037 pSMB->ParameterCount = pSMB->TotalParameterCount;
4023 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO); 4038 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
4024 pSMB->Reserved4 = 0; 4039 pSMB->Reserved4 = 0;
4025 pSMB->hdr.smb_buf_length += byte_count; 4040 inc_rfc1001_len(pSMB, byte_count);
4026 pSMB->ByteCount = cpu_to_le16(byte_count); 4041 pSMB->ByteCount = cpu_to_le16(byte_count);
4027 4042
4028 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4043 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -4032,8 +4047,8 @@ GetInodeNumberRetry:
4032 } else { 4047 } else {
4033 /* decode response */ 4048 /* decode response */
4034 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4049 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4035 if (rc || (pSMBr->ByteCount < 2))
4036 /* BB also check enough total bytes returned */ 4050 /* BB also check enough total bytes returned */
4051 if (rc || get_bcc(&pSMBr->hdr) < 2)
4037 /* If rc should we check for EOPNOSUPP and 4052 /* If rc should we check for EOPNOSUPP and
4038 disable the srvino flag? or in caller? */ 4053 disable the srvino flag? or in caller? */
4039 rc = -EIO; /* bad smb */ 4054 rc = -EIO; /* bad smb */
@@ -4246,7 +4261,7 @@ getDFSRetry:
4246 pSMB->ParameterCount = cpu_to_le16(params); 4261 pSMB->ParameterCount = cpu_to_le16(params);
4247 pSMB->TotalParameterCount = pSMB->ParameterCount; 4262 pSMB->TotalParameterCount = pSMB->ParameterCount;
4248 pSMB->MaxReferralLevel = cpu_to_le16(3); 4263 pSMB->MaxReferralLevel = cpu_to_le16(3);
4249 pSMB->hdr.smb_buf_length += byte_count; 4264 inc_rfc1001_len(pSMB, byte_count);
4250 pSMB->ByteCount = cpu_to_le16(byte_count); 4265 pSMB->ByteCount = cpu_to_le16(byte_count);
4251 4266
4252 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, 4267 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
@@ -4258,13 +4273,13 @@ getDFSRetry:
4258 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4273 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4259 4274
4260 /* BB Also check if enough total bytes returned? */ 4275 /* BB Also check if enough total bytes returned? */
4261 if (rc || (pSMBr->ByteCount < 17)) { 4276 if (rc || get_bcc(&pSMBr->hdr) < 17) {
4262 rc = -EIO; /* bad smb */ 4277 rc = -EIO; /* bad smb */
4263 goto GetDFSRefExit; 4278 goto GetDFSRefExit;
4264 } 4279 }
4265 4280
4266 cFYI(1, "Decoding GetDFSRefer response BCC: %d Offset %d", 4281 cFYI(1, "Decoding GetDFSRefer response BCC: %d Offset %d",
4267 pSMBr->ByteCount, 4282 get_bcc(&pSMBr->hdr),
4268 le16_to_cpu(pSMBr->t2.DataOffset)); 4283 le16_to_cpu(pSMBr->t2.DataOffset));
4269 4284
4270 /* parse returned result into more usable form */ 4285 /* parse returned result into more usable form */
@@ -4320,7 +4335,7 @@ oldQFSInfoRetry:
4320 pSMB->Reserved3 = 0; 4335 pSMB->Reserved3 = 0;
4321 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4336 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4322 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION); 4337 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
4323 pSMB->hdr.smb_buf_length += byte_count; 4338 inc_rfc1001_len(pSMB, byte_count);
4324 pSMB->ByteCount = cpu_to_le16(byte_count); 4339 pSMB->ByteCount = cpu_to_le16(byte_count);
4325 4340
4326 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4341 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -4330,12 +4345,12 @@ oldQFSInfoRetry:
4330 } else { /* decode response */ 4345 } else { /* decode response */
4331 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4346 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4332 4347
4333 if (rc || (pSMBr->ByteCount < 18)) 4348 if (rc || get_bcc(&pSMBr->hdr) < 18)
4334 rc = -EIO; /* bad smb */ 4349 rc = -EIO; /* bad smb */
4335 else { 4350 else {
4336 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4351 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4337 cFYI(1, "qfsinf resp BCC: %d Offset %d", 4352 cFYI(1, "qfsinf resp BCC: %d Offset %d",
4338 pSMBr->ByteCount, data_offset); 4353 get_bcc(&pSMBr->hdr), data_offset);
4339 4354
4340 response_data = (FILE_SYSTEM_ALLOC_INFO *) 4355 response_data = (FILE_SYSTEM_ALLOC_INFO *)
4341 (((char *) &pSMBr->hdr.Protocol) + data_offset); 4356 (((char *) &pSMBr->hdr.Protocol) + data_offset);
@@ -4399,7 +4414,7 @@ QFSInfoRetry:
4399 pSMB->Reserved3 = 0; 4414 pSMB->Reserved3 = 0;
4400 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4415 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4401 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO); 4416 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
4402 pSMB->hdr.smb_buf_length += byte_count; 4417 inc_rfc1001_len(pSMB, byte_count);
4403 pSMB->ByteCount = cpu_to_le16(byte_count); 4418 pSMB->ByteCount = cpu_to_le16(byte_count);
4404 4419
4405 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4420 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -4409,7 +4424,7 @@ QFSInfoRetry:
4409 } else { /* decode response */ 4424 } else { /* decode response */
4410 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4425 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4411 4426
4412 if (rc || (pSMBr->ByteCount < 24)) 4427 if (rc || get_bcc(&pSMBr->hdr) < 24)
4413 rc = -EIO; /* bad smb */ 4428 rc = -EIO; /* bad smb */
4414 else { 4429 else {
4415 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4430 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
@@ -4479,7 +4494,7 @@ QFSAttributeRetry:
4479 pSMB->Reserved3 = 0; 4494 pSMB->Reserved3 = 0;
4480 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4495 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4481 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO); 4496 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
4482 pSMB->hdr.smb_buf_length += byte_count; 4497 inc_rfc1001_len(pSMB, byte_count);
4483 pSMB->ByteCount = cpu_to_le16(byte_count); 4498 pSMB->ByteCount = cpu_to_le16(byte_count);
4484 4499
4485 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4500 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -4489,7 +4504,7 @@ QFSAttributeRetry:
4489 } else { /* decode response */ 4504 } else { /* decode response */
4490 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4505 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4491 4506
4492 if (rc || (pSMBr->ByteCount < 13)) { 4507 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4493 /* BB also check if enough bytes returned */ 4508 /* BB also check if enough bytes returned */
4494 rc = -EIO; /* bad smb */ 4509 rc = -EIO; /* bad smb */
4495 } else { 4510 } else {
@@ -4550,7 +4565,7 @@ QFSDeviceRetry:
4550 pSMB->Reserved3 = 0; 4565 pSMB->Reserved3 = 0;
4551 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4566 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4552 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO); 4567 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
4553 pSMB->hdr.smb_buf_length += byte_count; 4568 inc_rfc1001_len(pSMB, byte_count);
4554 pSMB->ByteCount = cpu_to_le16(byte_count); 4569 pSMB->ByteCount = cpu_to_le16(byte_count);
4555 4570
4556 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4571 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -4560,7 +4575,8 @@ QFSDeviceRetry:
4560 } else { /* decode response */ 4575 } else { /* decode response */
4561 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4576 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4562 4577
4563 if (rc || (pSMBr->ByteCount < sizeof(FILE_SYSTEM_DEVICE_INFO))) 4578 if (rc || get_bcc(&pSMBr->hdr) <
4579 sizeof(FILE_SYSTEM_DEVICE_INFO))
4564 rc = -EIO; /* bad smb */ 4580 rc = -EIO; /* bad smb */
4565 else { 4581 else {
4566 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4582 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
@@ -4619,7 +4635,7 @@ QFSUnixRetry:
4619 pSMB->Reserved3 = 0; 4635 pSMB->Reserved3 = 0;
4620 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4636 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4621 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO); 4637 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
4622 pSMB->hdr.smb_buf_length += byte_count; 4638 inc_rfc1001_len(pSMB, byte_count);
4623 pSMB->ByteCount = cpu_to_le16(byte_count); 4639 pSMB->ByteCount = cpu_to_le16(byte_count);
4624 4640
4625 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4641 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -4629,7 +4645,7 @@ QFSUnixRetry:
4629 } else { /* decode response */ 4645 } else { /* decode response */
4630 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4646 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4631 4647
4632 if (rc || (pSMBr->ByteCount < 13)) { 4648 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4633 rc = -EIO; /* bad smb */ 4649 rc = -EIO; /* bad smb */
4634 } else { 4650 } else {
4635 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4651 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
@@ -4702,7 +4718,7 @@ SETFSUnixRetry:
4702 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION); 4718 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
4703 pSMB->ClientUnixCap = cpu_to_le64(cap); 4719 pSMB->ClientUnixCap = cpu_to_le64(cap);
4704 4720
4705 pSMB->hdr.smb_buf_length += byte_count; 4721 inc_rfc1001_len(pSMB, byte_count);
4706 pSMB->ByteCount = cpu_to_le16(byte_count); 4722 pSMB->ByteCount = cpu_to_le16(byte_count);
4707 4723
4708 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4724 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -4764,7 +4780,7 @@ QFSPosixRetry:
4764 pSMB->Reserved3 = 0; 4780 pSMB->Reserved3 = 0;
4765 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4781 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
4766 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO); 4782 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
4767 pSMB->hdr.smb_buf_length += byte_count; 4783 inc_rfc1001_len(pSMB, byte_count);
4768 pSMB->ByteCount = cpu_to_le16(byte_count); 4784 pSMB->ByteCount = cpu_to_le16(byte_count);
4769 4785
4770 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4786 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -4774,7 +4790,7 @@ QFSPosixRetry:
4774 } else { /* decode response */ 4790 } else { /* decode response */
4775 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4791 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
4776 4792
4777 if (rc || (pSMBr->ByteCount < 13)) { 4793 if (rc || get_bcc(&pSMBr->hdr) < 13) {
4778 rc = -EIO; /* bad smb */ 4794 rc = -EIO; /* bad smb */
4779 } else { 4795 } else {
4780 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4796 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
@@ -4890,7 +4906,7 @@ SetEOFRetry:
4890 pSMB->ParameterCount = cpu_to_le16(params); 4906 pSMB->ParameterCount = cpu_to_le16(params);
4891 pSMB->TotalParameterCount = pSMB->ParameterCount; 4907 pSMB->TotalParameterCount = pSMB->ParameterCount;
4892 pSMB->Reserved4 = 0; 4908 pSMB->Reserved4 = 0;
4893 pSMB->hdr.smb_buf_length += byte_count; 4909 inc_rfc1001_len(pSMB, byte_count);
4894 parm_data->FileSize = cpu_to_le64(size); 4910 parm_data->FileSize = cpu_to_le64(size);
4895 pSMB->ByteCount = cpu_to_le16(byte_count); 4911 pSMB->ByteCount = cpu_to_le16(byte_count);
4896 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4912 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -4969,7 +4985,7 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
4969 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO); 4985 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
4970 } 4986 }
4971 pSMB->Reserved4 = 0; 4987 pSMB->Reserved4 = 0;
4972 pSMB->hdr.smb_buf_length += byte_count; 4988 inc_rfc1001_len(pSMB, byte_count);
4973 pSMB->ByteCount = cpu_to_le16(byte_count); 4989 pSMB->ByteCount = cpu_to_le16(byte_count);
4974 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); 4990 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
4975 if (rc) { 4991 if (rc) {
@@ -5037,7 +5053,7 @@ CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon,
5037 else 5053 else
5038 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO); 5054 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5039 pSMB->Reserved4 = 0; 5055 pSMB->Reserved4 = 0;
5040 pSMB->hdr.smb_buf_length += byte_count; 5056 inc_rfc1001_len(pSMB, byte_count);
5041 pSMB->ByteCount = cpu_to_le16(byte_count); 5057 pSMB->ByteCount = cpu_to_le16(byte_count);
5042 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); 5058 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5043 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); 5059 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
@@ -5096,7 +5112,7 @@ CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon,
5096 pSMB->Fid = fid; 5112 pSMB->Fid = fid;
5097 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO); 5113 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
5098 pSMB->Reserved4 = 0; 5114 pSMB->Reserved4 = 0;
5099 pSMB->hdr.smb_buf_length += byte_count; 5115 inc_rfc1001_len(pSMB, byte_count);
5100 pSMB->ByteCount = cpu_to_le16(byte_count); 5116 pSMB->ByteCount = cpu_to_le16(byte_count);
5101 *data_offset = delete_file ? 1 : 0; 5117 *data_offset = delete_file ? 1 : 0;
5102 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); 5118 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
@@ -5169,7 +5185,7 @@ SetTimesRetry:
5169 else 5185 else
5170 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO); 5186 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
5171 pSMB->Reserved4 = 0; 5187 pSMB->Reserved4 = 0;
5172 pSMB->hdr.smb_buf_length += byte_count; 5188 inc_rfc1001_len(pSMB, byte_count);
5173 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); 5189 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5174 pSMB->ByteCount = cpu_to_le16(byte_count); 5190 pSMB->ByteCount = cpu_to_le16(byte_count);
5175 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5191 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -5221,7 +5237,7 @@ SetAttrLgcyRetry:
5221 } 5237 }
5222 pSMB->attr = cpu_to_le16(dos_attrs); 5238 pSMB->attr = cpu_to_le16(dos_attrs);
5223 pSMB->BufferFormat = 0x04; 5239 pSMB->BufferFormat = 0x04;
5224 pSMB->hdr.smb_buf_length += name_len + 1; 5240 inc_rfc1001_len(pSMB, name_len + 1);
5225 pSMB->ByteCount = cpu_to_le16(name_len + 1); 5241 pSMB->ByteCount = cpu_to_le16(name_len + 1);
5226 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5242 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5227 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5243 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -5326,7 +5342,7 @@ CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon,
5326 pSMB->Fid = fid; 5342 pSMB->Fid = fid;
5327 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC); 5343 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5328 pSMB->Reserved4 = 0; 5344 pSMB->Reserved4 = 0;
5329 pSMB->hdr.smb_buf_length += byte_count; 5345 inc_rfc1001_len(pSMB, byte_count);
5330 pSMB->ByteCount = cpu_to_le16(byte_count); 5346 pSMB->ByteCount = cpu_to_le16(byte_count);
5331 5347
5332 cifs_fill_unix_set_info(data_offset, args); 5348 cifs_fill_unix_set_info(data_offset, args);
@@ -5402,7 +5418,7 @@ setPermsRetry:
5402 pSMB->TotalDataCount = pSMB->DataCount; 5418 pSMB->TotalDataCount = pSMB->DataCount;
5403 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC); 5419 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
5404 pSMB->Reserved4 = 0; 5420 pSMB->Reserved4 = 0;
5405 pSMB->hdr.smb_buf_length += byte_count; 5421 inc_rfc1001_len(pSMB, byte_count);
5406 5422
5407 cifs_fill_unix_set_info(data_offset, args); 5423 cifs_fill_unix_set_info(data_offset, args);
5408 5424
@@ -5418,79 +5434,6 @@ setPermsRetry:
5418 return rc; 5434 return rc;
5419} 5435}
5420 5436
5421int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
5422 const int notify_subdirs, const __u16 netfid,
5423 __u32 filter, struct file *pfile, int multishot,
5424 const struct nls_table *nls_codepage)
5425{
5426 int rc = 0;
5427 struct smb_com_transaction_change_notify_req *pSMB = NULL;
5428 struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
5429 struct dir_notify_req *dnotify_req;
5430 int bytes_returned;
5431
5432 cFYI(1, "In CIFSSMBNotify for file handle %d", (int)netfid);
5433 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
5434 (void **) &pSMBr);
5435 if (rc)
5436 return rc;
5437
5438 pSMB->TotalParameterCount = 0 ;
5439 pSMB->TotalDataCount = 0;
5440 pSMB->MaxParameterCount = cpu_to_le32(2);
5441 /* BB find exact data count max from sess structure BB */
5442 pSMB->MaxDataCount = 0; /* same in little endian or be */
5443/* BB VERIFY verify which is correct for above BB */
5444 pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
5445 MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
5446
5447 pSMB->MaxSetupCount = 4;
5448 pSMB->Reserved = 0;
5449 pSMB->ParameterOffset = 0;
5450 pSMB->DataCount = 0;
5451 pSMB->DataOffset = 0;
5452 pSMB->SetupCount = 4; /* single byte does not need le conversion */
5453 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
5454 pSMB->ParameterCount = pSMB->TotalParameterCount;
5455 if (notify_subdirs)
5456 pSMB->WatchTree = 1; /* one byte - no le conversion needed */
5457 pSMB->Reserved2 = 0;
5458 pSMB->CompletionFilter = cpu_to_le32(filter);
5459 pSMB->Fid = netfid; /* file handle always le */
5460 pSMB->ByteCount = 0;
5461
5462 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5463 (struct smb_hdr *)pSMBr, &bytes_returned,
5464 CIFS_ASYNC_OP);
5465 if (rc) {
5466 cFYI(1, "Error in Notify = %d", rc);
5467 } else {
5468 /* Add file to outstanding requests */
5469 /* BB change to kmem cache alloc */
5470 dnotify_req = kmalloc(
5471 sizeof(struct dir_notify_req),
5472 GFP_KERNEL);
5473 if (dnotify_req) {
5474 dnotify_req->Pid = pSMB->hdr.Pid;
5475 dnotify_req->PidHigh = pSMB->hdr.PidHigh;
5476 dnotify_req->Mid = pSMB->hdr.Mid;
5477 dnotify_req->Tid = pSMB->hdr.Tid;
5478 dnotify_req->Uid = pSMB->hdr.Uid;
5479 dnotify_req->netfid = netfid;
5480 dnotify_req->pfile = pfile;
5481 dnotify_req->filter = filter;
5482 dnotify_req->multishot = multishot;
5483 spin_lock(&GlobalMid_Lock);
5484 list_add_tail(&dnotify_req->lhead,
5485 &GlobalDnotifyReqList);
5486 spin_unlock(&GlobalMid_Lock);
5487 } else
5488 rc = -ENOMEM;
5489 }
5490 cifs_buf_release(pSMB);
5491 return rc;
5492}
5493
5494#ifdef CONFIG_CIFS_XATTR 5437#ifdef CONFIG_CIFS_XATTR
5495/* 5438/*
5496 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common 5439 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
@@ -5560,7 +5503,7 @@ QAllEAsRetry:
5560 pSMB->ParameterCount = pSMB->TotalParameterCount; 5503 pSMB->ParameterCount = pSMB->TotalParameterCount;
5561 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS); 5504 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
5562 pSMB->Reserved4 = 0; 5505 pSMB->Reserved4 = 0;
5563 pSMB->hdr.smb_buf_length += byte_count; 5506 inc_rfc1001_len(pSMB, byte_count);
5564 pSMB->ByteCount = cpu_to_le16(byte_count); 5507 pSMB->ByteCount = cpu_to_le16(byte_count);
5565 5508
5566 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5509 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
@@ -5576,7 +5519,7 @@ QAllEAsRetry:
5576 of these trans2 responses */ 5519 of these trans2 responses */
5577 5520
5578 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 5521 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
5579 if (rc || (pSMBr->ByteCount < 4)) { 5522 if (rc || get_bcc(&pSMBr->hdr) < 4) {
5580 rc = -EIO; /* bad smb */ 5523 rc = -EIO; /* bad smb */
5581 goto QAllEAsOut; 5524 goto QAllEAsOut;
5582 } 5525 }
@@ -5773,7 +5716,7 @@ SetEARetry:
5773 pSMB->ParameterCount = cpu_to_le16(params); 5716 pSMB->ParameterCount = cpu_to_le16(params);
5774 pSMB->TotalParameterCount = pSMB->ParameterCount; 5717 pSMB->TotalParameterCount = pSMB->ParameterCount;
5775 pSMB->Reserved4 = 0; 5718 pSMB->Reserved4 = 0;
5776 pSMB->hdr.smb_buf_length += byte_count; 5719 inc_rfc1001_len(pSMB, byte_count);
5777 pSMB->ByteCount = cpu_to_le16(byte_count); 5720 pSMB->ByteCount = cpu_to_le16(byte_count);
5778 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5721 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5779 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5722 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -5787,5 +5730,99 @@ SetEARetry:
5787 5730
5788 return rc; 5731 return rc;
5789} 5732}
5790
5791#endif 5733#endif
5734
5735#ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
5736/*
5737 * Years ago the kernel added a "dnotify" function for Samba server,
5738 * to allow network clients (such as Windows) to display updated
5739 * lists of files in directory listings automatically when
5740 * files are added by one user when another user has the
5741 * same directory open on their desktop. The Linux cifs kernel
5742 * client hooked into the kernel side of this interface for
5743 * the same reason, but ironically when the VFS moved from
5744 * "dnotify" to "inotify" it became harder to plug in Linux
5745 * network file system clients (the most obvious use case
5746 * for notify interfaces is when multiple users can update
5747 * the contents of the same directory - exactly what network
5748 * file systems can do) although the server (Samba) could
5749 * still use it. For the short term we leave the worker
5750 * function ifdeffed out (below) until inotify is fixed
5751 * in the VFS to make it easier to plug in network file
5752 * system clients. If inotify turns out to be permanently
5753 * incompatible for network fs clients, we could instead simply
5754 * expose this config flag by adding a future cifs (and smb2) notify ioctl.
5755 */
5756int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
5757 const int notify_subdirs, const __u16 netfid,
5758 __u32 filter, struct file *pfile, int multishot,
5759 const struct nls_table *nls_codepage)
5760{
5761 int rc = 0;
5762 struct smb_com_transaction_change_notify_req *pSMB = NULL;
5763 struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
5764 struct dir_notify_req *dnotify_req;
5765 int bytes_returned;
5766
5767 cFYI(1, "In CIFSSMBNotify for file handle %d", (int)netfid);
5768 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
5769 (void **) &pSMBr);
5770 if (rc)
5771 return rc;
5772
5773 pSMB->TotalParameterCount = 0 ;
5774 pSMB->TotalDataCount = 0;
5775 pSMB->MaxParameterCount = cpu_to_le32(2);
5776 /* BB find exact data count max from sess structure BB */
5777 pSMB->MaxDataCount = 0; /* same in little endian or be */
5778/* BB VERIFY verify which is correct for above BB */
5779 pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
5780 MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
5781
5782 pSMB->MaxSetupCount = 4;
5783 pSMB->Reserved = 0;
5784 pSMB->ParameterOffset = 0;
5785 pSMB->DataCount = 0;
5786 pSMB->DataOffset = 0;
5787 pSMB->SetupCount = 4; /* single byte does not need le conversion */
5788 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
5789 pSMB->ParameterCount = pSMB->TotalParameterCount;
5790 if (notify_subdirs)
5791 pSMB->WatchTree = 1; /* one byte - no le conversion needed */
5792 pSMB->Reserved2 = 0;
5793 pSMB->CompletionFilter = cpu_to_le32(filter);
5794 pSMB->Fid = netfid; /* file handle always le */
5795 pSMB->ByteCount = 0;
5796
5797 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5798 (struct smb_hdr *)pSMBr, &bytes_returned,
5799 CIFS_ASYNC_OP);
5800 if (rc) {
5801 cFYI(1, "Error in Notify = %d", rc);
5802 } else {
5803 /* Add file to outstanding requests */
5804 /* BB change to kmem cache alloc */
5805 dnotify_req = kmalloc(
5806 sizeof(struct dir_notify_req),
5807 GFP_KERNEL);
5808 if (dnotify_req) {
5809 dnotify_req->Pid = pSMB->hdr.Pid;
5810 dnotify_req->PidHigh = pSMB->hdr.PidHigh;
5811 dnotify_req->Mid = pSMB->hdr.Mid;
5812 dnotify_req->Tid = pSMB->hdr.Tid;
5813 dnotify_req->Uid = pSMB->hdr.Uid;
5814 dnotify_req->netfid = netfid;
5815 dnotify_req->pfile = pfile;
5816 dnotify_req->filter = filter;
5817 dnotify_req->multishot = multishot;
5818 spin_lock(&GlobalMid_Lock);
5819 list_add_tail(&dnotify_req->lhead,
5820 &GlobalDnotifyReqList);
5821 spin_unlock(&GlobalMid_Lock);
5822 } else
5823 rc = -ENOMEM;
5824 }
5825 cifs_buf_release(pSMB);
5826 return rc;
5827}
5828#endif /* was needed for dnotify, and will be needed for inotify when VFS fix */