]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
more .23 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Tue, 15 Jan 2008 21:53:21 +0000 (13:53 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 15 Jan 2008 21:53:21 +0000 (13:53 -0800)
queue-2.6.23/cifs-fix-buffer-overflow-if-server-sends-corrupt-response-to-small-request.patch [new file with mode: 0644]
queue-2.6.23/cifs-respect-umask-when-using-posix-mkdir.patch [new file with mode: 0644]
queue-2.6.23/m68k-export-cachectl.h.patch [new file with mode: 0644]
queue-2.6.23/md-fix-data-corruption-when-a-degraded-raid5-array-is-reshaped.patch [new file with mode: 0644]
queue-2.6.23/security-protect-from-stack-expantion-into-low-vm-addresses.patch [new file with mode: 0644]
queue-2.6.23/series
queue-2.6.23/vm-security-add-security-hook-to-do_brk.patch [new file with mode: 0644]

diff --git a/queue-2.6.23/cifs-fix-buffer-overflow-if-server-sends-corrupt-response-to-small-request.patch b/queue-2.6.23/cifs-fix-buffer-overflow-if-server-sends-corrupt-response-to-small-request.patch
new file mode 100644 (file)
index 0000000..04aaec1
--- /dev/null
@@ -0,0 +1,719 @@
+From stable-bounces@linux.kernel.org Mon Dec 17 12:35:33 2007
+From: Steve French <sfrench@us.ibm.com>
+Date: Mon, 17 Dec 2007 21:01:23 +0100
+Subject: CIFS: Fix buffer overflow if server sends corrupt response to small request (CVE-2007-5904)
+To: stable@kernel.org
+Cc: Steve French <sfrench@us.ibm.com>
+Message-ID: <20071217200123.GE17669@stro.at>
+Content-Disposition: inline
+
+From: Steve French <sfrench@us.ibm.com>
+
+patch 133672efbc1085f9af990bdc145e1822ea93bcf3 in mainline.
+
+[CIFS] Fix buffer overflow if server sends corrupt response to small request
+
+In SendReceive() function in transport.c - it memcpy's
+message payload into a buffer passed via out_buf param. The function
+assumes that all buffers are of size (CIFSMaxBufSize +
+MAX_CIFS_HDR_SIZE) , unfortunately it is also called with smaller
+(MAX_CIFS_SMALL_BUFFER_SIZE) buffers.  There are eight callers
+(SMB worker functions) which are primarily affected by this change:
+
+TreeDisconnect, uLogoff, Close, findClose, SetFileSize, SetFileTimes,
+Lock and PosixLock
+
+CC: Dave Kleikamp <shaggy@austin.ibm.com>
+CC: Przemyslaw Wegrzyn <czajnik@czajsoft.pl>
+Cc: maximilian attems <max@stro.at>
+Acked-by: Jeff Layton <jlayton@redhat.com>
+Signed-off-by: Steve French <sfrench@us.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -471,6 +471,17 @@ struct dir_notify_req {
+ #define   CIFS_LARGE_BUFFER     2
+ #define   CIFS_IOVEC            4    /* array of response buffers */
++/* Type of Request to SendReceive2 */
++#define   CIFS_STD_OP         0    /* normal request timeout */
++#define   CIFS_LONG_OP          1    /* long op (up to 45 sec, oplock time) */
++#define   CIFS_VLONG_OP         2    /* sloow op - can take up to 180 seconds */
++#define   CIFS_BLOCKING_OP      4    /* operation can block */
++#define   CIFS_ASYNC_OP         8    /* do not wait for response */
++#define   CIFS_TIMEOUT_MASK 0x00F    /* only one of 5 above set in req */
++#define   CIFS_LOG_ERROR    0x010    /* log NT STATUS if non-zero */
++#define   CIFS_LARGE_BUF_OP 0x020    /* large request buffer */
++#define   CIFS_NO_RESP      0x040    /* no response buffer required */
++
+ /* Security Flags: indicate type of session setup needed */
+ #define   CIFSSEC_MAY_SIGN    0x00001
+ #define   CIFSSEC_MAY_NTLM    0x00002
+diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
+index dd1d7c2..0c55dff 100644
+--- a/fs/cifs/cifsproto.h
++++ b/fs/cifs/cifsproto.h
+@@ -48,10 +48,11 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *,
+                       struct smb_hdr * /* input */ ,
+                       struct smb_hdr * /* out */ ,
+                       int * /* bytes returned */ , const int long_op);
++extern int SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses,
++                      struct smb_hdr *in_buf, int flags);
+ extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *,
+                       struct kvec *, int /* nvec to send */,
+-                      int * /* type of buf returned */ , const int long_op,
+-                      const int logError /* whether to log status code*/ );
++                      int * /* type of buf returned */ , const int flags);
+ extern int SendReceiveBlockingLock(const unsigned int /* xid */ ,
+                                       struct cifsTconInfo *,
+                               struct smb_hdr * /* input */ ,
+diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
+index 59d7b7c..9e8a6be 100644
+--- a/fs/cifs/cifssmb.c
++++ b/fs/cifs/cifssmb.c
+@@ -698,9 +698,7 @@ int
+ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
+ {
+       struct smb_hdr *smb_buffer;
+-      struct smb_hdr *smb_buffer_response; /* BB removeme BB */
+       int rc = 0;
+-      int length;
+       cFYI(1, ("In tree disconnect"));
+       /*
+@@ -737,16 +735,12 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
+       if (rc) {
+               up(&tcon->tconSem);
+               return rc;
+-      } else {
+-              smb_buffer_response = smb_buffer; /* BB removeme BB */
+       }
+-      rc = SendReceive(xid, tcon->ses, smb_buffer, smb_buffer_response,
+-                       &length, 0);
++
++      rc = SendReceiveNoRsp(xid, tcon->ses, smb_buffer, 0);
+       if (rc)
+               cFYI(1, ("Tree disconnect failed %d", rc));
+-      if (smb_buffer)
+-              cifs_small_buf_release(smb_buffer);
+       up(&tcon->tconSem);
+       /* No need to return error on this operation if tid invalidated and
+@@ -760,10 +754,8 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
+ int
+ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
+ {
+-      struct smb_hdr *smb_buffer_response;
+       LOGOFF_ANDX_REQ *pSMB;
+       int rc = 0;
+-      int length;
+       cFYI(1, ("In SMBLogoff for session disconnect"));
+       if (ses)
+@@ -782,8 +774,6 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
+               return rc;
+       }
+-      smb_buffer_response = (struct smb_hdr *)pSMB; /* BB removeme BB */
+-
+       if (ses->server) {
+               pSMB->hdr.Mid = GetNextMid(ses->server);
+@@ -795,8 +785,7 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
+       pSMB->hdr.Uid = ses->Suid;
+       pSMB->AndXCommand = 0xFF;
+-      rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
+-                       smb_buffer_response, &length, 0);
++      rc = SendReceiveNoRsp(xid, ses, (struct smb_hdr *) pSMB, 0);
+       if (ses->server) {
+               atomic_dec(&ses->server->socketUseCount);
+               if (atomic_read(&ses->server->socketUseCount) == 0) {
+@@ -807,7 +796,6 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
+               }
+       }
+       up(&ses->sesSem);
+-      cifs_small_buf_release(pSMB);
+       /* if session dead then we do not need to do ulogoff,
+               since server closed smb session, no sense reporting
+@@ -1255,7 +1243,7 @@ OldOpenRetry:
+       pSMB->ByteCount = cpu_to_le16(count);
+       /* long_op set to 1 to allow for oplock break timeouts */
+       rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+-                       (struct smb_hdr *) pSMBr, &bytes_returned, 1);
++                      (struct smb_hdr *)pSMBr, &bytes_returned, CIFS_LONG_OP);
+       cifs_stats_inc(&tcon->num_opens);
+       if (rc) {
+               cFYI(1, ("Error in Open = %d", rc));
+@@ -1368,7 +1356,7 @@ openRetry:
+       pSMB->ByteCount = cpu_to_le16(count);
+       /* long_op set to 1 to allow for oplock break timeouts */
+       rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+-                       (struct smb_hdr *) pSMBr, &bytes_returned, 1);
++                      (struct smb_hdr *)pSMBr, &bytes_returned, CIFS_LONG_OP);
+       cifs_stats_inc(&tcon->num_opens);
+       if (rc) {
+               cFYI(1, ("Error in Open = %d", rc));
+@@ -1446,7 +1434,7 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
+       iov[0].iov_base = (char *)pSMB;
+       iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
+       rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
+-                       &resp_buf_type, 0 /* not long op */, 1 /* log err */ );
++                       &resp_buf_type, CIFS_STD_OP | CIFS_LOG_ERROR);
+       cifs_stats_inc(&tcon->num_reads);
+       pSMBr = (READ_RSP *)iov[0].iov_base;
+       if (rc) {
+@@ -1665,7 +1653,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
+       rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type,
+-                        long_op, 0 /* do not log STATUS code */ );
++                        long_op);
+       cifs_stats_inc(&tcon->num_writes);
+       if (rc) {
+               cFYI(1, ("Send error Write2 = %d", rc));
+@@ -1707,7 +1695,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
+       int timeout = 0;
+       __u16 count;
+-      cFYI(1, ("In CIFSSMBLock - timeout %d numLock %d", waitFlag, numLock));
++      cFYI(1, ("CIFSSMBLock timeout %d numLock %d", waitFlag, numLock));
+       rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
+       if (rc)
+@@ -1716,10 +1704,10 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
+       pSMBr = (LOCK_RSP *)pSMB; /* BB removeme BB */
+       if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
+-              timeout = -1; /* no response expected */
++              timeout = CIFS_ASYNC_OP; /* no response expected */
+               pSMB->Timeout = 0;
+       } else if (waitFlag == TRUE) {
+-              timeout = 3;  /* blocking operation, no timeout */
++              timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
+               pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
+       } else {
+               pSMB->Timeout = 0;
+@@ -1749,15 +1737,16 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
+       if (waitFlag) {
+               rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
+                       (struct smb_hdr *) pSMBr, &bytes_returned);
++              cifs_small_buf_release(pSMB);
+       } else {
+-              rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+-                       (struct smb_hdr *) pSMBr, &bytes_returned, timeout);
++              rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *)pSMB,
++                                    timeout);
++              /* SMB buffer freed by function above */
+       }
+       cifs_stats_inc(&tcon->num_locks);
+       if (rc) {
+               cFYI(1, ("Send error in Lock = %d", rc));
+       }
+-      cifs_small_buf_release(pSMB);
+       /* Note: On -EAGAIN error only caller can retry on handle based calls
+       since file handle passed in no longer valid */
+@@ -1776,7 +1765,9 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
+       int rc = 0;
+       int timeout = 0;
+       int bytes_returned = 0;
++      int resp_buf_type = 0;
+       __u16 params, param_offset, offset, byte_count, count;
++      struct kvec iov[1];
+       cFYI(1, ("Posix Lock"));
+@@ -1818,7 +1809,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
+       parm_data->lock_type = cpu_to_le16(lock_type);
+       if (waitFlag) {
+-              timeout = 3;  /* blocking operation, no timeout */
++              timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
+               parm_data->lock_flags = cpu_to_le16(1);
+               pSMB->Timeout = cpu_to_le32(-1);
+       } else
+@@ -1838,8 +1829,13 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
+               rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
+                       (struct smb_hdr *) pSMBr, &bytes_returned);
+       } else {
+-              rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+-                      (struct smb_hdr *) pSMBr, &bytes_returned, timeout);
++              iov[0].iov_base = (char *)pSMB;
++              iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
++              rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
++                              &resp_buf_type, timeout);
++              pSMB = NULL; /* request buf already freed by SendReceive2. Do
++                              not try to free it twice below on exit */
++              pSMBr = (struct smb_com_transaction2_sfi_rsp *)iov[0].iov_base;
+       }
+       if (rc) {
+@@ -1874,6 +1870,11 @@ plk_err_exit:
+       if (pSMB)
+               cifs_small_buf_release(pSMB);
++      if (resp_buf_type == CIFS_SMALL_BUFFER)
++              cifs_small_buf_release(iov[0].iov_base);
++      else if (resp_buf_type == CIFS_LARGE_BUFFER)
++              cifs_buf_release(iov[0].iov_base);
++
+       /* Note: On -EAGAIN error only caller can retry on handle based calls
+          since file handle passed in no longer valid */
+@@ -1886,8 +1887,6 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
+ {
+       int rc = 0;
+       CLOSE_REQ *pSMB = NULL;
+-      CLOSE_RSP *pSMBr = NULL;
+-      int bytes_returned;
+       cFYI(1, ("In CIFSSMBClose"));
+ /* do not retry on dead session on close */
+@@ -1897,13 +1896,10 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
+       if (rc)
+               return rc;
+-      pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */
+-
+       pSMB->FileID = (__u16) smb_file_id;
+       pSMB->LastWriteTime = 0xFFFFFFFF;
+       pSMB->ByteCount = 0;
+-      rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+-                       (struct smb_hdr *) pSMBr, &bytes_returned, 0);
++      rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
+       cifs_stats_inc(&tcon->num_closes);
+       if (rc) {
+               if (rc != -EINTR) {
+@@ -1912,8 +1908,6 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
+               }
+       }
+-      cifs_small_buf_release(pSMB);
+-
+       /* Since session is dead, file will be closed on server already */
+       if (rc == -EAGAIN)
+               rc = 0;
+@@ -3102,7 +3096,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
+       iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
+       rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
+-                       0 /* not long op */, 0 /* do not log STATUS codes */ );
++                       CIFS_STD_OP);
+       cifs_stats_inc(&tcon->num_acl_get);
+       if (rc) {
+               cFYI(1, ("Send error in QuerySecDesc = %d", rc));
+@@ -3763,8 +3757,6 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon,
+ {
+       int rc = 0;
+       FINDCLOSE_REQ *pSMB = NULL;
+-      CLOSE_RSP *pSMBr = NULL; /* BB removeme BB */
+-      int bytes_returned;
+       cFYI(1, ("In CIFSSMBFindClose"));
+       rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
+@@ -3776,16 +3768,13 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon,
+       if (rc)
+               return rc;
+-      pSMBr = (CLOSE_RSP *)pSMB;  /* BB removeme BB */
+       pSMB->FileID = searchHandle;
+       pSMB->ByteCount = 0;
+-      rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+-                       (struct smb_hdr *) pSMBr, &bytes_returned, 0);
++      rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
+       if (rc) {
+               cERROR(1, ("Send error in FindClose = %d", rc));
+       }
+       cifs_stats_inc(&tcon->num_fclose);
+-      cifs_small_buf_release(pSMB);
+       /* Since session is dead, search handle closed on server already */
+       if (rc == -EAGAIN)
+@@ -4707,11 +4696,9 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
+                  __u16 fid, __u32 pid_of_opener, int SetAllocation)
+ {
+       struct smb_com_transaction2_sfi_req *pSMB  = NULL;
+-      struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
+       char *data_offset;
+       struct file_end_of_file_info *parm_data;
+       int rc = 0;
+-      int bytes_returned = 0;
+       __u16 params, param_offset, offset, byte_count, count;
+       cFYI(1, ("SetFileSize (via SetFileInfo) %lld",
+@@ -4721,8 +4708,6 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
+       if (rc)
+               return rc;
+-      pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
+-
+       pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
+       pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
+@@ -4773,17 +4758,13 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
+       pSMB->Reserved4 = 0;
+       pSMB->hdr.smb_buf_length += byte_count;
+       pSMB->ByteCount = cpu_to_le16(byte_count);
+-      rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+-                       (struct smb_hdr *) pSMBr, &bytes_returned, 0);
++      rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
+       if (rc) {
+               cFYI(1,
+                    ("Send error in SetFileInfo (SetFileSize) = %d",
+                     rc));
+       }
+-      if (pSMB)
+-              cifs_small_buf_release(pSMB);
+-
+       /* Note: On -EAGAIN error only caller can retry on handle based calls
+               since file handle passed in no longer valid */
+@@ -4801,10 +4782,8 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon,
+                   const FILE_BASIC_INFO *data, __u16 fid)
+ {
+       struct smb_com_transaction2_sfi_req *pSMB  = NULL;
+-      struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
+       char *data_offset;
+       int rc = 0;
+-      int bytes_returned = 0;
+       __u16 params, param_offset, offset, byte_count, count;
+       cFYI(1, ("Set Times (via SetFileInfo)"));
+@@ -4813,8 +4792,6 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon,
+       if (rc)
+               return rc;
+-      pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
+-
+       /* At this point there is no need to override the current pid
+       with the pid of the opener, but that could change if we someday
+       use an existing handle (rather than opening one on the fly) */
+@@ -4854,14 +4831,11 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon,
+       pSMB->hdr.smb_buf_length += byte_count;
+       pSMB->ByteCount = cpu_to_le16(byte_count);
+       memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
+-      rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+-                       (struct smb_hdr *) pSMBr, &bytes_returned, 0);
++      rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
+       if (rc) {
+               cFYI(1, ("Send error in Set Time (SetFileInfo) = %d", rc));
+       }
+-      cifs_small_buf_release(pSMB);
+-
+       /* Note: On -EAGAIN error only caller can retry on handle based calls
+               since file handle passed in no longer valid */
+@@ -5152,7 +5126,8 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
+       pSMB->ByteCount = 0;
+       rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+-                      (struct smb_hdr *) pSMBr, &bytes_returned, -1);
++                       (struct smb_hdr *)pSMBr, &bytes_returned,
++                       CIFS_ASYNC_OP);
+       if (rc) {
+               cFYI(1, ("Error in Notify = %d", rc));
+       } else {
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index c52a76f..26e1087 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -2374,7 +2374,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
+       pSMB->req_no_secext.ByteCount = cpu_to_le16(count);
+       rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
+-                       &bytes_returned, 1);
++                       &bytes_returned, CIFS_LONG_OP);
+       if (rc) {
+ /* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */
+       } else if ((smb_buffer_response->WordCount == 3)
+@@ -2678,7 +2678,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
+       pSMB->req.ByteCount = cpu_to_le16(count);
+       rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
+-                       &bytes_returned, 1);
++                       &bytes_returned, CIFS_LONG_OP);
+       if (smb_buffer_response->Status.CifsError ==
+           cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
+@@ -3105,7 +3105,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
+       pSMB->req.ByteCount = cpu_to_le16(count);
+       rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
+-                       &bytes_returned, 1);
++                       &bytes_returned, CIFS_LONG_OP);
+       if (rc) {
+ /*   rc = map_smb_to_linux_error(smb_buffer_response) done in SendReceive now */
+       } else if ((smb_buffer_response->WordCount == 3) ||
+@@ -3381,7 +3381,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
+       pSMB->hdr.smb_buf_length += count;
+       pSMB->ByteCount = cpu_to_le16(count);
+-      rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length, 0);
++      rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
++                       CIFS_STD_OP);
+       /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
+       /* above now done in SendReceive */
+diff --git a/fs/cifs/file.c b/fs/cifs/file.c
+index 68ad4ca..82326d2 100644
+--- a/fs/cifs/file.c
++++ b/fs/cifs/file.c
+@@ -835,9 +835,9 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
+       xid = GetXid();
+       if (*poffset > file->f_path.dentry->d_inode->i_size)
+-              long_op = 2; /* writes past end of file can take a long time */
++              long_op = CIFS_VLONG_OP; /* writes past EOF take long time */
+       else
+-              long_op = 1;
++              long_op = CIFS_LONG_OP;
+       for (total_written = 0; write_size > total_written;
+            total_written += bytes_written) {
+@@ -884,7 +884,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
+                       }
+               } else
+                       *poffset += bytes_written;
+-              long_op = FALSE; /* subsequent writes fast -
++              long_op = CIFS_STD_OP; /* subsequent writes fast -
+                                   15 seconds is plenty */
+       }
+@@ -934,9 +934,9 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
+       xid = GetXid();
+       if (*poffset > file->f_path.dentry->d_inode->i_size)
+-              long_op = 2; /* writes past end of file can take a long time */
++              long_op = CIFS_VLONG_OP; /* writes past EOF can be slow */
+       else
+-              long_op = 1;
++              long_op = CIFS_LONG_OP;
+       for (total_written = 0; write_size > total_written;
+            total_written += bytes_written) {
+@@ -1002,7 +1002,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
+                       }
+               } else
+                       *poffset += bytes_written;
+-              long_op = FALSE; /* subsequent writes fast -
++              long_op = CIFS_STD_OP; /* subsequent writes fast -
+                                   15 seconds is plenty */
+       }
+@@ -1360,7 +1360,7 @@ retry:
+                                                  open_file->netfid,
+                                                  bytes_to_write, offset,
+                                                  &bytes_written, iov, n_iov,
+-                                                 1);
++                                                 CIFS_LONG_OP);
+                               atomic_dec(&open_file->wrtPending);
+                               if (rc || bytes_written < bytes_to_write) {
+                                       cERROR(1, ("Write2 ret %d, wrote %d",
+diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
+index 899dc60..ed01ef3 100644
+--- a/fs/cifs/sess.c
++++ b/fs/cifs/sess.c
+@@ -514,7 +514,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
+       iov[1].iov_base = str_area;
+       iov[1].iov_len = count;
+       rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type,
+-                        0 /* not long op */, 1 /* log NT STATUS if any */ );
++                        CIFS_STD_OP /* not long */ | CIFS_LOG_ERROR);
+       /* SMB request buf freed in SendReceive2 */
+       cFYI(1, ("ssetup rc from sendrecv2 is %d", rc));
+diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
+index 7ed32b3..50b623a 100644
+--- a/fs/cifs/transport.c
++++ b/fs/cifs/transport.c
+@@ -308,7 +308,7 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
+ static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op)
+ {
+-      if (long_op == -1) {
++      if (long_op == CIFS_ASYNC_OP) {
+               /* oplock breaks must not be held up */
+               atomic_inc(&ses->server->inFlight);
+       } else {
+@@ -337,7 +337,7 @@ static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op)
+                                  as they are allowed to block on server */
+                               /* update # of requests on the wire to server */
+-                              if (long_op < 3)
++                              if (long_op != CIFS_BLOCKING_OP)
+                                       atomic_inc(&ses->server->inFlight);
+                               spin_unlock(&GlobalMid_Lock);
+                               break;
+@@ -415,17 +415,48 @@ static int wait_for_response(struct cifsSesInfo *ses,
+       }
+ }
++
++/*
++ *
++ * Send an SMB Request.  No response info (other than return code)
++ * needs to be parsed.
++ *
++ * flags indicate the type of request buffer and how long to wait
++ * and whether to log NT STATUS code (error) before mapping it to POSIX error
++ *
++ */
++int
++SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses,
++              struct smb_hdr *in_buf, int flags)
++{
++      int rc;
++      struct kvec iov[1];
++      int resp_buf_type;
++
++      iov[0].iov_base = (char *)in_buf;
++      iov[0].iov_len = in_buf->smb_buf_length + 4;
++      flags |= CIFS_NO_RESP;
++      rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags);
++#ifdef CONFIG_CIFS_DEBUG2
++      cFYI(1, ("SendRcvNoR flags %d rc %d", flags, rc));
++#endif
++      return rc;
++}
++
+ int
+ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
+            struct kvec *iov, int n_vec, int *pRespBufType /* ret */,
+-           const int long_op, const int logError)
++           const int flags)
+ {
+       int rc = 0;
++      int long_op;
+       unsigned int receive_len;
+       unsigned long timeout;
+       struct mid_q_entry *midQ;
+       struct smb_hdr *in_buf = iov[0].iov_base;
++      long_op = flags & CIFS_TIMEOUT_MASK;
++
+       *pRespBufType = CIFS_NO_BUFFER;  /* no response buf yet */
+       if ((ses == NULL) || (ses->server == NULL)) {
+@@ -483,15 +514,22 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
+       if (rc < 0)
+               goto out;
+-      if (long_op == -1)
+-              goto out;
+-      else if (long_op == 2) /* writes past end of file can take loong time */
++      if (long_op == CIFS_STD_OP)
++              timeout = 15 * HZ;
++      else if (long_op == CIFS_VLONG_OP) /* e.g. slow writes past EOF */
+               timeout = 180 * HZ;
+-      else if (long_op == 1)
++      else if (long_op == CIFS_LONG_OP)
+               timeout = 45 * HZ; /* should be greater than
+                       servers oplock break timeout (about 43 seconds) */
+-      else
+-              timeout = 15 * HZ;
++      else if (long_op == CIFS_ASYNC_OP)
++              goto out;
++      else if (long_op == CIFS_BLOCKING_OP)
++              timeout = 0x7FFFFFFF; /*  large, but not so large as to wrap */
++      else {
++              cERROR(1, ("unknown timeout flag %d", long_op));
++              rc = -EIO;
++              goto out;
++      }
+       /* wait for 15 seconds or until woken up due to response arriving or
+          due to last connection to this server being unmounted */
+@@ -566,7 +604,8 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
+                       }
+                       /* BB special case reconnect tid and uid here? */
+-                      rc = map_smb_to_linux_error(midQ->resp_buf, logError);
++                      rc = map_smb_to_linux_error(midQ->resp_buf,
++                                              flags & CIFS_LOG_ERROR);
+                       /* convert ByteCount if necessary */
+                       if (receive_len >= sizeof(struct smb_hdr) - 4
+@@ -574,8 +613,10 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
+                           (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ )
+                               BCC(midQ->resp_buf) =
+                                       le16_to_cpu(BCC_LE(midQ->resp_buf));
+-                      midQ->resp_buf = NULL;  /* mark it so will not be freed
+-                                              by DeleteMidQEntry */
++                      if ((flags & CIFS_NO_RESP) == 0)
++                              midQ->resp_buf = NULL;  /* mark it so buf will
++                                                         not be freed by
++                                                         DeleteMidQEntry */
+               } else {
+                       rc = -EIO;
+                       cFYI(1, ("Bad MID state?"));
+@@ -663,17 +704,25 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
+       if (rc < 0)
+               goto out;
+-      if (long_op == -1)
++      if (long_op == CIFS_STD_OP)
++              timeout = 15 * HZ;
++      /* wait for 15 seconds or until woken up due to response arriving or
++         due to last connection to this server being unmounted */
++      else if (long_op == CIFS_ASYNC_OP)
+               goto out;
+-      else if (long_op == 2) /* writes past end of file can take loong time */
++      else if (long_op == CIFS_VLONG_OP) /* writes past EOF can be slow */
+               timeout = 180 * HZ;
+-      else if (long_op == 1)
++      else if (long_op == CIFS_LONG_OP)
+               timeout = 45 * HZ; /* should be greater than
+                       servers oplock break timeout (about 43 seconds) */
+-      else
+-              timeout = 15 * HZ;
+-      /* wait for 15 seconds or until woken up due to response arriving or
+-         due to last connection to this server being unmounted */
++      else if (long_op == CIFS_BLOCKING_OP)
++              timeout = 0x7FFFFFFF; /* large but no so large as to wrap */
++      else {
++              cERROR(1, ("unknown timeout flag %d", long_op));
++              rc = -EIO;
++              goto out;
++      }
++
+       if (signal_pending(current)) {
+               /* if signal pending do not hold up user for full smb timeout
+               but we still give response a chance to complete */
+@@ -812,7 +861,7 @@ send_lock_cancel(const unsigned int xid, struct cifsTconInfo *tcon,
+       pSMB->hdr.Mid = GetNextMid(ses->server);
+       return SendReceive(xid, ses, in_buf, out_buf,
+-                      &bytes_returned, 0);
++                      &bytes_returned, CIFS_STD_OP);
+ }
+ int
+@@ -844,7 +893,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
+          to the same server. We may make this configurable later or
+          use ses->maxReq */
+-      rc = wait_for_free_request(ses, 3);
++      rc = wait_for_free_request(ses, CIFS_BLOCKING_OP);
+       if (rc)
+               return rc;
+-
+To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
+the body of a message to majordomo@vger.kernel.org
+More majordomo info at  http://vger.kernel.org/majordomo-info.html
+
+----- End forwarded message -----
+-- 
+maks
+
+_______________________________________________
+stable mailing list
+stable@linux.kernel.org
+http://linux.kernel.org/mailman/listinfo/stable
+
diff --git a/queue-2.6.23/cifs-respect-umask-when-using-posix-mkdir.patch b/queue-2.6.23/cifs-respect-umask-when-using-posix-mkdir.patch
new file mode 100644 (file)
index 0000000..dc4b2ec
--- /dev/null
@@ -0,0 +1,38 @@
+From stable-bounces@linux.kernel.org Mon Dec 17 14:10:07 2007
+From: Steve French <sfrench@us.ibm.com>
+Date: Mon, 17 Dec 2007 23:08:58 +0100
+Subject: CIFS: Respect umask when using POSIX mkdir
+To: stable@kernel.org
+Cc: Steve French <sfrench@us.ibm.com>, Jeff <jlayton@redhat.com>
+Message-ID: <20071217220858.GG29139@stro.at>
+Content-Disposition: inline
+
+From: Steve French <sfrench@us.ibm.com>
+
+patch a8cd925f74c3b1b6d1192f9e75f9d12cc2ab148a in mainline.
+
+[CIFS] Respect umask when using POSIX mkdir
+
+When making a directory with POSIX mkdir calls, cifs_mkdir does not
+respect the umask.  This patch causes the new POSIX mkdir to create with
+the right mode
+
+Signed-off-by: Jeff Layton <jlayton@redhat.com>
+Signed-off-by: Steve French <sfrench@us.ibm.com>
+Cc: maximilian attems <max@stro.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/cifs/inode.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/cifs/inode.c
++++ b/fs/cifs/inode.c
+@@ -919,6 +919,7 @@ int cifs_mkdir(struct inode *inode, stru
+                       goto mkdir_out;
+               }
++              mode &= ~current->fs->umask;
+               rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT,
+                               mode, NULL /* netfid */, pInfo, &oplock,
+                               full_path, cifs_sb->local_nls,
diff --git a/queue-2.6.23/m68k-export-cachectl.h.patch b/queue-2.6.23/m68k-export-cachectl.h.patch
new file mode 100644 (file)
index 0000000..cc3f39e
--- /dev/null
@@ -0,0 +1,33 @@
+From stable-bounces@linux.kernel.org Mon Dec 17 17:18:52 2007
+From: Matthew Wilcox <matthew@wil.cx>
+Date: Tue, 18 Dec 2007 00:44:43 +0100
+Subject: m68k: Export cachectl.h
+To: stable@kernel.org
+Cc: Matthew Wilcox <matthew@wil.cx>
+Message-ID: <20071217234443.GM29139@stro.at>
+Content-Disposition: inline
+
+From: Matthew Wilcox <matthew@wil.cx>
+
+patch e92042e5c009d84ba741ec4a978a13f260e6ee24 in mainline.
+
+m68k: Export cachectl.h
+
+libffi in GCC 4.2 needs cachectl.h to do its cache flushing.  But we
+don't currently export it.  I believe this patch should do the trick.
+
+Signed-off-by: Matthew Wilcox <matthew@wil.cx>
+Cc: maximilian attems <max@stro.at>
+Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/asm-m68k/Kbuild |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/include/asm-m68k/Kbuild
++++ b/include/asm-m68k/Kbuild
+@@ -1 +1,2 @@
+ include include/asm-generic/Kbuild.asm
++header-y += cachectl.h
diff --git a/queue-2.6.23/md-fix-data-corruption-when-a-degraded-raid5-array-is-reshaped.patch b/queue-2.6.23/md-fix-data-corruption-when-a-degraded-raid5-array-is-reshaped.patch
new file mode 100644 (file)
index 0000000..7268932
--- /dev/null
@@ -0,0 +1,51 @@
+From 0f94e87cdeaaac9f0f9a28a5dd2a5070b87cd3e8 Mon Sep 17 00:00:00 2001
+From: Dan Williams <dan.j.williams@intel.com>
+Date: Tue, 8 Jan 2008 15:32:53 -0800
+Subject: md: fix data corruption when a degraded raid5 array is reshaped
+Message-Id: <200801082332.m08NWrxY005511@imap1.linux-foundation.org>
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+patch 0f94e87cdeaaac9f0f9a28a5dd2a5070b87cd3e8 in mainline.
+
+We currently do not wait for the block from the missing device to be
+computed from parity before copying data to the new stripe layout.
+
+The change in the raid6 code is not techincally needed as we don't delay
+data block recovery in the same way for raid6 yet.  But making the change
+now is safer long-term.
+
+This bug exists in 2.6.23 and 2.6.24-rc
+
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Acked-by: Neil Brown <neilb@suse.de>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/md/raid5.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/md/raid5.c
++++ b/drivers/md/raid5.c
+@@ -2875,7 +2875,8 @@ static void handle_stripe5(struct stripe
+               md_done_sync(conf->mddev, STRIPE_SECTORS, 1);
+       }
+-      if (s.expanding && s.locked == 0)
++      if (s.expanding && s.locked == 0 &&
++          !test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending))
+               handle_stripe_expansion(conf, sh, NULL);
+       if (sh->ops.count)
+@@ -3077,7 +3078,8 @@ static void handle_stripe6(struct stripe
+               md_done_sync(conf->mddev, STRIPE_SECTORS, 1);
+       }
+-      if (s.expanding && s.locked == 0)
++      if (s.expanding && s.locked == 0 &&
++          !test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending))
+               handle_stripe_expansion(conf, sh, &r6s);
+       spin_unlock(&sh->lock);
diff --git a/queue-2.6.23/security-protect-from-stack-expantion-into-low-vm-addresses.patch b/queue-2.6.23/security-protect-from-stack-expantion-into-low-vm-addresses.patch
new file mode 100644 (file)
index 0000000..d1b05a0
--- /dev/null
@@ -0,0 +1,44 @@
+From 8869477a49c3e99def1fcdadd6bbc407fea14b45 Mon Sep 17 00:00:00 2001
+From: Eric Paris <eparis@redhat.com>
+Date: Mon, 26 Nov 2007 18:47:26 -0500
+Subject: security: protect from stack expantion into low vm addresses
+
+From: Eric Paris <eparis@redhat.com>
+
+patch 8869477a49c3e99def1fcdadd6bbc407fea14b45 in mainline.
+
+Add security checks to make sure we are not attempting to expand the
+stack into memory protected by mmap_min_addr
+
+Signed-off-by: Eric Paris <eparis@redhat.com>
+Signed-off-by: James Morris <jmorris@namei.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ mm/mmap.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -1619,6 +1619,12 @@ static inline int expand_downwards(struc
+        */
+       if (unlikely(anon_vma_prepare(vma)))
+               return -ENOMEM;
++
++      address &= PAGE_MASK;
++      error = security_file_mmap(0, 0, 0, 0, address, 1);
++      if (error)
++              return error;
++
+       anon_vma_lock(vma);
+       /*
+@@ -1626,8 +1632,6 @@ static inline int expand_downwards(struc
+        * is required to hold the mmap_sem in read mode.  We need the
+        * anon_vma lock to serialize against concurrent expand_stacks.
+        */
+-      address &= PAGE_MASK;
+-      error = 0;
+       /* Somebody else might have raced and expanded it already */
+       if (address < vma->vm_start) {
index 81f8e5700d0f4e15192480d9643dc5d70e0044de..b2f25a46b680542f91e4406c5d45fa4ecf433a18 100644 (file)
@@ -53,3 +53,8 @@ input-joydev-implement-proper-locking.patch
 input-tsdev-implement-proper-locking.patch
 input-use-full-rcu-api.patch
 input-fix-open-count-handling-in-input-interfaces.patch
+cifs-respect-umask-when-using-posix-mkdir.patch
+m68k-export-cachectl.h.patch
+vm-security-add-security-hook-to-do_brk.patch
+security-protect-from-stack-expantion-into-low-vm-addresses.patch
+md-fix-data-corruption-when-a-degraded-raid5-array-is-reshaped.patch
diff --git a/queue-2.6.23/vm-security-add-security-hook-to-do_brk.patch b/queue-2.6.23/vm-security-add-security-hook-to-do_brk.patch
new file mode 100644 (file)
index 0000000..e66dbd1
--- /dev/null
@@ -0,0 +1,46 @@
+From stable-bounces@linux.kernel.org Wed Dec 19 05:00:00 2007
+From: Eric Paris <eparis@redhat.com>
+Date: Wed, 19 Dec 2007 13:59:32 +0100
+Subject: VM/Security: add security hook to do_brk (CVE-2007-6434)
+To: stable@kernel.org
+Cc: Eric Paris <eparis@redhat.com>
+Message-ID: <20071219125931.GF4472@stro.at>
+Content-Disposition: inline
+
+From: Eric Paris <eparis@redhat.com>
+
+patch ecaf18c15aac8bb9bed7b7aa0e382fe252e275d5 in mainline.
+
+VM/Security: add security hook to do_brk
+
+Given a specifically crafted binary do_brk() can be used to get low pages
+available in userspace virtual memory and can thus be used to circumvent
+the mmap_min_addr low memory protection.  Add security checks in do_brk().
+
+Signed-off-by: Eric Paris <eparis@redhat.com>
+Acked-by: Alan Cox <alan@redhat.com>
+Cc: Stephen Smalley <sds@tycho.nsa.gov>
+Cc: James Morris <jmorris@namei.org>
+Cc: Chris Wright <chrisw@sous-sol.org>
+Cc: maximilian attems <max@stro.at>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ mm/mmap.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -1938,6 +1938,10 @@ unsigned long do_brk(unsigned long addr,
+       if (is_hugepage_only_range(mm, addr, len))
+               return -EINVAL;
++      error = security_file_mmap(0, 0, 0, 0, addr, 1);
++      if (error)
++              return error;
++
+       flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
+       error = arch_mmap_check(addr, len, flags);