1 From: Steve French <sfrench@us.ibm.com>
2 Date: Tue, 13 Nov 2007 22:41:37 +0000 (+0000)
3 Subject: [CIFS] Fix buffer overflow if server sends corrupt response to small
4 Patch-mainline: 2.6.24?
5 X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fsfrench%2Fcifs-2.6.git;a=commitdiff_plain;h=133672efbc1085f9af990bdc145e1822ea93bcf3
6 References: CVE-2007-5904, 342448
8 [CIFS] Fix buffer overflow if server sends corrupt response to small
11 In SendReceive() function in transport.c - it memcpy's
12 message payload into a buffer passed via out_buf param. The function
13 assumes that all buffers are of size (CIFSMaxBufSize +
14 MAX_CIFS_HDR_SIZE) , unfortunately it is also called with smaller
15 (MAX_CIFS_SMALL_BUFFER_SIZE) buffers. There are eight callers
16 (SMB worker functions) which are primarily affected by this change:
18 TreeDisconnect, uLogoff, Close, findClose, SetFileSize, SetFileTimes,
21 CC: Dave Kleikamp <shaggy@austin.ibm.com>
22 CC: Przemyslaw Wegrzyn <czajnik@czajsoft.pl>
23 Acked-by: Jeff Layton <jlayton@redhat.com>
24 Signed-off-by: Steve French <sfrench@us.ibm.com>
25 Acked-by: Jeff Mahoney <jeffm@suse.com>
26 Signed-off-by: Oliver Pinter <oliver.pntr@gmail.com>
30 fs/cifs/cifsglob.h | 11 +++++
31 fs/cifs/cifsproto.h | 4 +-
32 fs/cifs/cifssmb.c | 96 +++++++++++++++++++---------------------------------
33 fs/cifs/connect.c | 9 ++--
34 fs/cifs/file.c | 14 +++----
36 fs/cifs/transport.c | 88 ++++++++++++++++++++++++++++++++++++-----------
37 7 files changed, 132 insertions(+), 93 deletions(-)
39 --- a/fs/cifs/cifsglob.h 2007-11-16 17:54:37.000000000 -0500
40 +++ b/fs/cifs/cifsglob.h 2007-11-16 17:58:12.000000000 -0500
41 @@ -442,6 +442,17 @@ struct dir_notify_req {
42 #define CIFS_LARGE_BUFFER 2
43 #define CIFS_IOVEC 4 /* array of response buffers */
45 +/* Type of Request to SendReceive2 */
46 +#define CIFS_STD_OP 0 /* normal request timeout */
47 +#define CIFS_LONG_OP 1 /* long op (up to 45 sec, oplock time) */
48 +#define CIFS_VLONG_OP 2 /* sloow op - can take up to 180 seconds */
49 +#define CIFS_BLOCKING_OP 4 /* operation can block */
50 +#define CIFS_ASYNC_OP 8 /* do not wait for response */
51 +#define CIFS_TIMEOUT_MASK 0x00F /* only one of 5 above set in req */
52 +#define CIFS_LOG_ERROR 0x010 /* log NT STATUS if non-zero */
53 +#define CIFS_LARGE_BUF_OP 0x020 /* large request buffer */
54 +#define CIFS_NO_RESP 0x040 /* no response buffer required */
56 /* Security Flags: indicate type of session setup needed */
57 #define CIFSSEC_MAY_SIGN 0x00001
58 #define CIFSSEC_MAY_NTLM 0x00002
59 --- a/fs/cifs/cifsproto.h 2007-11-16 17:54:37.000000000 -0500
60 +++ b/fs/cifs/cifsproto.h 2007-11-16 17:58:12.000000000 -0500
61 @@ -48,9 +48,11 @@ extern int SendReceive(const unsigned in
62 struct smb_hdr * /* input */ ,
63 struct smb_hdr * /* out */ ,
64 int * /* bytes returned */ , const int long_op);
65 +extern int SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses,
66 + struct smb_hdr *in_buf, int flags);
67 extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *,
68 struct kvec *, int /* nvec to send */,
69 - int * /* type of buf returned */ , const int long_op);
70 + int * /* type of buf returned */ , const int flags);
71 extern int SendReceiveBlockingLock(const unsigned int /* xid */ ,
72 struct cifsTconInfo *,
73 struct smb_hdr * /* input */ ,
74 --- a/fs/cifs/cifssmb.c 2007-11-16 17:54:37.000000000 -0500
75 +++ b/fs/cifs/cifssmb.c 2007-11-16 17:58:12.000000000 -0500
76 @@ -660,9 +660,7 @@ int
77 CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
79 struct smb_hdr *smb_buffer;
80 - struct smb_hdr *smb_buffer_response; /* BB removeme BB */
84 cFYI(1, ("In tree disconnect"));
86 @@ -699,16 +697,12 @@ CIFSSMBTDis(const int xid, struct cifsTc
91 - smb_buffer_response = smb_buffer; /* BB removeme BB */
93 - rc = SendReceive(xid, tcon->ses, smb_buffer, smb_buffer_response,
96 + rc = SendReceiveNoRsp(xid, tcon->ses, smb_buffer, 0);
98 cFYI(1, ("Tree disconnect failed %d", rc));
101 - cifs_small_buf_release(smb_buffer);
104 /* No need to return error on this operation if tid invalidated and
105 @@ -722,10 +716,8 @@ CIFSSMBTDis(const int xid, struct cifsTc
107 CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
109 - struct smb_hdr *smb_buffer_response;
110 LOGOFF_ANDX_REQ *pSMB;
114 cFYI(1, ("In SMBLogoff for session disconnect"));
116 @@ -744,8 +736,6 @@ CIFSSMBLogoff(const int xid, struct cifs
120 - smb_buffer_response = (struct smb_hdr *)pSMB; /* BB removeme BB */
123 pSMB->hdr.Mid = GetNextMid(ses->server);
125 @@ -757,8 +747,7 @@ CIFSSMBLogoff(const int xid, struct cifs
126 pSMB->hdr.Uid = ses->Suid;
128 pSMB->AndXCommand = 0xFF;
129 - rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
130 - smb_buffer_response, &length, 0);
131 + rc = SendReceiveNoRsp(xid, ses, (struct smb_hdr *) pSMB, 0);
133 atomic_dec(&ses->server->socketUseCount);
134 if (atomic_read(&ses->server->socketUseCount) == 0) {
135 @@ -769,7 +758,6 @@ CIFSSMBLogoff(const int xid, struct cifs
139 - cifs_small_buf_release(pSMB);
141 /* if session dead then we do not need to do ulogoff,
142 since server closed smb session, no sense reporting
143 @@ -1143,7 +1131,7 @@ OldOpenRetry:
144 pSMB->ByteCount = cpu_to_le16(count);
145 /* long_op set to 1 to allow for oplock break timeouts */
146 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
147 - (struct smb_hdr *) pSMBr, &bytes_returned, 1);
148 + (struct smb_hdr *)pSMBr, &bytes_returned, CIFS_LONG_OP);
149 cifs_stats_inc(&tcon->num_opens);
151 cFYI(1, ("Error in Open = %d", rc));
152 @@ -1257,7 +1245,7 @@ openRetry:
153 pSMB->ByteCount = cpu_to_le16(count);
154 /* long_op set to 1 to allow for oplock break timeouts */
155 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
156 - (struct smb_hdr *) pSMBr, &bytes_returned, 1);
157 + (struct smb_hdr *)pSMBr, &bytes_returned, CIFS_LONG_OP);
158 cifs_stats_inc(&tcon->num_opens);
160 cFYI(1, ("Error in Open = %d", rc));
161 @@ -1337,7 +1325,7 @@ CIFSSMBRead(const int xid, struct cifsTc
162 iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
163 rc = SendReceive2(xid, tcon->ses, iov,
165 - &resp_buf_type, 0);
166 + &resp_buf_type, CIFS_STD_OP | CIFS_LOG_ERROR);
167 cifs_stats_inc(&tcon->num_reads);
168 pSMBr = (READ_RSP *)iov[0].iov_base;
170 @@ -1596,7 +1584,7 @@ CIFSSMBLock(const int xid, struct cifsTc
174 - cFYI(1, ("In CIFSSMBLock - timeout %d numLock %d",waitFlag,numLock));
175 + cFYI(1, ("CIFSSMBLock timeout %d numLock %d", waitFlag, numLock));
176 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
179 @@ -1605,10 +1593,10 @@ CIFSSMBLock(const int xid, struct cifsTc
180 pSMBr = (LOCK_RSP *)pSMB; /* BB removeme BB */
182 if(lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
183 - timeout = -1; /* no response expected */
184 + timeout = CIFS_ASYNC_OP; /* no response expected */
186 } else if (waitFlag == TRUE) {
187 - timeout = 3; /* blocking operation, no timeout */
188 + timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
189 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
192 @@ -1638,15 +1626,16 @@ CIFSSMBLock(const int xid, struct cifsTc
194 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
195 (struct smb_hdr *) pSMBr, &bytes_returned);
196 + cifs_small_buf_release(pSMB);
198 - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
199 - (struct smb_hdr *) pSMBr, &bytes_returned, timeout);
200 + rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *)pSMB,
202 + /* SMB buffer freed by function above */
204 cifs_stats_inc(&tcon->num_locks);
206 cFYI(1, ("Send error in Lock = %d", rc));
208 - cifs_small_buf_release(pSMB);
210 /* Note: On -EAGAIN error only caller can retry on handle based calls
211 since file handle passed in no longer valid */
212 @@ -1666,7 +1655,9 @@ CIFSSMBPosixLock(const int xid, struct c
215 int bytes_returned = 0;
216 + int resp_buf_type = 0;
217 __u16 params, param_offset, offset, byte_count, count;
218 + struct kvec iov[1];
220 cFYI(1, ("Posix Lock"));
222 @@ -1710,7 +1701,7 @@ CIFSSMBPosixLock(const int xid, struct c
224 parm_data->lock_type = cpu_to_le16(lock_type);
226 - timeout = 3; /* blocking operation, no timeout */
227 + timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
228 parm_data->lock_flags = cpu_to_le16(1);
229 pSMB->Timeout = cpu_to_le32(-1);
231 @@ -1730,8 +1721,13 @@ CIFSSMBPosixLock(const int xid, struct c
232 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
233 (struct smb_hdr *) pSMBr, &bytes_returned);
235 - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
236 - (struct smb_hdr *) pSMBr, &bytes_returned, timeout);
237 + iov[0].iov_base = (char *)pSMB;
238 + iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
239 + rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
240 + &resp_buf_type, timeout);
241 + pSMB = NULL; /* request buf already freed by SendReceive2. Do
242 + not try to free it twice below on exit */
243 + pSMBr = (struct smb_com_transaction2_sfi_rsp *)iov[0].iov_base;
247 @@ -1766,6 +1762,11 @@ plk_err_exit:
249 cifs_small_buf_release(pSMB);
251 + if (resp_buf_type == CIFS_SMALL_BUFFER)
252 + cifs_small_buf_release(iov[0].iov_base);
253 + else if (resp_buf_type == CIFS_LARGE_BUFFER)
254 + cifs_buf_release(iov[0].iov_base);
256 /* Note: On -EAGAIN error only caller can retry on handle based calls
257 since file handle passed in no longer valid */
259 @@ -1778,8 +1779,6 @@ CIFSSMBClose(const int xid, struct cifsT
262 CLOSE_REQ *pSMB = NULL;
263 - CLOSE_RSP *pSMBr = NULL;
264 - int bytes_returned;
265 cFYI(1, ("In CIFSSMBClose"));
267 /* do not retry on dead session on close */
268 @@ -1789,13 +1788,10 @@ CIFSSMBClose(const int xid, struct cifsT
272 - pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */
274 pSMB->FileID = (__u16) smb_file_id;
275 pSMB->LastWriteTime = 0xFFFFFFFF;
277 - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
278 - (struct smb_hdr *) pSMBr, &bytes_returned, 0);
279 + rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
280 cifs_stats_inc(&tcon->num_closes);
283 @@ -1804,8 +1800,6 @@ CIFSSMBClose(const int xid, struct cifsT
287 - cifs_small_buf_release(pSMB);
289 /* Since session is dead, file will be closed on server already */
292 @@ -2989,7 +2983,8 @@ CIFSSMBGetCIFSACL(const int xid, struct
293 iov[0].iov_base = (char *)pSMB;
294 iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
296 - rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, 0);
297 + rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
299 cifs_stats_inc(&tcon->num_acl_get);
301 cFYI(1, ("Send error in QuerySecDesc = %d", rc));
302 @@ -3634,8 +3629,6 @@ CIFSFindClose(const int xid, struct cifs
305 FINDCLOSE_REQ *pSMB = NULL;
306 - CLOSE_RSP *pSMBr = NULL; /* BB removeme BB */
307 - int bytes_returned;
309 cFYI(1, ("In CIFSSMBFindClose"));
310 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
311 @@ -3647,16 +3640,13 @@ CIFSFindClose(const int xid, struct cifs
315 - pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */
316 pSMB->FileID = searchHandle;
318 - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
319 - (struct smb_hdr *) pSMBr, &bytes_returned, 0);
320 + rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
322 cERROR(1, ("Send error in FindClose = %d", rc));
324 cifs_stats_inc(&tcon->num_fclose);
325 - cifs_small_buf_release(pSMB);
327 /* Since session is dead, search handle closed on server already */
329 @@ -4571,11 +4561,9 @@ CIFSSMBSetFileSize(const int xid, struct
330 __u16 fid, __u32 pid_of_opener, int SetAllocation)
332 struct smb_com_transaction2_sfi_req *pSMB = NULL;
333 - struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
335 struct file_end_of_file_info *parm_data;
337 - int bytes_returned = 0;
338 __u16 params, param_offset, offset, byte_count, count;
340 cFYI(1, ("SetFileSize (via SetFileInfo) %lld",
341 @@ -4585,8 +4573,6 @@ CIFSSMBSetFileSize(const int xid, struct
345 - pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
347 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
348 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
350 @@ -4637,17 +4623,13 @@ CIFSSMBSetFileSize(const int xid, struct
352 pSMB->hdr.smb_buf_length += byte_count;
353 pSMB->ByteCount = cpu_to_le16(byte_count);
354 - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
355 - (struct smb_hdr *) pSMBr, &bytes_returned, 0);
356 + rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
359 ("Send error in SetFileInfo (SetFileSize) = %d",
364 - cifs_small_buf_release(pSMB);
366 /* Note: On -EAGAIN error only caller can retry on handle based calls
367 since file handle passed in no longer valid */
369 @@ -4665,10 +4647,8 @@ CIFSSMBSetFileTimes(const int xid, struc
372 struct smb_com_transaction2_sfi_req *pSMB = NULL;
373 - struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
376 - int bytes_returned = 0;
377 __u16 params, param_offset, offset, byte_count, count;
379 cFYI(1, ("Set Times (via SetFileInfo)"));
380 @@ -4677,8 +4657,6 @@ CIFSSMBSetFileTimes(const int xid, struc
384 - pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
386 /* At this point there is no need to override the current pid
387 with the pid of the opener, but that could change if we someday
388 use an existing handle (rather than opening one on the fly) */
389 @@ -4718,14 +4696,11 @@ CIFSSMBSetFileTimes(const int xid, struc
390 pSMB->hdr.smb_buf_length += byte_count;
391 pSMB->ByteCount = cpu_to_le16(byte_count);
392 memcpy(data_offset,data,sizeof(FILE_BASIC_INFO));
393 - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
394 - (struct smb_hdr *) pSMBr, &bytes_returned, 0);
395 + rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
397 cFYI(1,("Send error in Set Time (SetFileInfo) = %d",rc));
400 - cifs_small_buf_release(pSMB);
402 /* Note: On -EAGAIN error only caller can retry on handle based calls
403 since file handle passed in no longer valid */
405 @@ -5016,7 +4991,8 @@ int CIFSSMBNotify(const int xid, struct
408 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
409 - (struct smb_hdr *) pSMBr, &bytes_returned, -1);
410 + (struct smb_hdr *)pSMBr, &bytes_returned,
413 cFYI(1, ("Error in Notify = %d", rc));
415 --- a/fs/cifs/connect.c 2007-11-16 17:54:37.000000000 -0500
416 +++ b/fs/cifs/connect.c 2007-11-16 17:58:21.000000000 -0500
417 @@ -2273,7 +2273,7 @@ CIFSSessSetup(unsigned int xid, struct c
418 pSMB->req_no_secext.ByteCount = cpu_to_le16(count);
420 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
421 - &bytes_returned, 1);
422 + &bytes_returned, CIFS_LONG_OP);
424 /* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */
425 } else if ((smb_buffer_response->WordCount == 3)
426 @@ -2559,7 +2559,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned i
427 pSMB->req.ByteCount = cpu_to_le16(count);
429 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
430 - &bytes_returned, 1);
431 + &bytes_returned, CIFS_LONG_OP);
433 if (smb_buffer_response->Status.CifsError ==
434 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
435 @@ -2985,7 +2985,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xi
436 pSMB->req.ByteCount = cpu_to_le16(count);
438 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
439 - &bytes_returned, 1);
440 + &bytes_returned, CIFS_LONG_OP);
442 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
443 } else if ((smb_buffer_response->WordCount == 3)
444 @@ -3256,7 +3256,8 @@ CIFSTCon(unsigned int xid, struct cifsSe
445 pSMB->hdr.smb_buf_length += count;
446 pSMB->ByteCount = cpu_to_le16(count);
448 - rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length, 0);
449 + rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
452 /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
453 /* above now done in SendReceive */
454 --- a/fs/cifs/file.c 2007-11-16 17:54:37.000000000 -0500
455 +++ b/fs/cifs/file.c 2007-11-16 17:58:12.000000000 -0500
456 @@ -809,9 +809,9 @@ ssize_t cifs_user_write(struct file *fil
459 if (*poffset > file->f_path.dentry->d_inode->i_size)
460 - long_op = 2; /* writes past end of file can take a long time */
461 + long_op = CIFS_VLONG_OP; /* writes past EOF take long time */
464 + long_op = CIFS_LONG_OP;
466 for (total_written = 0; write_size > total_written;
467 total_written += bytes_written) {
468 @@ -858,7 +858,7 @@ ssize_t cifs_user_write(struct file *fil
471 *poffset += bytes_written;
472 - long_op = FALSE; /* subsequent writes fast -
473 + long_op = CIFS_STD_OP; /* subsequent writes fast -
474 15 seconds is plenty */
477 @@ -908,9 +908,9 @@ static ssize_t cifs_write(struct file *f
480 if (*poffset > file->f_path.dentry->d_inode->i_size)
481 - long_op = 2; /* writes past end of file can take a long time */
482 + long_op = CIFS_VLONG_OP; /* writes past EOF can be slow */
485 + long_op = CIFS_LONG_OP;
487 for (total_written = 0; write_size > total_written;
488 total_written += bytes_written) {
489 @@ -976,7 +976,7 @@ static ssize_t cifs_write(struct file *f
492 *poffset += bytes_written;
493 - long_op = FALSE; /* subsequent writes fast -
494 + long_op = CIFS_STD_OP; /* subsequent writes fast -
495 15 seconds is plenty */
498 @@ -1276,7 +1276,7 @@ retry:
500 bytes_to_write, offset,
501 &bytes_written, iov, n_iov,
504 atomic_dec(&open_file->wrtPending);
505 if (rc || bytes_written < bytes_to_write) {
506 cERROR(1,("Write2 ret %d, written = %d",
507 --- a/fs/cifs/sess.c 2007-11-16 17:54:37.000000000 -0500
508 +++ b/fs/cifs/sess.c 2007-11-16 17:58:12.000000000 -0500
509 @@ -489,7 +489,8 @@ CIFS_SessSetup(unsigned int xid, struct
511 iov[1].iov_base = str_area;
512 iov[1].iov_len = count;
513 - rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type, 0);
514 + rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type,
515 + CIFS_STD_OP /* not long */ | CIFS_LOG_ERROR);
516 /* SMB request buf freed in SendReceive2 */
518 cFYI(1,("ssetup rc from sendrecv2 is %d",rc));
519 --- a/fs/cifs/transport.c 2007-11-16 17:54:37.000000000 -0500
520 +++ b/fs/cifs/transport.c 2007-11-16 18:04:35.000000000 -0500
521 @@ -308,7 +308,7 @@ smb_send2(struct socket *ssocket, struct
523 static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op)
525 - if(long_op == -1) {
526 + if (long_op == CIFS_ASYNC_OP) {
527 /* oplock breaks must not be held up */
528 atomic_inc(&ses->server->inFlight);
530 @@ -337,7 +337,7 @@ static int wait_for_free_request(struct
531 they are allowed to block on server */
533 /* update # of requests on the wire to server */
535 + if (long_op != CIFS_BLOCKING_OP)
536 atomic_inc(&ses->server->inFlight);
537 spin_unlock(&GlobalMid_Lock);
539 @@ -416,17 +416,48 @@ static int wait_for_response(struct cifs
546 + * Send an SMB Request. No response info (other than return code)
547 + * needs to be parsed.
549 + * flags indicate the type of request buffer and how long to wait
550 + * and whether to log NT STATUS code (error) before mapping it to POSIX error
554 +SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses,
555 + struct smb_hdr *in_buf, int flags)
558 + struct kvec iov[1];
561 + iov[0].iov_base = (char *)in_buf;
562 + iov[0].iov_len = in_buf->smb_buf_length + 4;
563 + flags |= CIFS_NO_RESP;
564 + rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags);
565 +#ifdef CONFIG_CIFS_DEBUG2
566 + cFYI(1, ("SendRcvNoR flags %d rc %d", flags, rc));
572 SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
573 struct kvec *iov, int n_vec, int * pRespBufType /* ret */,
579 unsigned int receive_len;
580 unsigned long timeout;
581 struct mid_q_entry *midQ;
582 struct smb_hdr *in_buf = iov[0].iov_base;
584 + long_op = flags & CIFS_TIMEOUT_MASK;
586 *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */
588 if ((ses == NULL) || (ses->server == NULL)) {
589 @@ -485,15 +516,22 @@ SendReceive2(const unsigned int xid, str
595 - else if (long_op == 2) /* writes past end of file can take loong time */
596 + if (long_op == CIFS_STD_OP)
598 + else if (long_op == CIFS_VLONG_OP) /* e.g. slow writes past EOF */
600 - else if (long_op == 1)
601 + else if (long_op == CIFS_LONG_OP)
602 timeout = 45 * HZ; /* should be greater than
603 servers oplock break timeout (about 43 seconds) */
606 + else if (long_op == CIFS_ASYNC_OP)
608 + else if (long_op == CIFS_BLOCKING_OP)
609 + timeout = 0x7FFFFFFF; /* large, but not so large as to wrap */
611 + cERROR(1, ("unknown timeout flag %d", long_op));
616 /* wait for 15 seconds or until woken up due to response arriving or
617 due to last connection to this server being unmounted */
618 @@ -578,8 +616,10 @@ SendReceive2(const unsigned int xid, str
619 (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ )
620 BCC(midQ->resp_buf) =
621 le16_to_cpu(BCC_LE(midQ->resp_buf));
622 - midQ->resp_buf = NULL; /* mark it so will not be freed
623 - by DeleteMidQEntry */
624 + if ((flags & CIFS_NO_RESP) == 0)
625 + midQ->resp_buf = NULL; /* mark it so buf will
630 cFYI(1,("Bad MID state?"));
631 @@ -667,17 +707,25 @@ SendReceive(const unsigned int xid, stru
636 + if (long_op == CIFS_STD_OP)
638 + /* wait for 15 seconds or until woken up due to response arriving or
639 + due to last connection to this server being unmounted */
640 + else if (long_op == CIFS_ASYNC_OP)
642 - else if (long_op == 2) /* writes past end of file can take loong time */
643 + else if (long_op == CIFS_VLONG_OP) /* writes past EOF can be slow */
645 - else if (long_op == 1)
646 + else if (long_op == CIFS_LONG_OP)
647 timeout = 45 * HZ; /* should be greater than
648 servers oplock break timeout (about 43 seconds) */
651 - /* wait for 15 seconds or until woken up due to response arriving or
652 - due to last connection to this server being unmounted */
653 + else if (long_op == CIFS_BLOCKING_OP)
654 + timeout = 0x7FFFFFFF; /* large but no so large as to wrap */
656 + cERROR(1, ("unknown timeout flag %d", long_op));
661 if (signal_pending(current)) {
662 /* if signal pending do not hold up user for full smb timeout
663 but we still give response a chance to complete */
664 @@ -817,7 +865,7 @@ send_lock_cancel(const unsigned int xid,
665 pSMB->hdr.Mid = GetNextMid(ses->server);
667 return SendReceive(xid, ses, in_buf, out_buf,
668 - &bytes_returned, 0);
669 + &bytes_returned, CIFS_STD_OP);
673 @@ -849,7 +897,7 @@ SendReceiveBlockingLock(const unsigned i
674 to the same server. We may make this configurable later or
677 - rc = wait_for_free_request(ses, 3);
678 + rc = wait_for_free_request(ses, CIFS_BLOCKING_OP);
682 From: Suresh Jayaraman <sjayaraman@suse.de>
683 Subject: Fix sign mount option and sign proc config setting
684 References: 329790, CVE-2007-3843
685 Patch mainline: 2.6.23-rc1
687 Backported the fix (2.6.23-rc1) from Steve French. The original patch removes
688 few commented functions (which are not required) as part of this fix, backport
689 also does the same to retain compatibility.
691 We were checking the wrong (old) global variable to determine
692 whether to override server and force signing on the SMB
695 Acked-by: Dave Kleikamp <shaggy@austin.ibm.com>
696 Signed-off-by: Steve French <sfrench@us.ibm.com>
697 Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>
698 Signed-off-by: Oliver Pinter <oliver.pntr@gmail.com>
701 fs/cifs/cifs_debug.c | 92 ++++-----------------------------------------------
702 fs/cifs/cifssmb.c | 34 ++++++++++++------
703 2 files changed, 30 insertions(+), 96 deletions(-)
706 Index: linux-2.6.22-SL103_BRANCH/fs/cifs/cifs_debug.c
707 ===================================================================
708 --- linux-2.6.22-SL103_BRANCH.orig/fs/cifs/cifs_debug.c 2007-11-23 16:23:30.000000000 +0530
709 +++ linux-2.6.22-SL103_BRANCH/fs/cifs/cifs_debug.c 2007-11-23 16:24:23.000000000 +0530
710 @@ -901,90 +901,14 @@ security_flags_write(struct file *file,
712 /* flags look ok - update the global security flags for cifs module */
713 extended_security = flags;
714 + if (extended_security & CIFSSEC_MUST_SIGN) {
715 + /* requiring signing implies signing is allowed */
716 + extended_security |= CIFSSEC_MAY_SIGN;
717 + cFYI(1, ("packet signing now required"));
718 + } else if ((extended_security & CIFSSEC_MAY_SIGN) == 0) {
719 + cFYI(1, ("packet signing disabled"));
721 + /* BB should we turn on MAY flags for other MUST options? */
726 -ntlmv2_enabled_read(char *page, char **start, off_t off,
727 - int count, int *eof, void *data)
731 - len = sprintf(page, "%d\n", ntlmv2_support);
734 - *start = page + off;
747 -ntlmv2_enabled_write(struct file *file, const char __user *buffer,
748 - unsigned long count, void *data)
753 - rc = get_user(c, buffer);
756 - if (c == '0' || c == 'n' || c == 'N')
757 - ntlmv2_support = 0;
758 - else if (c == '1' || c == 'y' || c == 'Y')
759 - ntlmv2_support = 1;
761 - ntlmv2_support = 2;
767 -packet_signing_enabled_read(char *page, char **start, off_t off,
768 - int count, int *eof, void *data)
772 - len = sprintf(page, "%d\n", sign_CIFS_PDUs);
775 - *start = page + off;
788 -packet_signing_enabled_write(struct file *file, const char __user *buffer,
789 - unsigned long count, void *data)
794 - rc = get_user(c, buffer);
797 - if (c == '0' || c == 'n' || c == 'N')
798 - sign_CIFS_PDUs = 0;
799 - else if (c == '1' || c == 'y' || c == 'Y')
800 - sign_CIFS_PDUs = 1;
802 - sign_CIFS_PDUs = 2;
809 Index: linux-2.6.22-SL103_BRANCH/fs/cifs/cifssmb.c
810 ===================================================================
811 --- linux-2.6.22-SL103_BRANCH.orig/fs/cifs/cifssmb.c 2007-11-23 16:23:30.000000000 +0530
812 +++ linux-2.6.22-SL103_BRANCH/fs/cifs/cifssmb.c 2007-11-23 16:24:23.000000000 +0530
813 @@ -426,11 +426,11 @@ CIFSSMBNegotiate(unsigned int xid, struc
815 /* if any of auth flags (ie not sign or seal) are overriden use them */
816 if(ses->overrideSecFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
817 - secFlags = ses->overrideSecFlg;
818 + secFlags = ses->overrideSecFlg; /* BB FIXME fix sign flags? */
819 else /* if override flags set only sign/seal OR them with global auth */
820 secFlags = extended_security | ses->overrideSecFlg;
822 - cFYI(1,("secFlags 0x%x",secFlags));
823 + cFYI(1, ("secFlags 0x%x", secFlags));
825 pSMB->hdr.Mid = GetNextMid(server);
826 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
827 @@ -633,22 +633,32 @@ CIFSSMBNegotiate(unsigned int xid, struc
828 #ifdef CONFIG_CIFS_WEAK_PW_HASH
831 - if(sign_CIFS_PDUs == FALSE) {
832 + if ((secFlags & CIFSSEC_MAY_SIGN) == 0) {
833 + /* MUST_SIGN already includes the MAY_SIGN FLAG
834 + so if this is zero it means that signing is disabled */
835 + cFYI(1, ("Signing disabled"));
836 if(server->secMode & SECMODE_SIGN_REQUIRED)
837 - cERROR(1,("Server requires "
838 - "/proc/fs/cifs/PacketSigningEnabled to be on"));
839 + cERROR(1, ("Server requires "
840 + "/proc/fs/cifs/PacketSigningEnabled "
843 ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
844 - } else if(sign_CIFS_PDUs == 1) {
845 + } else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) {
846 + /* signing required */
847 + cFYI(1, ("Must sign - secFlags 0x%x", secFlags));
848 + if((server->secMode &
849 + (SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) {
851 + ("signing required but server lacks support"));
853 + server->secMode |= SECMODE_SIGN_REQUIRED;
855 + /* signing optional ie CIFSSEC_MAY_SIGN */
856 if((server->secMode & SECMODE_SIGN_REQUIRED) == 0)
859 ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
860 - } else if(sign_CIFS_PDUs == 2) {
861 - if((server->secMode &
862 - (SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) {
863 - cERROR(1,("signing required but server lacks support"));
868 cifs_buf_release(pSMB);
870 From: Dean Roe <roe@sgi.com>
871 Subject: Prevent NULL pointer deref in grab_swap_token
874 grab_swap_token() assumes that the current process has an mm struct,
875 which is not true for kernel threads invoking get_user_pages(). Since
876 this should be extremely rare, just return from grab_swap_token()
877 without doing anything.
879 Signed-off-by: Dean Roe <roe@sgi.com>
880 Acked-by: mason@suse.de
881 Acked-by: okir@suse.de
882 Signed-off-by: Oliver Pinter <oliver.pntr@gmail.com>
886 1 file changed, 3 insertions(+)
888 --- a/mm/thrash.c 2007-07-08 19:32:17.000000000 -0400
889 +++ b/mm/thrash.c 2007-08-27 14:01:21.000000000 -0400
890 @@ -31,6 +31,9 @@ void grab_swap_token(void)
891 int current_interval;
894 + if (current->mm == NULL)
898 current_interval = global_faults - current->mm->faultstamp;
900 Patch-mainline: 2.6.25
902 Git-commit: 6ed3003c19a96fe18edf8179c4be6fe14abbebbc
903 From: NeilBrown <neilb@suse.de>
904 Date: Wed, 6 Feb 2008 01:40:00 -0800
905 Subject: [PATCH] md: fix an occasional deadlock in raid5
907 raid5's 'make_request' function calls generic_make_request on underlying
908 devices and if we run out of stripe heads, it could end up waiting for one of
909 those requests to complete. This is bad as recursive calls to
910 generic_make_request go on a queue and are not even attempted until
911 make_request completes.
913 So: don't make any generic_make_request calls in raid5 make_request until all
914 waiting has been done. We do this by simply setting STRIPE_HANDLE instead of
915 calling handle_stripe().
917 If we need more stripe_heads, raid5d will get called to process the pending
918 stripe_heads which will call generic_make_request from a
920 This change by itself causes a performance hit. So add a change so that
921 raid5_activate_delayed is only called at unplug time, never in raid5. This
922 seems to bring back the performance numbers. Calling it in raid5d was
923 sometimes too soon...
927 How about we queue it for 2.6.25-rc1 and then about when -rc2 comes out,
928 we queue it for 2.6.24.y?
930 Acked-by: Dan Williams <dan.j.williams@intel.com>
931 Signed-off-by: Neil Brown <neilb@suse.de>
932 Tested-by: dean gaudet <dean@arctic.org>
933 Cc: <stable@kernel.org>
934 Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
935 Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
936 Signed-off-by: Oliver Pinter <oliver.pntr@gmail.com>
939 drivers/md/raid5.c | 14 +++++---------
940 1 file changed, 5 insertions(+), 9 deletions(-)
942 --- linux-2.6.22-SL103_BRANCH.orig/drivers/md/raid5.c
943 +++ linux-2.6.22-SL103_BRANCH/drivers/md/raid5.c
944 @@ -2525,7 +2525,8 @@ static void raid5_activate_delayed(raid5
945 atomic_inc(&conf->preread_active_stripes);
946 list_add_tail(&sh->lru, &conf->handle_list);
950 + blk_plug_device(conf->mddev->queue);
953 static void activate_bit_delay(raid5_conf_t *conf)
954 @@ -2949,7 +2950,8 @@ static int make_request(request_queue_t
957 finish_wait(&conf->wait_for_overlap, &w);
958 - handle_stripe(sh, NULL);
959 + set_bit(STRIPE_HANDLE, &sh->state);
960 + clear_bit(STRIPE_DELAYED, &sh->state);
963 /* cannot get stripe for read-ahead, just give-up */
964 @@ -3267,7 +3269,7 @@ static int retry_aligned_read(raid5_con
965 * During the scan, completed stripes are saved for us by the interrupt
966 * handler, so that they will not have to wait for our next wakeup.
968 -static void raid5d (mddev_t *mddev)
969 +static void raid5d(mddev_t *mddev)
971 struct stripe_head *sh;
972 raid5_conf_t *conf = mddev_to_conf(mddev);
973 @@ -3292,12 +3294,6 @@ static void raid5d (mddev_t *mddev)
974 activate_bit_delay(conf);
977 - if (list_empty(&conf->handle_list) &&
978 - atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD &&
979 - !blk_queue_plugged(mddev->queue) &&
980 - !list_empty(&conf->delayed_list))
981 - raid5_activate_delayed(conf);
983 while ((bio = remove_bio_from_retry(conf))) {
985 spin_unlock_irq(&conf->device_lock);
986 From 6d2144d355d2a532e5cc3fc12a6ba2a8d4ef15e4 Mon Sep 17 00:00:00 2001
987 From: Joe Korty <joe.korty@ccur.com>
988 Date: Wed, 5 Mar 2008 15:04:59 -0800
989 Subject: [PATCH] slab: NUMA slab allocator migration bugfix
991 NUMA slab allocator cpu migration bugfix
993 The NUMA slab allocator (specifically, cache_alloc_refill)
994 is not refreshing its local copies of what cpu and what
995 numa node it is on, when it drops and reacquires the irq
996 block that it inherited from its caller. As a result
997 those values become invalid if an attempt to migrate the
998 process to another numa node occured while the irq block
1001 The solution is to make cache_alloc_refill reload these
1002 variables whenever it drops and reacquires the irq block.
1004 The error is very difficult to hit. When it does occur,
1005 one gets the following oops + stack traceback bits in
1006 check_spinlock_acquired:
1008 kernel BUG at mm/slab.c:2417
1009 cache_alloc_refill+0xe6
1010 kmem_cache_alloc+0xd0
1013 This patch was developed against 2.6.23, ported to and
1014 compiled-tested only against 2.6.25-rc4.
1016 Signed-off-by: Joe Korty <joe.korty@ccur.com>
1017 Signed-off-by: Christoph Lameter <clameter@sgi.com>
1018 Signed-off-by: Oliver Pinter <oliver.pntr@gmail.com>
1021 diff --git a/mm/slab.c b/mm/slab.c
1022 index f7faff7..e6c698f 100644
1025 @@ -2964,11 +2964,10 @@ static void *cache_alloc_refill(struct kmem_cache *cachep, gfp_t flags)
1026 struct array_cache *ac;
1029 - node = numa_node_id();
1033 + node = numa_node_id();
1034 ac = cpu_cache_get(cachep);
1036 batchcount = ac->batchcount;
1037 if (!ac->touched && batchcount > BATCHREFILL_LIMIT) {
1039 Subject: MCA when shutting down tulip quad-NIC
1040 From: andrew.patterson@hp.com
1041 References: SUSE39204
1043 Shutting down the network causes an MCA because of an IO TLB error when
1044 a DEC quad 10/100 card is in any slot. This problem was originally seen
1047 Acked-by: Olaf Kirch <okir@suse.de>
1048 Signed-off-by: Oliver Pinter <oliver.pntr@gmail.com>
1050 drivers/net/tulip/tulip_core.c | 4 ++++
1051 1 file changed, 4 insertions(+)
1053 --- a/drivers/net/tulip/tulip_core.c 2007-07-08 19:32:17.000000000 -0400
1054 +++ b/drivers/net/tulip/tulip_core.c 2007-08-27 14:01:23.000000000 -0400
1055 @@ -1794,6 +1794,10 @@ static void __devexit tulip_remove_one (
1058 tp = netdev_priv(dev);
1060 + /* shoot NIC in the head before deallocating descriptors */
1061 + pci_disable_device(tp->pdev);
1063 unregister_netdev(dev);
1064 pci_free_consistent (pdev,
1065 sizeof (struct tulip_rx_desc) * RX_RING_SIZE +