linux v2.6.22.21-op1-rc1 patches
[linux-2.6.22.y-op-patches.git] / review-2.6.22.y / mbox
bloba094f335658a74633fc34b0605b3c893dd30e2af
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
9 request
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,
19 Lock and PosixLock
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>
28 ---
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 +++----
35  fs/cifs/sess.c      |    3 +
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)
78  {
79         struct smb_hdr *smb_buffer;
80 -       struct smb_hdr *smb_buffer_response; /* BB removeme BB */
81         int rc = 0;
82 -       int length;
84         cFYI(1, ("In tree disconnect"));
85         /*
86 @@ -699,16 +697,12 @@ CIFSSMBTDis(const int xid, struct cifsTc
87         if (rc) {
88                 up(&tcon->tconSem);
89                 return rc;
90 -       } else {
91 -               smb_buffer_response = smb_buffer; /* BB removeme BB */
92         }
93 -       rc = SendReceive(xid, tcon->ses, smb_buffer, smb_buffer_response,
94 -                        &length, 0);
96 +       rc = SendReceiveNoRsp(xid, tcon->ses, smb_buffer, 0);
97         if (rc)
98                 cFYI(1, ("Tree disconnect failed %d", rc));
100 -       if (smb_buffer)
101 -               cifs_small_buf_release(smb_buffer);
102         up(&tcon->tconSem);
104         /* No need to return error on this operation if tid invalidated and 
105 @@ -722,10 +716,8 @@ CIFSSMBTDis(const int xid, struct cifsTc
106  int
107  CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
109 -       struct smb_hdr *smb_buffer_response;
110         LOGOFF_ANDX_REQ *pSMB;
111         int rc = 0;
112 -       int length;
114         cFYI(1, ("In SMBLogoff for session disconnect"));
115         if (ses)
116 @@ -744,8 +736,6 @@ CIFSSMBLogoff(const int xid, struct cifs
117                 return rc;
118         }
120 -       smb_buffer_response = (struct smb_hdr *)pSMB; /* BB removeme BB */
121 -       
122         if(ses->server) {
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);
132         if (ses->server) {
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
136                 }
137         }
138         up(&ses->sesSem);
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);
150         if (rc) {
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);
159         if (rc) {
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, 
164                           1 /* num iovecs */,
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;
169         if (rc) {
170 @@ -1596,7 +1584,7 @@ CIFSSMBLock(const int xid, struct cifsTc
171         int timeout = 0;
172         __u16 count;
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);
178         if (rc)
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 */
185                 pSMB->Timeout = 0;
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 */
190         } else {
191                 pSMB->Timeout = 0;
192 @@ -1638,15 +1626,16 @@ CIFSSMBLock(const int xid, struct cifsTc
193         if (waitFlag) {
194                 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
195                         (struct smb_hdr *) pSMBr, &bytes_returned);
196 +               cifs_small_buf_release(pSMB);
197         } else {
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,
201 +                                     timeout);
202 +               /* SMB buffer freed by function above */
203         }
204         cifs_stats_inc(&tcon->num_locks);
205         if (rc) {
206                 cFYI(1, ("Send error in Lock = %d", rc));
207         }
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
213         int rc = 0;
214         int timeout = 0;
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);
225         if(waitFlag) {
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);
230         } else
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);
234         } else {
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;
244         }
246         if (rc) {
247 @@ -1766,6 +1762,11 @@ plk_err_exit:
248         if (pSMB)
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
261         int rc = 0;
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
269         if (rc)
270                 return rc;
272 -       pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */
274         pSMB->FileID = (__u16) smb_file_id;
275         pSMB->LastWriteTime = 0xFFFFFFFF;
276         pSMB->ByteCount = 0;
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);
281         if (rc) {
282                 if(rc!=-EINTR) {
283 @@ -1804,8 +1800,6 @@ CIFSSMBClose(const int xid, struct cifsT
284                 }
285         }
287 -       cifs_small_buf_release(pSMB);
289         /* Since session is dead, file will be closed on server already */
290         if(rc == -EAGAIN)
291                 rc = 0;
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,
298 +                        CIFS_STD_OP);
299         cifs_stats_inc(&tcon->num_acl_get);
300         if (rc) {
301                 cFYI(1, ("Send error in QuerySecDesc = %d", rc));
302 @@ -3634,8 +3629,6 @@ CIFSFindClose(const int xid, struct cifs
304         int rc = 0;
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
312         if (rc)
313                 return rc;
315 -       pSMBr = (CLOSE_RSP *)pSMB;  /* BB removeme BB */
316         pSMB->FileID = searchHandle;
317         pSMB->ByteCount = 0;
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);
321         if (rc) {
322                 cERROR(1, ("Send error in FindClose = %d", rc));
323         }
324         cifs_stats_inc(&tcon->num_fclose);
325 -       cifs_small_buf_release(pSMB);
327         /* Since session is dead, search handle closed on server already */
328         if (rc == -EAGAIN)
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;
334         char *data_offset;
335         struct file_end_of_file_info *parm_data;
336         int rc = 0;
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
342         if (rc)
343                 return rc;
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));
349      
350 @@ -4637,17 +4623,13 @@ CIFSSMBSetFileSize(const int xid, struct
351         pSMB->Reserved4 = 0;
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);
357         if (rc) {
358                 cFYI(1,
359                      ("Send error in SetFileInfo (SetFileSize) = %d",
360                       rc));
361         }
363 -       if (pSMB)
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
370                     __u16 fid)
372         struct smb_com_transaction2_sfi_req *pSMB  = NULL;
373 -       struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
374         char *data_offset;
375         int rc = 0;
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
381         if (rc)
382                 return rc;
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);
396         if (rc) {
397                 cFYI(1,("Send error in Set Time (SetFileInfo) = %d",rc));
398         }
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 
406         pSMB->ByteCount = 0;
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,
411 +                        CIFS_ASYNC_OP);
412         if (rc) {
413                 cFYI(1, ("Error in Notify = %d", rc));
414         } else {
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);
423         if (rc) {
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);
441         if (rc) {
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,
450 +                        CIFS_STD_OP);
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
457         xid = GetXid();
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 */
462         else
463 -               long_op = 1;
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
469                         }
470                 } else
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 */
475         }
477 @@ -908,9 +908,9 @@ static ssize_t cifs_write(struct file *f
478         xid = GetXid();
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 */
483         else
484 -               long_op = 1;
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
490                         }
491                 } else
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 */
496         }
498 @@ -1276,7 +1276,7 @@ retry:
499                                                    open_file->netfid,
500                                                    bytes_to_write, offset,
501                                                    &bytes_written, iov, n_iov,
502 -                                                  1);
503 +                                                  CIFS_LONG_OP);
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);
529         } else {
530 @@ -337,7 +337,7 @@ static int wait_for_free_request(struct 
531                                    they are allowed to block on server */
532                                         
533                                 /* update # of requests on the wire to server */
534 -                               if (long_op < 3)
535 +                               if (long_op != CIFS_BLOCKING_OP)
536                                         atomic_inc(&ses->server->inFlight);
537                                 spin_unlock(&GlobalMid_Lock);
538                                 break;
539 @@ -416,17 +416,48 @@ static int wait_for_response(struct cifs
540         }
545 + *
546 + * Send an SMB Request.  No response info (other than return code)
547 + * needs to be parsed.
548 + *
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
551 + *
552 + */
553 +int
554 +SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses,
555 +               struct smb_hdr *in_buf, int flags)
557 +       int rc;
558 +       struct kvec iov[1];
559 +       int resp_buf_type;
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));
567 +#endif
568 +       return rc;
571  int
572  SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, 
573              struct kvec *iov, int n_vec, int * pRespBufType /* ret */, 
574 -            const int long_op)
575 +            const int flags)
577         int rc = 0;
578 +       int long_op;
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;
583         
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
590         if(rc < 0)
591                 goto out;
593 -       if (long_op == -1)
594 -               goto out;
595 -       else if (long_op == 2) /* writes past end of file can take loong time */
596 +       if (long_op == CIFS_STD_OP)
597 +               timeout = 15 * HZ;
598 +       else if (long_op == CIFS_VLONG_OP) /* e.g. slow writes past EOF */
599                 timeout = 180 * HZ;
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) */
604 -       else
605 -               timeout = 15 * HZ;
606 +       else if (long_op == CIFS_ASYNC_OP)
607 +               goto out;
608 +       else if (long_op == CIFS_BLOCKING_OP)
609 +               timeout = 0x7FFFFFFF; /*  large, but not so large as to wrap */
610 +       else {
611 +               cERROR(1, ("unknown timeout flag %d", long_op));
612 +               rc = -EIO;
613 +               goto out;
614 +       }
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
626 +                                                          not be freed by
627 +                                                          DeleteMidQEntry */
628                 } else {
629                         rc = -EIO;
630                         cFYI(1,("Bad MID state?"));
631 @@ -667,17 +707,25 @@ SendReceive(const unsigned int xid, stru
632         if(rc < 0)
633                 goto out;
635 -       if (long_op == -1)
636 +       if (long_op == CIFS_STD_OP)
637 +               timeout = 15 * HZ;
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)
641                 goto out;
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 */
644                 timeout = 180 * HZ;
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) */
649 -       else
650 -               timeout = 15 * HZ;
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 */
655 +       else {
656 +               cERROR(1, ("unknown timeout flag %d", long_op));
657 +               rc = -EIO;
658 +               goto out;
659 +       }
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);
672  int
673 @@ -849,7 +897,7 @@ SendReceiveBlockingLock(const unsigned i
674            to the same server. We may make this configurable later or
675            use ses->maxReq */
677 -       rc = wait_for_free_request(ses, 3);
678 +       rc = wait_for_free_request(ses, CIFS_BLOCKING_OP);
679         if (rc)
680                 return rc;
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
693 connection.
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, 
711         }
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"));
720 +       }
721 +       /* BB should we turn on MAY flags for other MUST options? */
722         return count;
725 -/* static int
726 -ntlmv2_enabled_read(char *page, char **start, off_t off,
727 -                      int count, int *eof, void *data)
729 -       int len;
731 -       len = sprintf(page, "%d\n", ntlmv2_support);
733 -       len -= off;
734 -       *start = page + off;
736 -       if (len > count)
737 -               len = count;
738 -       else
739 -               *eof = 1;
741 -       if (len < 0)
742 -               len = 0;
744 -       return len;
746 -static int
747 -ntlmv2_enabled_write(struct file *file, const char __user *buffer,
748 -                       unsigned long count, void *data)
750 -       char c;
751 -       int rc;
753 -       rc = get_user(c, buffer);
754 -       if (rc)
755 -               return rc;
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;
760 -       else if (c == '2')
761 -               ntlmv2_support = 2;
763 -       return count;
766 -static int
767 -packet_signing_enabled_read(char *page, char **start, off_t off,
768 -                      int count, int *eof, void *data)
770 -       int len;
772 -       len = sprintf(page, "%d\n", sign_CIFS_PDUs);
774 -       len -= off;
775 -       *start = page + off;
777 -       if (len > count)
778 -               len = count;
779 -       else
780 -               *eof = 1;
782 -       if (len < 0)
783 -               len = 0;
785 -       return len;
787 -static int
788 -packet_signing_enabled_write(struct file *file, const char __user *buffer,
789 -                       unsigned long count, void *data)
791 -       char c;
792 -       int rc;
794 -       rc = get_user(c, buffer);
795 -       if (rc)
796 -               return rc;
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;
801 -       else if (c == '2')
802 -               sign_CIFS_PDUs = 2;
804 -       return count;
805 -} */
808  #endif
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
829  signing_check:
830  #endif
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 "
841 +                                "to be on"));
842                 server->secMode &= 
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) {
850 +                       cERROR(1,
851 +                               ("signing required but server lacks support"));
852 +               } else
853 +                       server->secMode |= SECMODE_SIGN_REQUIRED;
854 +       } else {
855 +               /* signing optional ie CIFSSEC_MAY_SIGN */
856                 if((server->secMode & SECMODE_SIGN_REQUIRED) == 0)
857 -                       server->secMode &= 
858 +                       server->secMode &=
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"));
864 -               }
865         }
867  neg_err_exit:  
868         cifs_buf_release(pSMB);
870 From: Dean Roe <roe@sgi.com>
871 Subject: Prevent NULL pointer deref in grab_swap_token
872 References: 159260
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>
885  mm/thrash.c |    3 +++
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;
893         global_faults++;
894 +       if (current->mm == NULL)
895 +               return;
898         current_interval = global_faults - current->mm->faultstamp;
900 Patch-mainline: 2.6.25
901 References: 357088
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...
925 Neil said:
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);
947                 }
948 -       }
949 +       } else
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 
955                                 goto retry;
956                         }
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);
961                         release_stripe(sh);
962                 } else {
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.
967   */
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);
975                 }
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))) {
984                         int ok;
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
999 had been dropped.
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
1011         ...
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
1023 --- a/mm/slab.c
1024 +++ b/mm/slab.c
1025 @@ -2964,11 +2964,10 @@ static void *cache_alloc_refill(struct kmem_cache *cachep, gfp_t flags)
1026         struct array_cache *ac;
1027         int node;
1029 -       node = numa_node_id();
1031 +retry:
1032         check_irq_off();
1033 +       node = numa_node_id();
1034         ac = cpu_cache_get(cachep);
1035 -retry:
1036         batchcount = ac->batchcount;
1037         if (!ac->touched && batchcount > BATCHREFILL_LIMIT) {
1038                 /*
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
1045 on an HP rx4640.
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 (
1056                 return;
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 +