aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve French <smfrench@austin.rr.com>2005-04-29 01:41:08 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-29 01:41:08 -0400
commit09d1db5c6131232f764046160c29118cd4e5e646 (patch)
tree198d0b03c0afa7974cd6dcea4e711351f4e056eb
parent966ca9234754ece58870075972ef103e354de075 (diff)
[PATCH] cifs: improve check for search entry going beyond end of SMB transact
Signed-off-by: Steve French (sfrench@us.ibm.com) Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--fs/cifs/README8
-rw-r--r--fs/cifs/cifssmb.c89
-rw-r--r--fs/cifs/connect.c62
-rw-r--r--fs/cifs/readdir.c11
4 files changed, 102 insertions, 68 deletions
diff --git a/fs/cifs/README b/fs/cifs/README
index 48c37a6e9c3f..bec7b3fc8a72 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -420,7 +420,7 @@ Misc /proc/fs/cifs Flags and Debug Info
420======================================= 420=======================================
421Informational pseudo-files: 421Informational pseudo-files:
422DebugData Displays information about active CIFS sessions 422DebugData Displays information about active CIFS sessions
423 and shares. 423 and shares, as well as the cifs.ko version.
424Stats Lists summary resource usage information as well as per 424Stats Lists summary resource usage information as well as per
425 share statistics, if CONFIG_CIFS_STATS in enabled 425 share statistics, if CONFIG_CIFS_STATS in enabled
426 in the kernel configuration. 426 in the kernel configuration.
@@ -477,7 +477,7 @@ and for more extensive tracing including the start of smb requests and responses
477Two other experimental features are under development and to test 477Two other experimental features are under development and to test
478require enabling CONFIG_CIFS_EXPERIMENTAL 478require enabling CONFIG_CIFS_EXPERIMENTAL
479 479
480 More efficient write operations and SMB buffer handling 480 More efficient write operations
481 481
482 DNOTIFY fcntl: needed for support of directory change 482 DNOTIFY fcntl: needed for support of directory change
483 notification and perhaps later for file leases) 483 notification and perhaps later for file leases)
@@ -495,8 +495,8 @@ returned success.
495 495
496Also note that "cat /proc/fs/cifs/DebugData" will display information about 496Also note that "cat /proc/fs/cifs/DebugData" will display information about
497the active sessions and the shares that are mounted. Note: NTLMv2 enablement 497the active sessions and the shares that are mounted. Note: NTLMv2 enablement
498will not work since they its implementation is not quite complete yet. 498will not work since its implementation is not quite complete yet. Do not alter
499Do not alter these configuration values unless you are doing specific testing. 499the ExtendedSecurity configuration value unless you are doing specific testing.
500Enabling extended security works to Windows 2000 Workstations and XP but not to 500Enabling extended security works to Windows 2000 Workstations and XP but not to
501Windows 2000 server or Samba since it does not usually send "raw NTLMSSP" 501Windows 2000 server or Samba since it does not usually send "raw NTLMSSP"
502(instead it sends NTLMSSP encapsulated in SPNEGO/GSSAPI, which support is not 502(instead it sends NTLMSSP encapsulated in SPNEGO/GSSAPI, which support is not
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index b102ddb977ca..834297f7b5e1 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -75,7 +75,8 @@ static void mark_open_files_invalid(struct cifsTconInfo * pTcon)
75 } 75 }
76 } 76 }
77 write_unlock(&GlobalSMBSeslock); 77 write_unlock(&GlobalSMBSeslock);
78 /* BB Add call to invalidate_inodes(sb) for all superblocks mounted to this tcon */ 78 /* BB Add call to invalidate_inodes(sb) for all superblocks mounted
79 to this tcon */
79} 80}
80 81
81/* If the return code is zero, this function must fill in request_buf pointer */ 82/* If the return code is zero, this function must fill in request_buf pointer */
@@ -92,8 +93,8 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
92 if((tcon->ses) && (tcon->ses->server)){ 93 if((tcon->ses) && (tcon->ses->server)){
93 struct nls_table *nls_codepage; 94 struct nls_table *nls_codepage;
94 /* Give Demultiplex thread up to 10 seconds to 95 /* Give Demultiplex thread up to 10 seconds to
95 reconnect, should be greater than cifs socket 96 reconnect, should be greater than cifs socket
96 timeout which is 7 seconds */ 97 timeout which is 7 seconds */
97 while(tcon->ses->server->tcpStatus == CifsNeedReconnect) { 98 while(tcon->ses->server->tcpStatus == CifsNeedReconnect) {
98 wait_event_interruptible_timeout(tcon->ses->server->response_q, 99 wait_event_interruptible_timeout(tcon->ses->server->response_q,
99 (tcon->ses->server->tcpStatus == CifsGood), 10 * HZ); 100 (tcon->ses->server->tcpStatus == CifsGood), 10 * HZ);
@@ -103,8 +104,9 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
103 (tcon->ses->status == CifsExiting)) { 104 (tcon->ses->status == CifsExiting)) {
104 cFYI(1,("gave up waiting on reconnect in smb_init")); 105 cFYI(1,("gave up waiting on reconnect in smb_init"));
105 return -EHOSTDOWN; 106 return -EHOSTDOWN;
106 } /* else "hard" mount - keep retrying until 107 } /* else "hard" mount - keep retrying
107 process is killed or server comes back up */ 108 until process is killed or server
109 comes back on-line */
108 } else /* TCP session is reestablished now */ 110 } else /* TCP session is reestablished now */
109 break; 111 break;
110 112
@@ -115,23 +117,24 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
115 simultaneously reconnect the same SMB session */ 117 simultaneously reconnect the same SMB session */
116 down(&tcon->ses->sesSem); 118 down(&tcon->ses->sesSem);
117 if(tcon->ses->status == CifsNeedReconnect) 119 if(tcon->ses->status == CifsNeedReconnect)
118 rc = cifs_setup_session(0, tcon->ses, nls_codepage); 120 rc = cifs_setup_session(0, tcon->ses,
121 nls_codepage);
119 if(!rc && (tcon->tidStatus == CifsNeedReconnect)) { 122 if(!rc && (tcon->tidStatus == CifsNeedReconnect)) {
120 mark_open_files_invalid(tcon); 123 mark_open_files_invalid(tcon);
121 rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon, 124 rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon
122 nls_codepage); 125 , nls_codepage);
123 up(&tcon->ses->sesSem); 126 up(&tcon->ses->sesSem);
124 if(rc == 0) 127 if(rc == 0)
125 atomic_inc(&tconInfoReconnectCount); 128 atomic_inc(&tconInfoReconnectCount);
126 129
127 cFYI(1, ("reconnect tcon rc = %d", rc)); 130 cFYI(1, ("reconnect tcon rc = %d", rc));
128 /* Removed call to reopen open files here - 131 /* Removed call to reopen open files here -
129 it is safer (and faster) to reopen files 132 it is safer (and faster) to reopen files
130 one at a time as needed in read and write */ 133 one at a time as needed in read and write */
131 134
132 /* Check if handle based operation so we 135 /* Check if handle based operation so we
133 know whether we can continue or not without 136 know whether we can continue or not without
134 returning to caller to reset file handle */ 137 returning to caller to reset file handle */
135 switch(smb_command) { 138 switch(smb_command) {
136 case SMB_COM_READ_ANDX: 139 case SMB_COM_READ_ANDX:
137 case SMB_COM_WRITE_ANDX: 140 case SMB_COM_WRITE_ANDX:
@@ -184,20 +187,22 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
184 if(tcon) { 187 if(tcon) {
185 if((tcon->ses) && (tcon->ses->server)){ 188 if((tcon->ses) && (tcon->ses->server)){
186 struct nls_table *nls_codepage; 189 struct nls_table *nls_codepage;
187 /* Give Demultiplex thread up to 10 seconds to 190 /* Give Demultiplex thread up to 10 seconds to
188 reconnect, should be greater than cifs socket 191 reconnect, should be greater than cifs socket
189 timeout which is 7 seconds */ 192 timeout which is 7 seconds */
190 while(tcon->ses->server->tcpStatus == CifsNeedReconnect) { 193 while(tcon->ses->server->tcpStatus == CifsNeedReconnect) {
191 wait_event_interruptible_timeout(tcon->ses->server->response_q, 194 wait_event_interruptible_timeout(tcon->ses->server->response_q,
192 (tcon->ses->server->tcpStatus == CifsGood), 10 * HZ); 195 (tcon->ses->server->tcpStatus == CifsGood), 10 * HZ);
193 if(tcon->ses->server->tcpStatus == CifsNeedReconnect) { 196 if(tcon->ses->server->tcpStatus ==
197 CifsNeedReconnect) {
194 /* on "soft" mounts we wait once */ 198 /* on "soft" mounts we wait once */
195 if((tcon->retry == FALSE) || 199 if((tcon->retry == FALSE) ||
196 (tcon->ses->status == CifsExiting)) { 200 (tcon->ses->status == CifsExiting)) {
197 cFYI(1,("gave up waiting on reconnect in smb_init")); 201 cFYI(1,("gave up waiting on reconnect in smb_init"));
198 return -EHOSTDOWN; 202 return -EHOSTDOWN;
199 } /* else "hard" mount - keep retrying until 203 } /* else "hard" mount - keep retrying
200 process is killed or server comes back up */ 204 until process is killed or server
205 comes on-line */
201 } else /* TCP session is reestablished now */ 206 } else /* TCP session is reestablished now */
202 break; 207 break;
203 208
@@ -208,23 +213,24 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
208 simultaneously reconnect the same SMB session */ 213 simultaneously reconnect the same SMB session */
209 down(&tcon->ses->sesSem); 214 down(&tcon->ses->sesSem);
210 if(tcon->ses->status == CifsNeedReconnect) 215 if(tcon->ses->status == CifsNeedReconnect)
211 rc = cifs_setup_session(0, tcon->ses, nls_codepage); 216 rc = cifs_setup_session(0, tcon->ses,
217 nls_codepage);
212 if(!rc && (tcon->tidStatus == CifsNeedReconnect)) { 218 if(!rc && (tcon->tidStatus == CifsNeedReconnect)) {
213 mark_open_files_invalid(tcon); 219 mark_open_files_invalid(tcon);
214 rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon, 220 rc = CIFSTCon(0, tcon->ses, tcon->treeName,
215 nls_codepage); 221 tcon, nls_codepage);
216 up(&tcon->ses->sesSem); 222 up(&tcon->ses->sesSem);
217 if(rc == 0) 223 if(rc == 0)
218 atomic_inc(&tconInfoReconnectCount); 224 atomic_inc(&tconInfoReconnectCount);
219 225
220 cFYI(1, ("reconnect tcon rc = %d", rc)); 226 cFYI(1, ("reconnect tcon rc = %d", rc));
221 /* Removed call to reopen open files here - 227 /* Removed call to reopen open files here -
222 it is safer (and faster) to reopen files 228 it is safer (and faster) to reopen files
223 one at a time as needed in read and write */ 229 one at a time as needed in read and write */
224 230
225 /* Check if handle based operation so we 231 /* Check if handle based operation so we
226 know whether we can continue or not without 232 know whether we can continue or not without
227 returning to caller to reset file handle */ 233 returning to caller to reset file handle */
228 switch(smb_command) { 234 switch(smb_command) {
229 case SMB_COM_READ_ANDX: 235 case SMB_COM_READ_ANDX:
230 case SMB_COM_WRITE_ANDX: 236 case SMB_COM_WRITE_ANDX:
@@ -286,7 +292,8 @@ static int validate_t2(struct smb_t2_rsp * pSMB)
286 if(total_size < 512) { 292 if(total_size < 512) {
287 total_size+=le16_to_cpu(pSMB->t2_rsp.DataCount); 293 total_size+=le16_to_cpu(pSMB->t2_rsp.DataCount);
288 /* BCC le converted in SendReceive */ 294 /* BCC le converted in SendReceive */
289 pBCC = (pSMB->hdr.WordCount * 2) + sizeof(struct smb_hdr) + 295 pBCC = (pSMB->hdr.WordCount * 2) +
296 sizeof(struct smb_hdr) +
290 (char *)pSMB; 297 (char *)pSMB;
291 if((total_size <= (*(u16 *)pBCC)) && 298 if((total_size <= (*(u16 *)pBCC)) &&
292 (total_size < 299 (total_size <
@@ -337,8 +344,10 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
337 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 344 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
338 if (rc == 0) { 345 if (rc == 0) {
339 server->secMode = pSMBr->SecurityMode; 346 server->secMode = pSMBr->SecurityMode;
340 server->secType = NTLM; /* BB override default for NTLMv2 or krb*/ 347 server->secType = NTLM; /* BB override default for
341 /* one byte - no need to convert this or EncryptionKeyLen from le,*/ 348 NTLMv2 or kerberos v5 */
349 /* one byte - no need to convert this or EncryptionKeyLen
350 from little endian */
342 server->maxReq = le16_to_cpu(pSMBr->MaxMpxCount); 351 server->maxReq = le16_to_cpu(pSMBr->MaxMpxCount);
343 /* probably no need to store and check maxvcs */ 352 /* probably no need to store and check maxvcs */
344 server->maxBuf = 353 server->maxBuf =
@@ -374,7 +383,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
374 pSMBr->u.extended_response. 383 pSMBr->u.extended_response.
375 GUID, 16) != 0) { 384 GUID, 16) != 0) {
376 cFYI(1, 385 cFYI(1,
377 ("UID of server does not match previous connection to same ip address")); 386 ("UID of server does not match previous connection to same ip address"));
378 memcpy(server-> 387 memcpy(server->
379 server_GUID, 388 server_GUID,
380 pSMBr->u. 389 pSMBr->u.
@@ -454,7 +463,8 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
454 up(&tcon->tconSem); 463 up(&tcon->tconSem);
455 return -EIO; 464 return -EIO;
456 } 465 }
457 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon, (void **)&smb_buffer); 466 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
467 (void **)&smb_buffer);
458 if (rc) { 468 if (rc) {
459 up(&tcon->tconSem); 469 up(&tcon->tconSem);
460 return rc; 470 return rc;
@@ -559,7 +569,7 @@ DelFileRetry:
559 PATH_MAX, nls_codepage, remap); 569 PATH_MAX, nls_codepage, remap);
560 name_len++; /* trailing null */ 570 name_len++; /* trailing null */
561 name_len *= 2; 571 name_len *= 2;
562 } else { /* BB improve the check for buffer overruns BB */ 572 } else { /* BB improve check for buffer overruns BB */
563 name_len = strnlen(fileName, PATH_MAX); 573 name_len = strnlen(fileName, PATH_MAX);
564 name_len++; /* trailing null */ 574 name_len++; /* trailing null */
565 strncpy(pSMB->fileName, fileName, name_len); 575 strncpy(pSMB->fileName, fileName, name_len);
@@ -609,7 +619,7 @@ RmDirRetry:
609 PATH_MAX, nls_codepage, remap); 619 PATH_MAX, nls_codepage, remap);
610 name_len++; /* trailing null */ 620 name_len++; /* trailing null */
611 name_len *= 2; 621 name_len *= 2;
612 } else { /* BB improve the check for buffer overruns BB */ 622 } else { /* BB improve check for buffer overruns BB */
613 name_len = strnlen(dirName, PATH_MAX); 623 name_len = strnlen(dirName, PATH_MAX);
614 name_len++; /* trailing null */ 624 name_len++; /* trailing null */
615 strncpy(pSMB->DirName, dirName, name_len); 625 strncpy(pSMB->DirName, dirName, name_len);
@@ -657,7 +667,7 @@ MkDirRetry:
657 PATH_MAX, nls_codepage, remap); 667 PATH_MAX, nls_codepage, remap);
658 name_len++; /* trailing null */ 668 name_len++; /* trailing null */
659 name_len *= 2; 669 name_len *= 2;
660 } else { /* BB improve the check for buffer overruns BB */ 670 } else { /* BB improve check for buffer overruns BB */
661 name_len = strnlen(name, PATH_MAX); 671 name_len = strnlen(name, PATH_MAX);
662 name_len++; /* trailing null */ 672 name_len++; /* trailing null */
663 strncpy(pSMB->DirName, name, name_len); 673 strncpy(pSMB->DirName, name, name_len);
@@ -712,7 +722,7 @@ openRetry:
712 name_len++; /* trailing null */ 722 name_len++; /* trailing null */
713 name_len *= 2; 723 name_len *= 2;
714 pSMB->NameLength = cpu_to_le16(name_len); 724 pSMB->NameLength = cpu_to_le16(name_len);
715 } else { /* BB improve the check for buffer overruns BB */ 725 } else { /* BB improve check for buffer overruns BB */
716 count = 0; /* no pad */ 726 count = 0; /* no pad */
717 name_len = strnlen(fileName, PATH_MAX); 727 name_len = strnlen(fileName, PATH_MAX);
718 name_len++; /* trailing null */ 728 name_len++; /* trailing null */
@@ -741,7 +751,8 @@ openRetry:
741 pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL); 751 pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
742 pSMB->CreateDisposition = cpu_to_le32(openDisposition); 752 pSMB->CreateDisposition = cpu_to_le32(openDisposition);
743 pSMB->CreateOptions = cpu_to_le32(create_options); 753 pSMB->CreateOptions = cpu_to_le32(create_options);
744 pSMB->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION); /* BB ??*/ 754 /* BB Expirement with various impersonation levels and verify */
755 pSMB->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
745 pSMB->SecurityFlags = 756 pSMB->SecurityFlags =
746 SECURITY_CONTEXT_TRACKING | SECURITY_EFFECTIVE_ONLY; 757 SECURITY_CONTEXT_TRACKING | SECURITY_EFFECTIVE_ONLY;
747 758
@@ -755,7 +766,7 @@ openRetry:
755 if (rc) { 766 if (rc) {
756 cFYI(1, ("Error in Open = %d", rc)); 767 cFYI(1, ("Error in Open = %d", rc));
757 } else { 768 } else {
758 *pOplock = pSMBr->OplockLevel; /* one byte no need to le_to_cpu */ 769 *pOplock = pSMBr->OplockLevel; /* 1 byte no need to le_to_cpu */
759 *netfid = pSMBr->Fid; /* cifs fid stays in le */ 770 *netfid = pSMBr->Fid; /* cifs fid stays in le */
760 /* Let caller know file was created so we can set the mode. */ 771 /* Let caller know file was created so we can set the mode. */
761 /* Do we care about the CreateAction in any other cases? */ 772 /* Do we care about the CreateAction in any other cases? */
@@ -2504,7 +2515,9 @@ findFirstRetry:
2504 psrch_inf->srch_entries_start = 2515 psrch_inf->srch_entries_start =
2505 (char *) &pSMBr->hdr.Protocol + 2516 (char *) &pSMBr->hdr.Protocol +
2506 le16_to_cpu(pSMBr->t2.DataOffset); 2517 le16_to_cpu(pSMBr->t2.DataOffset);
2507 2518/* if(le16_to_cpu(pSMBr->t2.DataCount) != le16_to_cpu(pSMBr->t2.TotalDataCount)) {
2519 cERROR(1,("DC: %d TDC: %d",pSMBr->t2.DataCount,pSMBr->t2.TotalDataCount));
2520} */ /* BB removeme BB */
2508 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol + 2521 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
2509 le16_to_cpu(pSMBr->t2.ParameterOffset)); 2522 le16_to_cpu(pSMBr->t2.ParameterOffset));
2510 2523
@@ -2516,7 +2529,7 @@ findFirstRetry:
2516 psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount); 2529 psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount);
2517 psrch_inf->index_of_last_entry = 2530 psrch_inf->index_of_last_entry =
2518 psrch_inf->entries_in_buffer; 2531 psrch_inf->entries_in_buffer;
2519/*cFYI(1,("entries in buf %d index_of_last %d",psrch_inf->entries_in_buffer,psrch_inf->index_of_last_entry)); */ 2532/*cFYI(1,("entries in buf %d index_of_last %d",psrch_inf->entries_in_buffer,psrch_inf->index_of_last_entry)); */ /* BB removeme BB */
2520 *pnetfid = parms->SearchHandle; 2533 *pnetfid = parms->SearchHandle;
2521 } else { 2534 } else {
2522 cifs_buf_release(pSMB); 2535 cifs_buf_release(pSMB);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 8a8aa785e7b7..d5d49b584db4 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -157,9 +157,10 @@ cifs_reconnect(struct TCP_Server_Info *server)
157 qhead); 157 qhead);
158 if(mid_entry) { 158 if(mid_entry) {
159 if(mid_entry->midState == MID_REQUEST_SUBMITTED) { 159 if(mid_entry->midState == MID_REQUEST_SUBMITTED) {
160 /* Mark other intransit requests as needing retry so 160 /* Mark other intransit requests as needing
161 we do not immediately mark the session bad again 161 retry so we do not immediately mark the
162 (ie after we reconnect below) as they timeout too */ 162 session bad again (ie after we reconnect
163 below) as they timeout too */
163 mid_entry->midState = MID_RETRY_NEEDED; 164 mid_entry->midState = MID_RETRY_NEEDED;
164 } 165 }
165 } 166 }
@@ -278,9 +279,10 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
278 } else if (length <= 0) { 279 } else if (length <= 0) {
279 if(server->tcpStatus == CifsNew) { 280 if(server->tcpStatus == CifsNew) {
280 cFYI(1,("tcp session abended prematurely (after SMBnegprot)")); 281 cFYI(1,("tcp session abended prematurely (after SMBnegprot)"));
281 /* some servers kill tcp session rather than returning 282 /* some servers kill the TCP session rather than
282 smb negprot error in which case reconnecting here is 283 returning an SMB negprot error, in which
283 not going to help - return error to mount */ 284 case reconnecting here is not going to help,
285 and so simply return error to mount */
284 break; 286 break;
285 } 287 }
286 if(length == -EINTR) { 288 if(length == -EINTR) {
@@ -296,15 +298,19 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
296 pdu_length = ntohl(smb_buffer->smb_buf_length); 298 pdu_length = ntohl(smb_buffer->smb_buf_length);
297 /* Only read pdu_length after below checks for too short (due 299 /* Only read pdu_length after below checks for too short (due
298 to e.g. int overflow) and too long ie beyond end of buf */ 300 to e.g. int overflow) and too long ie beyond end of buf */
299 cFYI(1,("rfc1002 length(big endian)0x%x)", pdu_length+4)); 301 cFYI(1,("rfc1002 length(big endian)0x%x)",
302 pdu_length+4));
300 303
301 temp = (char *) smb_buffer; 304 temp = (char *) smb_buffer;
302 if (temp[0] == (char) RFC1002_SESSION_KEEP_ALIVE) { 305 if (temp[0] == (char) RFC1002_SESSION_KEEP_ALIVE) {
303 cFYI(0,("Received 4 byte keep alive packet")); 306 cFYI(0,("Received 4 byte keep alive packet"));
304 } else if (temp[0] == (char) RFC1002_POSITIVE_SESSION_RESPONSE) { 307 } else if (temp[0] ==
308 (char) RFC1002_POSITIVE_SESSION_RESPONSE) {
305 cFYI(1,("Good RFC 1002 session rsp")); 309 cFYI(1,("Good RFC 1002 session rsp"));
306 } else if (temp[0] == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) { 310 } else if (temp[0] ==
307 /* we get this from Windows 98 instead of error on SMB negprot response */ 311 (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
312 /* we get this from Windows 98 instead of
313 an error on SMB negprot response */
308 cFYI(1,("Negative RFC 1002 Session Response Error 0x%x)",temp[4])); 314 cFYI(1,("Negative RFC 1002 Session Response Error 0x%x)",temp[4]));
309 if(server->tcpStatus == CifsNew) { 315 if(server->tcpStatus == CifsNew) {
310 /* if nack on negprot (rather than 316 /* if nack on negprot (rather than
@@ -320,7 +326,8 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
320 connected to port 139 (the NACK is 326 connected to port 139 (the NACK is
321 since we do not begin with RFC1001 327 since we do not begin with RFC1001
322 session initialize frame) */ 328 session initialize frame) */
323 server->addr.sockAddr.sin_port = htons(CIFS_PORT); 329 server->addr.sockAddr.sin_port =
330 htons(CIFS_PORT);
324 cifs_reconnect(server); 331 cifs_reconnect(server);
325 csocket = server->ssocket; 332 csocket = server->ssocket;
326 wake_up(&server->response_q); 333 wake_up(&server->response_q);
@@ -333,8 +340,9 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
333 csocket = server->ssocket; 340 csocket = server->ssocket;
334 continue; 341 continue;
335 } else { 342 } else {
336 if((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) 343 if((pdu_length > CIFSMaxBufSize +
337 || (pdu_length < sizeof (struct smb_hdr) - 1 - 4)) { 344 MAX_CIFS_HDR_SIZE - 4) ||
345 (pdu_length < sizeof (struct smb_hdr) - 1 - 4)) {
338 cERROR(1, 346 cERROR(1,
339 ("Invalid size SMB length %d and pdu_length %d", 347 ("Invalid size SMB length %d and pdu_length %d",
340 length, pdu_length+4)); 348 length, pdu_length+4));
@@ -377,6 +385,8 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
377 continue; 385 continue;
378 } 386 }
379 387
388 /* BB FIXME - add checkTrans2SMBSecondary() */
389
380 task_to_wake = NULL; 390 task_to_wake = NULL;
381 spin_lock(&GlobalMid_Lock); 391 spin_lock(&GlobalMid_Lock);
382 list_for_each(tmp, &server->pending_mid_q) { 392 list_for_each(tmp, &server->pending_mid_q) {
@@ -408,7 +418,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
408 bigbuf = NULL; 418 bigbuf = NULL;
409 else 419 else
410 smallbuf = NULL; 420 smallbuf = NULL;
411 smb_buffer = NULL; /* will be freed by users thread after he is done */ 421 smb_buffer = NULL; /* will be freed by users thread after he is done */
412 wake_up_process(task_to_wake); 422 wake_up_process(task_to_wake);
413 } else if (is_valid_oplock_break(smb_buffer) == FALSE) { 423 } else if (is_valid_oplock_break(smb_buffer) == FALSE) {
414 cERROR(1, ("No task to wake, unknown frame rcvd!")); 424 cERROR(1, ("No task to wake, unknown frame rcvd!"));
@@ -432,7 +442,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
432 spin_unlock(&GlobalMid_Lock); 442 spin_unlock(&GlobalMid_Lock);
433 /* Although there should not be any requests blocked on 443 /* Although there should not be any requests blocked on
434 this queue it can not hurt to be paranoid and try to wake up requests 444 this queue it can not hurt to be paranoid and try to wake up requests
435 that may haven been blocked when more than 50 at time were on the wire 445 that may haven been blocked when more than 50 at time were on the wire
436 to the same server - they now will see the session is in exit state 446 to the same server - they now will see the session is in exit state
437 and get out of SendReceive. */ 447 and get out of SendReceive. */
438 wake_up_all(&server->request_q); 448 wake_up_all(&server->request_q);
@@ -451,7 +461,8 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
451 461
452 read_lock(&GlobalSMBSeslock); 462 read_lock(&GlobalSMBSeslock);
453 if (list_empty(&server->pending_mid_q)) { 463 if (list_empty(&server->pending_mid_q)) {
454 /* loop through server session structures attached to this and mark them dead */ 464 /* loop through server session structures attached to this and
465 mark them dead */
455 list_for_each(tmp, &GlobalSMBSessionList) { 466 list_for_each(tmp, &GlobalSMBSessionList) {
456 ses = 467 ses =
457 list_entry(tmp, struct cifsSesInfo, 468 list_entry(tmp, struct cifsSesInfo,
@@ -468,7 +479,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
468 mid_entry = list_entry(tmp, struct mid_q_entry, qhead); 479 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
469 if (mid_entry->midState == MID_REQUEST_SUBMITTED) { 480 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
470 cFYI(1, 481 cFYI(1,
471 (" Clearing Mid 0x%x - waking up ",mid_entry->mid)); 482 ("Clearing Mid 0x%x - waking up ",mid_entry->mid));
472 task_to_wake = mid_entry->tsk; 483 task_to_wake = mid_entry->tsk;
473 if(task_to_wake) { 484 if(task_to_wake) {
474 wake_up_process(task_to_wake); 485 wake_up_process(task_to_wake);
@@ -521,7 +532,8 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
521 /* does not have to be a perfect mapping since the field is 532 /* does not have to be a perfect mapping since the field is
522 informational, only used for servers that do not support 533 informational, only used for servers that do not support
523 port 445 and it can be overridden at mount time */ 534 port 445 and it can be overridden at mount time */
524 vol->source_rfc1001_name[i] = toupper(system_utsname.nodename[i]); 535 vol->source_rfc1001_name[i] =
536 toupper(system_utsname.nodename[i]);
525 } 537 }
526 vol->source_rfc1001_name[15] = 0; 538 vol->source_rfc1001_name[15] = 0;
527 539
@@ -596,14 +608,17 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
596 /* NB: password legally can have multiple commas and 608 /* NB: password legally can have multiple commas and
597 the only illegal character in a password is null */ 609 the only illegal character in a password is null */
598 610
599 if ((value[temp_len] == 0) && (value[temp_len+1] == separator[0])) { 611 if ((value[temp_len] == 0) &&
612 (value[temp_len+1] == separator[0])) {
600 /* reinsert comma */ 613 /* reinsert comma */
601 value[temp_len] = separator[0]; 614 value[temp_len] = separator[0];
602 temp_len+=2; /* move after the second comma */ 615 temp_len+=2; /* move after the second comma */
603 while(value[temp_len] != 0) { 616 while(value[temp_len] != 0) {
604 if (value[temp_len] == separator[0]) { 617 if (value[temp_len] == separator[0]) {
605 if (value[temp_len+1] == separator[0]) { 618 if (value[temp_len+1] ==
606 temp_len++; /* skip second comma */ 619 separator[0]) {
620 /* skip second comma */
621 temp_len++;
607 } else { 622 } else {
608 /* single comma indicating start 623 /* single comma indicating start
609 of next parm */ 624 of next parm */
@@ -629,14 +644,15 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
629 } 644 }
630 for(i=0,j=0;i<temp_len;i++,j++) { 645 for(i=0,j=0;i<temp_len;i++,j++) {
631 vol->password[j] = value[i]; 646 vol->password[j] = value[i];
632 if(value[i] == separator[0] && value[i+1] == separator[0]) { 647 if(value[i] == separator[0]
648 && value[i+1] == separator[0]) {
633 /* skip second comma */ 649 /* skip second comma */
634 i++; 650 i++;
635 } 651 }
636 } 652 }
637 vol->password[j] = 0; 653 vol->password[j] = 0;
638 } else { 654 } else {
639 vol->password = kcalloc(1, temp_len + 1, GFP_KERNEL); 655 vol->password = kcalloc(1, temp_len+1, GFP_KERNEL);
640 if(vol->password == NULL) { 656 if(vol->password == NULL) {
641 printk("CIFS: no memory for pass\n"); 657 printk("CIFS: no memory for pass\n");
642 return 1; 658 return 1;
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 39170cffcad8..22557716f9af 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -409,10 +409,15 @@ static char *nxt_dir_entry(char *old_entry, char *end_of_smb)
409 cFYI(1,("new entry %p old entry %p",new_entry,old_entry)); 409 cFYI(1,("new entry %p old entry %p",new_entry,old_entry));
410 /* validate that new_entry is not past end of SMB */ 410 /* validate that new_entry is not past end of SMB */
411 if(new_entry >= end_of_smb) { 411 if(new_entry >= end_of_smb) {
412 cFYI(1,("search entry %p began after end of SMB %p old entry %p", 412 cERROR(1,
413 new_entry,end_of_smb,old_entry)); 413 ("search entry %p began after end of SMB %p old entry %p",
414 new_entry, end_of_smb, old_entry));
414 return NULL; 415 return NULL;
415 } else 416 } else if (new_entry + sizeof(FILE_DIRECTORY_INFO) > end_of_smb) {
417 cERROR(1,("search entry %p extends after end of SMB %p",
418 new_entry, end_of_smb));
419 return NULL;
420 } else
416 return new_entry; 421 return new_entry;
417 422
418} 423}