summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Buchholz <rbu@gentoo.org>2008-02-20 00:07:00 +0000
committerRobert Buchholz <rbu@gentoo.org>2008-02-20 00:07:00 +0000
commit4fa4a321731bee0dc7ced70667a2539150968f50 (patch)
tree200601e868c1087146b986f07c8b8501f9a8f06d
parentReleasing 2.6.18-9 (diff)
downloadxen-4fa4a321731bee0dc7ced70667a2539150968f50.tar.gz
xen-4fa4a321731bee0dc7ced70667a2539150968f50.tar.bz2
xen-4fa4a321731bee0dc7ced70667a2539150968f50.zip
Update to current set of Security patches for 2.6.18
svn path=/patches/; revision=67
-rw-r--r--trunk/2.6.18/00000_README87
-rw-r--r--trunk/2.6.18/30044_cifs-better-failed-mount-errors.patch234
-rw-r--r--trunk/2.6.18/30045_cifs-corrupt-server-response-overflow.patch694
-rw-r--r--trunk/2.6.18/30046_wait_task_stopped-hang.patch38
-rw-r--r--trunk/2.6.18/30047_ieee80211-underflow.patch54
-rw-r--r--trunk/2.6.18/30048_sysfs_readdir-NULL-deref-1.patch112
-rw-r--r--trunk/2.6.18/30049_sysfs_readdir-NULL-deref-2.patch128
-rw-r--r--trunk/2.6.18/30050_sysfs-fix-condition-check.patch29
-rw-r--r--trunk/2.6.18/30051_tmpfs-restore-clear_highpage.patch44
-rw-r--r--trunk/2.6.18/30052_minixfs-printk-hang.patch76
-rw-r--r--trunk/2.6.18/30053_hrtimer-large-relative-timeouts-overflow.patch45
-rw-r--r--trunk/2.6.18/30054_coredump-only-to-same-uid.patch38
-rw-r--r--trunk/2.6.18/30055_isdn-net-overflow.patch54
-rw-r--r--trunk/2.6.18/30056_proc-snd-page-alloc-mem-leak.patch169
-rw-r--r--trunk/2.6.18/30057_fat-move-ioctl-compat-code.patch167
-rw-r--r--trunk/2.6.18/30058_fat-fix-compat-ioctls.patch311
-rw-r--r--trunk/2.6.18/30059_vfs-use-access-mode-flag.patch52
-rw-r--r--trunk/2.6.18/30060_i4l-isdn_ioctl-mem-overrun.patch56
-rw-r--r--trunk/2.6.18/30061_vmsplice-security.patch28
-rw-r--r--trunk/2.6.18/30062_clear-spurious-irq.patch34
20 files changed, 2450 insertions, 0 deletions
diff --git a/trunk/2.6.18/00000_README b/trunk/2.6.18/00000_README
index 3eae5d1..9202654 100644
--- a/trunk/2.6.18/00000_README
+++ b/trunk/2.6.18/00000_README
@@ -196,9 +196,96 @@ Patches
fix for CVE-2007-2242. Thanks to Brian Haley for the patch.
(closes: Debian #440127)
+/* This is already in Xen 3.2
30042_reset-pdeathsig-on-suid-upstream.patch
Update fix for CVE-2007-3848 with the patch accepted upstream
(formerly 30013_reset-pdeathsig-on-suid.patch)
+*/
+
+30043_don-t-leak-nt-bit-into-next-task-xen.patch
+ [SECURITY] Don't leak NT bit into next task (Xen).
+ See CVE-2006-5755
+
+30044_cifs-better-failed-mount-errors.patch,
+30045_cifs-corrupt-server-response-overflow.patch
+ [SECURITY][CIFS] Fix multiple overflows that can be remotely triggered
+ by a server sending a corrupt response.
+ See CVE-2007-5904
+
+30046_wait_task_stopped-hang.patch
+ [SECURITY] wait_task_stopped was incorrectly testing for TASK_TRACED -
+ check p->exit_state instead avoiding a potential system hang
+ See CVE-2007-5500
+
+30047_ieee80211-underflow.patch
+ [SECURITY] Fix integer overflow in ieee80211 which makes it possible
+ for a malicious frame to crash a system using a driver built on top of
+ the Linux 802.11 wireless code.
+ See CVE-2007-4997
+
+30048_sysfs_readdir-NULL-deref-1.patch,
+30049_sysfs_readdir-NULL-deref-2.patch,
+30050_sysfs-fix-condition-check.patch
+ [SECURITY] Fix potential NULL pointer dereference which can lead to
+ a local DoS (kernel oops)
+ See CVE-2007-3104
+
+30051_tmpfs-restore-clear_highpage.patch
+ [SECURITY] Fix a theoretical kernel memory leak in the tmpfs filesystem
+ See CVE-2007-6417
+
+30052_minixfs-printk-hang.patch
+ [SECURITY] Rate-limit printks caused by accessing a corrupted minixfs
+ filesystem that would otherwise cause a system to hang (printk storm)
+ See CVE-2006-6058
+
+30053_hrtimer-large-relative-timeouts-overflow.patch
+ [SECURITY] Avoid overflow in hrtimers due to large relative timeouts
+ See CVE-2007-5966
+
+30054_coredump-only-to-same-uid.patch
+ [SECURITY] Fix an issue where core dumping over a file that
+ already exists retains the ownership of the original file
+ See CVE-2007-6206
+
+30055_isdn-net-overflow.patch
+ [SECURITY] Fix potential overflows in the ISDN subsystem
+ See CVE-2007-6063
+
+30056_proc-snd-page-alloc-mem-leak.patch
+ [SECURITY][ABI Changer] Fix an issue in the alsa subsystem that allows a
+ local user to read potentially sensitive kernel memory from the proc
+ filesystem
+ See CVE-2007-4571
+
+30057_fat-move-ioctl-compat-code.patch
+30058_bugfix/fat-fix-compat-ioctls.patch
+ [SECURITY][ABI Changer] Fix kernel_dirent corruption in the compat layer
+ for fat ioctls
+ See CVE-2007-2878
+
+30059_vfs-use-access-mode-flag.patch
+ [SECURITY] Use the access mode flag instead of the open flag when
+ testing access mode for a directory. Modify
+ features/all/vserver/vs2.0.2.2-rc9.patch to apply on top of this
+ See CVE-2008-0001
+
+30060_i4l-isdn_ioctl-mem-overrun.patch
+ [SECURITY] Fix potential isdn ioctl memory overrun
+ See CVE-2007-6151
+
+30061_vmsplice-security.patch
+ [SECURITY] Fix missing access check in vmsplice.
+ See CVE-2008-0010, CVE-2008-0600
+
+30062_clear-spurious-irq.patch
+ Fix a minor denial of service issue that allows local users to disable
+ an interrupt by causing an interrupt handler to be quickly inserted/removed.
+ This has only been shown to happen with certain serial devices so can only
+ be triggered by a user who already has additional priveleges (dialout
+ group). (closes: Debian #404815)
+
+
50009_gentooify-tls-warning.patch
Change tls warning instructions to apply directly to Gentoo.
diff --git a/trunk/2.6.18/30044_cifs-better-failed-mount-errors.patch b/trunk/2.6.18/30044_cifs-better-failed-mount-errors.patch
new file mode 100644
index 0000000..d3b7c91
--- /dev/null
+++ b/trunk/2.6.18/30044_cifs-better-failed-mount-errors.patch
@@ -0,0 +1,234 @@
+From: Steve French <sfrench@us.ibm.com>
+Date: Thu, 18 Oct 2007 21:45:27 +0000 (+0000)
+Subject: [CIFS] log better errors on failed mounts
+X-Git-Tag: v2.6.24-rc1~138^2
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=a761ac579b89bc1f00212a42401398108deba65c
+
+[CIFS] log better errors on failed mounts
+
+Also returns more accurate errors to mount for the cases of
+account expired and password expired
+
+Acked-by: Jeff Layton <jlayton@redhat.com>
+Signed-off-by: Steve French <sfrench@us.ibm.com>
+---
+
+Backported to Debian's 2.6.18 by dann frazier <dannf@debian.org>
+
+diff -urpN linux-source-2.6.18.orig/fs/cifs/cifsproto.h linux-source-2.6.18/fs/cifs/cifsproto.h
+--- linux-source-2.6.18.orig/fs/cifs/cifsproto.h 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/fs/cifs/cifsproto.h 2007-11-25 14:13:04.000000000 -0700
+@@ -49,7 +49,8 @@ extern int SendReceive(const unsigned in
+ int * /* bytes returned */ , const int long_op);
+ extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *,
+ struct kvec *, int /* nvec to send */,
+- int * /* type of buf returned */ , const int long_op);
++ int * /* type of buf returned */ , const int long_op,
++ const int logError /* whether to log status code*/ );
+ extern int SendReceiveBlockingLock(const unsigned int /* xid */ , struct cifsTconInfo *,
+ struct smb_hdr * /* input */ ,
+ struct smb_hdr * /* out */ ,
+@@ -64,7 +65,7 @@ extern unsigned int smbCalcSize_LE(struc
+ extern int decode_negTokenInit(unsigned char *security_blob, int length,
+ enum securityEnum *secType);
+ extern int cifs_inet_pton(int, char * source, void *dst);
+-extern int map_smb_to_linux_error(struct smb_hdr *smb);
++extern int map_smb_to_linux_error(struct smb_hdr *smb, int logErr);
+ extern void header_assemble(struct smb_hdr *, char /* command */ ,
+ const struct cifsTconInfo *, int /* length of
+ fixed section (word count) in two byte units */);
+diff -urpN linux-source-2.6.18.orig/fs/cifs/cifssmb.c linux-source-2.6.18/fs/cifs/cifssmb.c
+--- linux-source-2.6.18.orig/fs/cifs/cifssmb.c 2007-10-03 12:38:14.000000000 -0600
++++ linux-source-2.6.18/fs/cifs/cifssmb.c 2007-11-25 14:14:07.000000000 -0700
+@@ -1170,9 +1170,8 @@ CIFSSMBRead(const int xid, struct cifsTc
+
+ 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);
++ rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
++ &resp_buf_type, 0 /* not long op */, 1 /* log err */ );
+ cifs_stats_inc(&tcon->num_reads);
+ pSMBr = (READ_RSP *)iov[0].iov_base;
+ if (rc) {
+@@ -1389,7 +1388,7 @@ CIFSSMBWrite2(const int xid, struct cifs
+
+
+ rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type,
+- long_op);
++ long_op, 0 /* do not log STATUS code */ );
+ cifs_stats_inc(&tcon->num_writes);
+ if (rc) {
+ cFYI(1, ("Send error Write2 = %d", rc));
+@@ -2822,7 +2821,8 @@ CIFSSMBGetCIFSACL(const int xid, struct
+ iov[0].iov_base = (char *)pSMB;
+ iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
+
+- rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, 0);
++ rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
++ 0 /* not long op */, 0 /* do not log STATUS codes */ );
+ cifs_stats_inc(&tcon->num_acl_get);
+ if (rc) {
+ cFYI(1, ("Send error in QuerySecDesc = %d", rc));
+diff -urpN linux-source-2.6.18.orig/fs/cifs/netmisc.c linux-source-2.6.18/fs/cifs/netmisc.c
+--- linux-source-2.6.18.orig/fs/cifs/netmisc.c 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/fs/cifs/netmisc.c 2007-11-25 14:16:03.000000000 -0700
+@@ -114,10 +114,16 @@ static const struct smb_to_posix_error m
+ {ERRusempx, -EIO},
+ {ERRusestd, -EIO},
+ {ERR_NOTIFY_ENUM_DIR, -ENOBUFS},
+- {ERRaccountexpired, -EACCES},
++ {ERRnoSuchUser, -EACCES},
++/* {ERRaccountexpired, -EACCES},
+ {ERRbadclient, -EACCES},
+ {ERRbadLogonTime, -EACCES},
+- {ERRpasswordExpired, -EACCES},
++ {ERRpasswordExpired, -EACCES},*/
++ {ERRaccountexpired, -EKEYEXPIRED},
++ {ERRbadclient, -EACCES},
++ {ERRbadLogonTime, -EACCES},
++ {ERRpasswordExpired, -EKEYEXPIRED},
++
+ {ERRnosupport, -EINVAL},
+ {0, 0}
+ };
+@@ -314,7 +320,7 @@ static const struct {
+ from NT_STATUS_NO_SUCH_USER to NT_STATUS_LOGON_FAILURE
+ during the session setup } */
+ {
+- ERRDOS, ERRnoaccess, NT_STATUS_NO_SUCH_USER}, {
++ ERRDOS, ERRnoaccess, NT_STATUS_NO_SUCH_USER}, { /* could map to 2238 */
+ ERRHRD, ERRgeneral, NT_STATUS_GROUP_EXISTS}, {
+ ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_GROUP}, {
+ ERRHRD, ERRgeneral, NT_STATUS_MEMBER_IN_GROUP}, {
+@@ -329,10 +335,10 @@ static const struct {
+ ERRHRD, ERRgeneral, NT_STATUS_PASSWORD_RESTRICTION}, {
+ ERRDOS, ERRnoaccess, NT_STATUS_LOGON_FAILURE}, {
+ ERRHRD, ERRgeneral, NT_STATUS_ACCOUNT_RESTRICTION}, {
+- ERRSRV, 2241, NT_STATUS_INVALID_LOGON_HOURS}, {
+- ERRSRV, 2240, NT_STATUS_INVALID_WORKSTATION}, {
++ ERRSRV, ERRbadLogonTime, NT_STATUS_INVALID_LOGON_HOURS}, {
++ ERRSRV, ERRbadclient, NT_STATUS_INVALID_WORKSTATION}, {
+ ERRSRV, ERRpasswordExpired, NT_STATUS_PASSWORD_EXPIRED}, {
+- ERRSRV, 2239, NT_STATUS_ACCOUNT_DISABLED}, {
++ ERRSRV, ERRaccountexpired, NT_STATUS_ACCOUNT_DISABLED}, {
+ ERRHRD, ERRgeneral, NT_STATUS_NONE_MAPPED}, {
+ ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_LUIDS_REQUESTED}, {
+ ERRHRD, ERRgeneral, NT_STATUS_LUIDS_EXHAUSTED}, {
+@@ -629,7 +635,7 @@ static const struct {
+ ERRDOS, ERRnoaccess, NT_STATUS_TRUST_FAILURE}, {
+ ERRHRD, ERRgeneral, NT_STATUS_MUTANT_LIMIT_EXCEEDED}, {
+ ERRDOS, ERRnetlogonNotStarted, NT_STATUS_NETLOGON_NOT_STARTED}, {
+- ERRSRV, 2239, NT_STATUS_ACCOUNT_EXPIRED}, {
++ ERRSRV, ERRaccountexpired, NT_STATUS_ACCOUNT_EXPIRED}, {
+ ERRHRD, ERRgeneral, NT_STATUS_POSSIBLE_DEADLOCK}, {
+ ERRHRD, ERRgeneral, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT}, {
+ ERRHRD, ERRgeneral, NT_STATUS_REMOTE_SESSION_LIMIT}, {
+@@ -798,7 +804,7 @@ ntstatus_to_dos(__u32 ntstatus, __u8 * e
+ }
+
+ int
+-map_smb_to_linux_error(struct smb_hdr *smb)
++map_smb_to_linux_error(struct smb_hdr *smb, int logErr)
+ {
+ unsigned int i;
+ int rc = -EIO; /* if transport error smb error may not be set */
+@@ -814,7 +820,9 @@ map_smb_to_linux_error(struct smb_hdr *s
+ if (smb->Flags2 & SMBFLG2_ERR_STATUS) {
+ /* translate the newer STATUS codes to old style errors and then to POSIX errors */
+ __u32 err = le32_to_cpu(smb->Status.CifsError);
+- if(cifsFYI & CIFS_RC)
++ if (logErr && (err != (NT_STATUS_MORE_PROCESSING_REQUIRED)))
++ cifs_print_status(err);
++ else if (cifsFYI & CIFS_RC)
+ cifs_print_status(err);
+ ntstatus_to_dos(err, &smberrclass, &smberrcode);
+ } else {
+@@ -854,7 +862,8 @@ map_smb_to_linux_error(struct smb_hdr *s
+ }
+ /* else ERRHRD class errors or junk - return EIO */
+
+- cFYI(1, (" !!Mapping smb error code %d to POSIX err %d !!", smberrcode,rc));
++ cFYI(1, ("Mapping smb error code %d to POSIX err %d",
++ smberrcode, rc));
+
+ /* generic corrective action e.g. reconnect SMB session on ERRbaduid could be added */
+
+diff -urpN linux-source-2.6.18.orig/fs/cifs/sess.c linux-source-2.6.18/fs/cifs/sess.c
+--- linux-source-2.6.18.orig/fs/cifs/sess.c 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/fs/cifs/sess.c 2007-11-25 14:17:16.000000000 -0700
+@@ -482,7 +482,8 @@ CIFS_SessSetup(unsigned int xid, struct
+
+ iov[1].iov_base = str_area;
+ iov[1].iov_len = count;
+- rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type, 0);
++ rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type,
++ 0 /* not long op */, 1 /* log NT STATUS if any */ );
+ /* SMB request buf freed in SendReceive2 */
+
+ cFYI(1,("ssetup rc from sendrecv2 is %d",rc));
+diff -urpN linux-source-2.6.18.orig/fs/cifs/smberr.h linux-source-2.6.18/fs/cifs/smberr.h
+--- linux-source-2.6.18.orig/fs/cifs/smberr.h 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/fs/cifs/smberr.h 2007-11-25 14:12:02.000000000 -0700
+@@ -173,9 +173,10 @@
+ #define ERRusestd 251 /* temporarily unable to use either raw
+ or mpx */
+ #define ERR_NOTIFY_ENUM_DIR 1024
++#define ERRnoSuchUser 2238 /* user account does not exist */
+ #define ERRaccountexpired 2239
+-#define ERRbadclient 2240
+-#define ERRbadLogonTime 2241
++#define ERRbadclient 2240 /* can not logon from this client */
++#define ERRbadLogonTime 2241 /* logon hours do not allow this */
+ #define ERRpasswordExpired 2242
+ #define ERRnetlogonNotStarted 2455
+ #define ERRnosupport 0xFFFF
+diff -urpN linux-source-2.6.18.orig/fs/cifs/transport.c linux-source-2.6.18/fs/cifs/transport.c
+--- linux-source-2.6.18.orig/fs/cifs/transport.c 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/fs/cifs/transport.c 2007-11-25 14:18:15.000000000 -0700
+@@ -419,7 +419,7 @@ static int wait_for_response(struct cifs
+ int
+ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
+ struct kvec *iov, int n_vec, int * pRespBufType /* ret */,
+- const int long_op)
++ const int long_op, const int logError)
+ {
+ int rc = 0;
+ unsigned int receive_len;
+@@ -465,7 +465,6 @@ SendReceive2(const unsigned int xid, str
+ wake_up(&ses->server->request_q);
+ return rc;
+ }
+-
+ rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number);
+
+ midQ->midState = MID_REQUEST_SUBMITTED;
+@@ -568,8 +567,7 @@ SendReceive2(const unsigned int xid, str
+ }
+
+ /* BB special case reconnect tid and uid here? */
+- /* BB special case Errbadpassword and pwdexpired here */
+- rc = map_smb_to_linux_error(midQ->resp_buf);
++ rc = map_smb_to_linux_error(midQ->resp_buf, logError);
+
+ /* convert ByteCount if necessary */
+ if (receive_len >=
+@@ -750,7 +748,7 @@ SendReceive(const unsigned int xid, stru
+ *pbytes_returned = out_buf->smb_buf_length;
+
+ /* BB special case reconnect tid and uid here? */
+- rc = map_smb_to_linux_error(out_buf);
++ rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
+
+ /* convert ByteCount if necessary */
+ if (receive_len >=
+@@ -995,7 +993,7 @@ SendReceiveBlockingLock(const unsigned i
+ *pbytes_returned = out_buf->smb_buf_length;
+
+ /* BB special case reconnect tid and uid here? */
+- rc = map_smb_to_linux_error(out_buf);
++ rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
+
+ /* convert ByteCount if necessary */
+ if (receive_len >=
diff --git a/trunk/2.6.18/30045_cifs-corrupt-server-response-overflow.patch b/trunk/2.6.18/30045_cifs-corrupt-server-response-overflow.patch
new file mode 100644
index 0000000..eb79c7b
--- /dev/null
+++ b/trunk/2.6.18/30045_cifs-corrupt-server-response-overflow.patch
@@ -0,0 +1,694 @@
+From: Steve French <sfrench@us.ibm.com>
+Date: Tue, 13 Nov 2007 22:41:37 +0000 (+0000)
+Subject: [CIFS] Fix buffer overflow if server sends corrupt response to small
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fsfrench%2Fcifs-2.6.git;a=commitdiff_plain;h=133672efbc1085f9af990bdc145e1822ea93bcf3
+
+[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>
+Acked-by: Jeff Layton <jlayton@redhat.com>
+Signed-off-by: Steve French <sfrench@us.ibm.com>
+---
+
+Backported to Debian's 2.6.18 by dann frazier <dannf@debian.org>
+
+diff -urpN linux-source-2.6.18.orig/fs/cifs/cifsglob.h linux-source-2.6.18/fs/cifs/cifsglob.h
+--- linux-source-2.6.18.orig/fs/cifs/cifsglob.h 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/fs/cifs/cifsglob.h 2007-11-25 14:19:26.000000000 -0700
+@@ -437,6 +437,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 -urpN linux-source-2.6.18.orig/fs/cifs/cifsproto.h linux-source-2.6.18/fs/cifs/cifsproto.h
+--- linux-source-2.6.18.orig/fs/cifs/cifsproto.h 2007-11-25 14:13:04.000000000 -0700
++++ linux-source-2.6.18/fs/cifs/cifsproto.h 2007-11-25 14:21:47.000000000 -0700
+@@ -47,10 +47,11 @@ extern int SendReceive(const unsigned in
+ 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 */ ,
+ struct smb_hdr * /* out */ ,
+diff -urpN linux-source-2.6.18.orig/fs/cifs/cifssmb.c linux-source-2.6.18/fs/cifs/cifssmb.c
+--- linux-source-2.6.18.orig/fs/cifs/cifssmb.c 2007-11-25 14:14:07.000000000 -0700
++++ linux-source-2.6.18/fs/cifs/cifssmb.c 2007-11-25 14:26:03.000000000 -0700
+@@ -619,9 +619,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"));
+ /*
+@@ -658,16 +656,12 @@ CIFSSMBTDis(const int xid, struct cifsTc
+ 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
+@@ -681,10 +675,8 @@ CIFSSMBTDis(const int xid, struct cifsTc
+ 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)
+@@ -703,8 +695,6 @@ CIFSSMBLogoff(const int xid, struct cifs
+ return rc;
+ }
+
+- smb_buffer_response = (struct smb_hdr *)pSMB; /* BB removeme BB */
+-
+ if(ses->server) {
+ pSMB->hdr.Mid = GetNextMid(ses->server);
+
+@@ -716,8 +706,7 @@ CIFSSMBLogoff(const int xid, struct cifs
+ 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) {
+@@ -728,7 +717,6 @@ CIFSSMBLogoff(const int xid, struct cifs
+ }
+ }
+ 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
+@@ -978,7 +966,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));
+@@ -1092,7 +1080,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));
+@@ -1171,7 +1159,7 @@ CIFSSMBRead(const int xid, struct cifsTc
+ 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) {
+@@ -1388,7 +1376,7 @@ CIFSSMBWrite2(const int xid, struct cifs
+
+
+ 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));
+@@ -1430,7 +1418,7 @@ CIFSSMBLock(const int xid, struct cifsTc
+ 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)
+@@ -1439,10 +1427,10 @@ CIFSSMBLock(const int xid, struct cifsTc
+ 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;
+@@ -1472,15 +1460,16 @@ CIFSSMBLock(const int xid, struct cifsTc
+ 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 */
+@@ -1500,7 +1489,9 @@ CIFSSMBPosixLock(const int xid, struct c
+ 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"));
+
+@@ -1544,7 +1535,7 @@ CIFSSMBPosixLock(const int xid, struct c
+
+ 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
+@@ -1564,8 +1555,13 @@ CIFSSMBPosixLock(const int xid, struct c
+ 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) {
+@@ -1600,6 +1596,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 */
+
+@@ -1612,8 +1613,6 @@ CIFSSMBClose(const int xid, struct cifsT
+ {
+ 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 */
+@@ -1623,13 +1622,10 @@ CIFSSMBClose(const int xid, struct cifsT
+ if (rc)
+ return rc;
+
+- pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */
+-
+ pSMB->FileID = (__u16) smb_file_id;
+ pSMB->LastWriteTime = 0;
+ 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) {
+@@ -1638,8 +1634,6 @@ CIFSSMBClose(const int xid, struct cifsT
+ }
+ }
+
+- cifs_small_buf_release(pSMB);
+-
+ /* Since session is dead, file will be closed on server already */
+ if(rc == -EAGAIN)
+ rc = 0;
+@@ -2822,7 +2816,7 @@ CIFSSMBGetCIFSACL(const int xid, struct
+ 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));
+@@ -3444,8 +3438,6 @@ CIFSFindClose(const int xid, struct cifs
+ {
+ 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);
+@@ -3457,16 +3449,13 @@ CIFSFindClose(const int xid, struct cifs
+ 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)
+@@ -4373,11 +4362,9 @@ CIFSSMBSetFileSize(const int xid, struct
+ __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",
+@@ -4387,8 +4374,6 @@ CIFSSMBSetFileSize(const int xid, struct
+ 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));
+
+@@ -4439,17 +4424,13 @@ CIFSSMBSetFileSize(const int xid, struct
+ 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 */
+
+@@ -4467,10 +4448,8 @@ CIFSSMBSetFileTimes(const int xid, struc
+ __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)"));
+@@ -4479,8 +4458,6 @@ CIFSSMBSetFileTimes(const int xid, struc
+ 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) */
+@@ -4520,14 +4497,11 @@ CIFSSMBSetFileTimes(const int xid, struc
+ 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 */
+
+@@ -4808,7 +4782,8 @@ int CIFSSMBNotify(const int xid, struct
+ 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 -urpN linux-source-2.6.18.orig/fs/cifs/connect.c linux-source-2.6.18/fs/cifs/connect.c
+--- linux-source-2.6.18.orig/fs/cifs/connect.c 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/fs/cifs/connect.c 2007-11-25 14:19:26.000000000 -0700
+@@ -2148,7 +2148,7 @@ CIFSSessSetup(unsigned int xid, struct c
+ 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)
+@@ -2434,7 +2434,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned i
+ 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))
+@@ -2860,7 +2860,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xi
+ 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)
+@@ -3131,7 +3131,8 @@ CIFSTCon(unsigned int xid, struct cifsSe
+ 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 -urpN linux-source-2.6.18.orig/fs/cifs/file.c linux-source-2.6.18/fs/cifs/file.c
+--- linux-source-2.6.18.orig/fs/cifs/file.c 2007-10-03 12:38:13.000000000 -0600
++++ linux-source-2.6.18/fs/cifs/file.c 2007-11-25 14:20:52.000000000 -0700
+@@ -813,9 +813,9 @@ ssize_t cifs_user_write(struct file *fil
+ }
+
+ if (*poffset > file->f_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) {
+@@ -868,7 +868,7 @@ ssize_t cifs_user_write(struct file *fil
+ }
+ } else
+ *poffset += bytes_written;
+- long_op = FALSE; /* subsequent writes fast -
++ long_op = CIFS_STD_OP; /* subsequent writes fast -
+ 15 seconds is plenty */
+ }
+
+@@ -927,9 +927,9 @@ static ssize_t cifs_write(struct file *f
+ }
+
+ if (*poffset > file->f_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) {
+@@ -1001,7 +1001,7 @@ static ssize_t cifs_write(struct file *f
+ }
+ } else
+ *poffset += bytes_written;
+- long_op = FALSE; /* subsequent writes fast -
++ long_op = CIFS_STD_OP; /* subsequent writes fast -
+ 15 seconds is plenty */
+ }
+
+@@ -1288,7 +1288,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, written = %d",
+diff -urpN linux-source-2.6.18.orig/fs/cifs/sess.c linux-source-2.6.18/fs/cifs/sess.c
+--- linux-source-2.6.18.orig/fs/cifs/sess.c 2007-11-25 14:17:16.000000000 -0700
++++ linux-source-2.6.18/fs/cifs/sess.c 2007-11-25 14:19:26.000000000 -0700
+@@ -483,7 +483,7 @@ CIFS_SessSetup(unsigned int xid, struct
+ 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 -urpN linux-source-2.6.18.orig/fs/cifs/transport.c linux-source-2.6.18/fs/cifs/transport.c
+--- linux-source-2.6.18.orig/fs/cifs/transport.c 2007-11-25 14:18:15.000000000 -0700
++++ linux-source-2.6.18/fs/cifs/transport.c 2007-11-25 14:30:14.000000000 -0700
+@@ -308,7 +308,7 @@ smb_send2(struct socket *ssocket, struct
+
+ 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
+ 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;
+@@ -416,17 +416,48 @@ static int wait_for_response(struct cifs
+ }
+ }
+
++
++/*
++ *
++ * 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)) {
+@@ -484,15 +515,22 @@ SendReceive2(const unsigned int xid, str
+ 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 */
+@@ -567,7 +605,8 @@ SendReceive2(const unsigned int xid, str
+ }
+
+ /* 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 >=
+@@ -576,8 +615,10 @@ SendReceive2(const unsigned int xid, str
+ (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?"));
+@@ -666,17 +707,25 @@ SendReceive(const unsigned int xid, stru
+ 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 change to complete */
+@@ -817,7 +866,7 @@ send_lock_cancel(const unsigned int xid,
+ pSMB->hdr.Mid = GetNextMid(ses->server);
+
+ return SendReceive(xid, ses, in_buf, out_buf,
+- &bytes_returned, 0);
++ &bytes_returned, CIFS_STD_OP);
+ }
+
+ int
+@@ -849,7 +898,7 @@ SendReceiveBlockingLock(const unsigned i
+ 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;
+
diff --git a/trunk/2.6.18/30046_wait_task_stopped-hang.patch b/trunk/2.6.18/30046_wait_task_stopped-hang.patch
new file mode 100644
index 0000000..de602c4
--- /dev/null
+++ b/trunk/2.6.18/30046_wait_task_stopped-hang.patch
@@ -0,0 +1,38 @@
+From: Roland McGrath <roland@redhat.com>
+Date: Wed, 14 Nov 2007 06:11:50 +0000 (-0800)
+Subject: wait_task_stopped: Check p->exit_state instead of TASK_TRACED
+X-Git-Tag: v2.6.24-rc3~12
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=a3474224e6a01924be40a8255636ea5522c1023a
+
+wait_task_stopped: Check p->exit_state instead of TASK_TRACED
+
+The original meaning of the old test (p->state > TASK_STOPPED) was
+"not dead", since it was before TASK_TRACED existed and before the
+state/exit_state split. It was a wrong correction in commit
+14bf01bb0599c89fc7f426d20353b76e12555308 to make this test for
+TASK_TRACED instead. It should have been changed when TASK_TRACED
+was introducted and again when exit_state was introduced.
+
+Signed-off-by: Roland McGrath <roland@redhat.com>
+Cc: Oleg Nesterov <oleg@tv-sign.ru>
+Cc: Alexey Dobriyan <adobriyan@sw.ru>
+Cc: Kees Cook <kees@ubuntu.com>
+Acked-by: Scott James Remnant <scott@ubuntu.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+---
+
+Adjusted to apply to Debian's 2.6.18 by dann frazier <dannf@debian.org>
+
+diff -urpN linux-source-2.6.18.orig/kernel/exit.c linux-source-2.6.18/kernel/exit.c
+--- linux-source-2.6.18.orig/kernel/exit.c 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/kernel/exit.c 2007-11-25 13:39:32.000000000 -0700
+@@ -1287,8 +1287,7 @@ static int wait_task_stopped(struct task
+ int why = (p->ptrace & PT_PTRACED) ? CLD_TRAPPED : CLD_STOPPED;
+
+ exit_code = p->exit_code;
+- if (unlikely(!exit_code) ||
+- unlikely(p->state & TASK_TRACED))
++ if (unlikely(!exit_code) || unlikely(p->exit_state))
+ goto bail_ref;
+ return wait_noreap_copyout(p, pid, uid,
+ why, (exit_code << 8) | 0x7f,
diff --git a/trunk/2.6.18/30047_ieee80211-underflow.patch b/trunk/2.6.18/30047_ieee80211-underflow.patch
new file mode 100644
index 0000000..53c733a
--- /dev/null
+++ b/trunk/2.6.18/30047_ieee80211-underflow.patch
@@ -0,0 +1,54 @@
+From: John W. Linville <linville@tuxdriver.com>
+Date: Tue, 2 Oct 2007 04:03:54 +0000 (-0700)
+Subject: [IEEE80211]: avoid integer underflow for runt rx frames
+X-Git-Tag: kvm-47~34^2~42^2
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Favi%2Fkvm.git;a=commitdiff_plain;h=04045f98e0457aba7d4e6736f37eed189c48a5f7
+
+[IEEE80211]: avoid integer underflow for runt rx frames
+
+Reported by Chris Evans <scarybeasts@gmail.com>:
+
+> The summary is that an evil 80211 frame can crash out a victim's
+> machine. It only applies to drivers using the 80211 wireless code, and
+> only then to certain drivers (and even then depends on a card's
+> firmware not dropping a dubious packet). I must confess I'm not
+> keeping track of Linux wireless support, and the different protocol
+> stacks etc.
+>
+> Details are as follows:
+>
+> ieee80211_rx() does not explicitly check that "skb->len >= hdrlen".
+> There are other skb->len checks, but not enough to prevent a subtle
+> off-by-two error if the frame has the IEEE80211_STYPE_QOS_DATA flag
+> set.
+>
+> This leads to integer underflow and crash here:
+>
+> if (frag != 0)
+> flen -= hdrlen;
+>
+> (flen is subsequently used as a memcpy length parameter).
+
+How about this?
+
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+
+diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
+index f2de2e4..6284c99 100644
+--- a/net/ieee80211/ieee80211_rx.c
++++ b/net/ieee80211/ieee80211_rx.c
+@@ -366,6 +366,12 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
+ frag = WLAN_GET_SEQ_FRAG(sc);
+ hdrlen = ieee80211_get_hdrlen(fc);
+
++ if (skb->len < hdrlen) {
++ printk(KERN_INFO "%s: invalid SKB length %d\n",
++ dev->name, skb->len);
++ goto rx_dropped;
++ }
++
+ /* Put this code here so that we avoid duplicating it in all
+ * Rx paths. - Jean II */
+ #ifdef CONFIG_WIRELESS_EXT
diff --git a/trunk/2.6.18/30048_sysfs_readdir-NULL-deref-1.patch b/trunk/2.6.18/30048_sysfs_readdir-NULL-deref-1.patch
new file mode 100644
index 0000000..c13fd1b
--- /dev/null
+++ b/trunk/2.6.18/30048_sysfs_readdir-NULL-deref-1.patch
@@ -0,0 +1,112 @@
+From: Eric Sandeen <sandeen@sandeen.net>
+Date: Mon, 11 Jun 2007 05:02:45 +0000 (+0900)
+Subject: sysfs: store sysfs inode nrs in s_ino to avoid readdir oopses
+X-Git-Tag: v2.6.22-rc5~47
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fstable%2Flinux-2.6.22.y.git;a=commitdiff_plain;h=dc351252b33f8fede396d6173dba117bcb933607
+
+sysfs: store sysfs inode nrs in s_ino to avoid readdir oopses
+
+Backport of
+ftp://ftp.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.22-rc1/2.6.22-rc1-mm1/broken-out/gregkh-driver-sysfs-allocate-inode-number-using-ida.patch
+
+For regular files in sysfs, sysfs_readdir wants to traverse
+sysfs_dirent->s_dentry->d_inode->i_ino to get to the inode number.
+But, the dentry can be reclaimed under memory pressure, and there is
+no synchronization with readdir. This patch follows Tejun's scheme of
+allocating and storing an inode number in the new s_ino member of a
+sysfs_dirent, when dirents are created, and retrieving it from there
+for readdir, so that the pointer chain doesn't have to be traversed.
+
+Tejun's upstream patch uses a new-ish "ida" allocator which brings
+along some extra complexity; this -stable patch has a brain-dead
+incrementing counter which does not guarantee uniqueness, but because
+sysfs doesn't hash inodes as iunique expects, uniqueness wasn't
+guaranteed today anyway.
+
+Signed-off-by: Eric Sandeen <sandeen@redhat.com>
+Signed-off-by: Tejun Heo <htejun@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+
+Backported to Debian's 2.6.18 by dann frazier <dannf@hp.com>
+
+diff -urpN linux-source-2.6.18.orig/fs/sysfs/dir.c linux-source-2.6.18/fs/sysfs/dir.c
+--- linux-source-2.6.18.orig/fs/sysfs/dir.c 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/fs/sysfs/dir.c 2007-11-07 15:31:11.000000000 -0700
+@@ -29,6 +29,14 @@ static struct dentry_operations sysfs_de
+ .d_iput = sysfs_d_iput,
+ };
+
++static unsigned int sysfs_inode_counter;
++ino_t sysfs_get_inum(void)
++{
++ if (unlikely(sysfs_inode_counter < 3))
++ sysfs_inode_counter = 3;
++ return sysfs_inode_counter++;
++}
++
+ /*
+ * Allocates a new sysfs_dirent and links it to the parent sysfs_dirent
+ */
+@@ -42,6 +50,7 @@ static struct sysfs_dirent * sysfs_new_d
+ return NULL;
+
+ memset(sd, 0, sizeof(*sd));
++ sd->s_ino = sysfs_get_inum();
+ atomic_set(&sd->s_count, 1);
+ atomic_set(&sd->s_event, 0);
+ INIT_LIST_HEAD(&sd->s_children);
+@@ -416,7 +425,7 @@ static int sysfs_readdir(struct file * f
+
+ switch (i) {
+ case 0:
+- ino = dentry->d_inode->i_ino;
++ ino = parent_sd->s_ino;
+ if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
+ break;
+ filp->f_pos++;
+@@ -445,10 +454,7 @@ static int sysfs_readdir(struct file * f
+
+ name = sysfs_get_name(next);
+ len = strlen(name);
+- if (next->s_dentry)
+- ino = next->s_dentry->d_inode->i_ino;
+- else
+- ino = iunique(sysfs_sb, 2);
++ ino = next->s_ino;
+
+ if (filldir(dirent, name, len, filp->f_pos, ino,
+ dt_type(next)) < 0)
+diff -urpN linux-source-2.6.18.orig/fs/sysfs/inode.c linux-source-2.6.18/fs/sysfs/inode.c
+--- linux-source-2.6.18.orig/fs/sysfs/inode.c 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/fs/sysfs/inode.c 2007-11-07 15:30:13.000000000 -0700
+@@ -129,6 +129,7 @@ struct inode * sysfs_new_inode(mode_t mo
+ inode->i_mapping->a_ops = &sysfs_aops;
+ inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info;
+ inode->i_op = &sysfs_inode_operations;
++ inode->i_ino = sd->s_ino;
+ lockdep_set_class(&inode->i_mutex, &sysfs_inode_imutex_key);
+
+ if (sd->s_iattr) {
+diff -urpN linux-source-2.6.18.orig/fs/sysfs/mount.c linux-source-2.6.18/fs/sysfs/mount.c
+--- linux-source-2.6.18.orig/fs/sysfs/mount.c 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/fs/sysfs/mount.c 2007-11-07 15:30:13.000000000 -0700
+@@ -29,6 +29,7 @@ static struct sysfs_dirent sysfs_root =
+ .s_element = NULL,
+ .s_type = SYSFS_ROOT,
+ .s_iattr = NULL,
++ .s_ino = 1,
+ };
+
+ static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
+diff -urpN linux-source-2.6.18.orig/include/linux/sysfs.h linux-source-2.6.18/include/linux/sysfs.h
+--- linux-source-2.6.18.orig/include/linux/sysfs.h 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/include/linux/sysfs.h 2007-11-07 15:34:16.000000000 -0700
+@@ -72,6 +72,7 @@ struct sysfs_dirent {
+ void * s_element;
+ int s_type;
+ umode_t s_mode;
++ ino_t s_ino;
+ struct dentry * s_dentry;
+ struct iattr * s_iattr;
+ atomic_t s_event;
diff --git a/trunk/2.6.18/30049_sysfs_readdir-NULL-deref-2.patch b/trunk/2.6.18/30049_sysfs_readdir-NULL-deref-2.patch
new file mode 100644
index 0000000..e242c17
--- /dev/null
+++ b/trunk/2.6.18/30049_sysfs_readdir-NULL-deref-2.patch
@@ -0,0 +1,128 @@
+From: Tejun Heo <htejun@gmail.com>
+Date: Mon, 11 Jun 2007 05:04:01 +0000 (+0900)
+Subject: sysfs: fix race condition around sd->s_dentry, take#2
+X-Git-Tag: v2.6.22-rc5~45
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fstable%2Flinux-2.6.22.y.git;a=commitdiff_plain;h=dd14cbc994709a1c5a64ed3621f583c49a27e521
+
+sysfs: fix race condition around sd->s_dentry, take#2
+
+Allowing attribute and symlink dentries to be reclaimed means
+sd->s_dentry can change dynamically. However, updates to the field
+are unsynchronized leading to race conditions. This patch adds
+sysfs_lock and use it to synchronize updates to sd->s_dentry.
+
+Due to the locking around ->d_iput, the check in sysfs_drop_dentry()
+is complex. sysfs_lock only protect sd->s_dentry pointer itself. The
+validity of the dentry is protected by dcache_lock, so whether dentry
+is alive or not can only be tested while holding both locks.
+
+This is minimal backport of sysfs_drop_dentry() rewrite in devel
+branch.
+
+Signed-off-by: Tejun Heo <htejun@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+
+Backported to Debian's 2.6.18 by dann frazier <dannf@hp.com>
+
+diff -urpN linux-source-2.6.18.orig/fs/sysfs/dir.c linux-source-2.6.18/fs/sysfs/dir.c
+--- linux-source-2.6.18.orig/fs/sysfs/dir.c 2007-11-07 15:44:57.000000000 -0700
++++ linux-source-2.6.18/fs/sysfs/dir.c 2007-11-07 15:38:57.000000000 -0700
+@@ -12,14 +12,26 @@
+ #include "sysfs.h"
+
+ DECLARE_RWSEM(sysfs_rename_sem);
++spinlock_t sysfs_lock = SPIN_LOCK_UNLOCKED;
+
+ static void sysfs_d_iput(struct dentry * dentry, struct inode * inode)
+ {
+ struct sysfs_dirent * sd = dentry->d_fsdata;
+
+ if (sd) {
+- BUG_ON(sd->s_dentry != dentry);
+- sd->s_dentry = NULL;
++ /* sd->s_dentry is protected with sysfs_lock. This
++ * allows sysfs_drop_dentry() to dereference it.
++ */
++ spin_lock(&sysfs_lock);
++
++ /* The dentry might have been deleted or another
++ * lookup could have happened updating sd->s_dentry to
++ * point the new dentry. Ignore if it isn't pointing
++ * to this dentry.
++ */
++ if (sd->s_dentry == dentry)
++ sd->s_dentry = NULL;
++ spin_unlock(&sysfs_lock);
+ sysfs_put(sd);
+ }
+ iput(inode);
+@@ -218,7 +230,10 @@ static int sysfs_attach_attr(struct sysf
+ }
+
+ dentry->d_fsdata = sysfs_get(sd);
++ /* protect sd->s_dentry against sysfs_d_iput */
++ spin_lock(&sysfs_lock);
+ sd->s_dentry = dentry;
++ spin_unlock(&sysfs_lock);
+ error = sysfs_create(dentry, (attr->mode & S_IALLUGO) | S_IFREG, init);
+ if (error) {
+ sysfs_put(sd);
+@@ -240,7 +255,10 @@ static int sysfs_attach_link(struct sysf
+ int err = 0;
+
+ dentry->d_fsdata = sysfs_get(sd);
++ /* protect sd->s_dentry against sysfs_d_iput */
++ spin_lock(&sysfs_lock);
+ sd->s_dentry = dentry;
++ spin_unlock(&sysfs_lock);
+ err = sysfs_create(dentry, S_IFLNK|S_IRWXUGO, init_symlink);
+ if (!err) {
+ dentry->d_op = &sysfs_dentry_ops;
+diff -urpN linux-source-2.6.18.orig/fs/sysfs/inode.c linux-source-2.6.18/fs/sysfs/inode.c
+--- linux-source-2.6.18.orig/fs/sysfs/inode.c 2007-11-07 15:44:57.000000000 -0700
++++ linux-source-2.6.18/fs/sysfs/inode.c 2007-11-07 15:40:19.000000000 -0700
+@@ -217,8 +217,22 @@ const unsigned char * sysfs_get_name(str
+ */
+ void sysfs_drop_dentry(struct sysfs_dirent * sd, struct dentry * parent)
+ {
+- struct dentry * dentry = sd->s_dentry;
++ struct dentry *dentry = NULL;
+
++ /* We're not holding a reference to ->s_dentry dentry but the
++ * field will stay valid as long as sysfs_lock is held.
++ */
++ spin_lock(&sysfs_lock);
++ spin_lock(&dcache_lock);
++
++ /* dget dentry if it's still alive */
++ if (sd->s_dentry && sd->s_dentry->d_inode)
++ dentry = dget_locked(sd->s_dentry);
++
++ spin_unlock(&dcache_lock);
++ spin_unlock(&sysfs_lock);
++
++ /* drop dentry */
+ if (dentry) {
+ spin_lock(&dcache_lock);
+ spin_lock(&dentry->d_lock);
+@@ -232,6 +246,8 @@ void sysfs_drop_dentry(struct sysfs_dire
+ spin_unlock(&dentry->d_lock);
+ spin_unlock(&dcache_lock);
+ }
++
++ dput(dentry);
+ }
+ }
+
+diff -urpN linux-source-2.6.18.orig/fs/sysfs/sysfs.h linux-source-2.6.18/fs/sysfs/sysfs.h
+--- linux-source-2.6.18.orig/fs/sysfs/sysfs.h 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/fs/sysfs/sysfs.h 2007-11-07 15:38:57.000000000 -0700
+@@ -20,6 +20,7 @@ extern const unsigned char * sysfs_get_n
+ extern void sysfs_drop_dentry(struct sysfs_dirent *sd, struct dentry *parent);
+ extern int sysfs_setattr(struct dentry *dentry, struct iattr *iattr);
+
++extern spinlock_t sysfs_lock;
+ extern struct rw_semaphore sysfs_rename_sem;
+ extern struct super_block * sysfs_sb;
+ extern const struct file_operations sysfs_dir_operations;
diff --git a/trunk/2.6.18/30050_sysfs-fix-condition-check.patch b/trunk/2.6.18/30050_sysfs-fix-condition-check.patch
new file mode 100644
index 0000000..652065e
--- /dev/null
+++ b/trunk/2.6.18/30050_sysfs-fix-condition-check.patch
@@ -0,0 +1,29 @@
+From: Tejun Heo <htejun@gmail.com>
+Date: Mon, 11 Jun 2007 05:03:27 +0000 (+0900)
+Subject: sysfs: fix condition check in sysfs_drop_dentry()
+X-Git-Tag: v2.6.22-rc5~46
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=6aa054aadfea613a437ad0b15d38eca2b963fc0a
+
+sysfs: fix condition check in sysfs_drop_dentry()
+
+The condition check doesn't make much sense as it basically always
+succeeds. This causes NULL dereferencing on certain cases. It seems
+that parentheses are put in the wrong place. Fix it.
+
+Signed-off-by: Tejun Heo <htejun@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+
+Adjusted to apply to Debian's 2.6.18 by dann frazier <dannf@hp.com>
+
+--- linux-source-2.6.18+2.6.22.y/fs/sysfs/inode.c.orig 2007-11-07 15:40:19.000000000 -0700
++++ linux-source-2.6.18+2.6.22.y/fs/sysfs/inode.c 2007-11-07 17:09:33.000000000 -0700
+@@ -236,7 +236,7 @@ void sysfs_drop_dentry(struct sysfs_dire
+ if (dentry) {
+ spin_lock(&dcache_lock);
+ spin_lock(&dentry->d_lock);
+- if (!(d_unhashed(dentry) && dentry->d_inode)) {
++ if (!d_unhashed(dentry) && dentry->d_inode) {
+ dget_locked(dentry);
+ __d_drop(dentry);
+ spin_unlock(&dentry->d_lock);
diff --git a/trunk/2.6.18/30051_tmpfs-restore-clear_highpage.patch b/trunk/2.6.18/30051_tmpfs-restore-clear_highpage.patch
new file mode 100644
index 0000000..c4ed61c
--- /dev/null
+++ b/trunk/2.6.18/30051_tmpfs-restore-clear_highpage.patch
@@ -0,0 +1,44 @@
+commit e84e2e132c9c66d8498e7710d4ea532d1feaaac5
+Author: Hugh Dickins <hugh@veritas.com>
+Date: Wed Nov 28 18:55:10 2007 +0000
+
+ tmpfs: restore missing clear_highpage
+
+ tmpfs was misconverted to __GFP_ZERO in 2.6.11. There's an unusual case in
+ which shmem_getpage receives the page from its caller instead of allocating.
+ We must cover this case by clear_highpage before SetPageUptodate, as before.
+
+ Signed-off-by: Hugh Dickins <hugh@veritas.com>
+ Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+
+Adjusted to apply to Debian's 2.6.18 by dann frazier <dannf@hp.com>
+
+diff -urpN linux-source-2.6.18.orig/mm/shmem.c linux-source-2.6.18/mm/shmem.c
+--- linux-source-2.6.18.orig/mm/shmem.c 2007-12-01 15:24:42.000000000 -0700
++++ linux-source-2.6.18/mm/shmem.c 2007-12-17 18:24:57.000000000 -0700
+@@ -972,7 +972,7 @@ shmem_alloc_page(gfp_t gfp, struct shmem
+ pvma.vm_policy = mpol_shared_policy_lookup(&info->policy, idx);
+ pvma.vm_pgoff = idx;
+ pvma.vm_end = PAGE_SIZE;
+- page = alloc_page_vma(gfp | __GFP_ZERO, &pvma, 0);
++ page = alloc_page_vma(gfp, &pvma, 0);
+ mpol_free(pvma.vm_policy);
+ return page;
+ }
+@@ -992,7 +992,7 @@ shmem_swapin(struct shmem_inode_info *in
+ static inline struct page *
+ shmem_alloc_page(gfp_t gfp,struct shmem_inode_info *info, unsigned long idx)
+ {
+- return alloc_page(gfp | __GFP_ZERO);
++ return alloc_page(gfp);
+ }
+ #endif
+
+@@ -1201,6 +1201,7 @@ repeat:
+
+ info->alloced++;
+ spin_unlock(&info->lock);
++ clear_highpage(filepage);
+ flush_dcache_page(filepage);
+ SetPageUptodate(filepage);
+ }
diff --git a/trunk/2.6.18/30052_minixfs-printk-hang.patch b/trunk/2.6.18/30052_minixfs-printk-hang.patch
new file mode 100644
index 0000000..b7b205b
--- /dev/null
+++ b/trunk/2.6.18/30052_minixfs-printk-hang.patch
@@ -0,0 +1,76 @@
+From: Eric Sandeen <sandeen@redhat.com>
+Date: Wed, 17 Oct 2007 06:27:15 +0000 (-0700)
+Subject: minixfs: limit minixfs printks on corrupted dir i_size (CVE-2006-6058)
+X-Git-Tag: v2.6.23.7~3
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fstable%2Flinux-2.6.23.y.git;a=commitdiff_plain;h=f0ae3188daf70ed07a4dfbeb133bef3a92838a15
+
+minixfs: limit minixfs printks on corrupted dir i_size (CVE-2006-6058)
+
+patch f44ec6f3f89889a469773b1fd894f8fcc07c29cf upstream.
+
+This attempts to address CVE-2006-6058
+http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-6058
+
+first reported at http://projects.info-pull.com/mokb/MOKB-17-11-2006.html
+
+Essentially a corrupted minix dir inode reporting a very large
+i_size will loop for a very long time in minix_readdir, minix_find_entry,
+etc, because on EIO they just move on to try the next page. This is
+under the BKL, printk-storming as well. This can lock up the machine
+for a very long time. Simply ratelimiting the printks gets things back
+under control. Make the message a bit more informative while we're here.
+
+Signed-off-by: Eric Sandeen <sandeen@redhat.com>
+Cc: Bodo Eggert <7eggert@gmx.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>
+---
+
+Backported to Debian's 2.6.18 by dann frazier <dannf@debian.org>
+
+diff -urpN linux-source-2.6.18.orig/fs/minix/itree_v1.c linux-source-2.6.18/fs/minix/itree_v1.c
+--- linux-source-2.6.18.orig/fs/minix/itree_v1.c 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/fs/minix/itree_v1.c 2007-12-16 19:13:41.000000000 -0700
+@@ -23,11 +23,16 @@ static inline block_t *i_data(struct ino
+ static int block_to_path(struct inode * inode, long block, int offsets[DEPTH])
+ {
+ int n = 0;
++ char b[BDEVNAME_SIZE];
+
+ if (block < 0) {
+- printk("minix_bmap: block<0\n");
++ printk("MINIX-fs: block_to_path: block %ld < 0 on dev %s\n",
++ block, bdevname(inode->i_sb->s_bdev, b));
+ } else if (block >= (minix_sb(inode->i_sb)->s_max_size/BLOCK_SIZE)) {
+- printk("minix_bmap: block>big\n");
++ if (printk_ratelimit())
++ printk("MINIX-fs: block_to_path: "
++ "block %ld too big on dev %s\n",
++ block, bdevname(inode->i_sb->s_bdev, b));
+ } else if (block < 7) {
+ offsets[n++] = block;
+ } else if ((block -= 7) < 512) {
+diff -urpN linux-source-2.6.18.orig/fs/minix/itree_v2.c linux-source-2.6.18/fs/minix/itree_v2.c
+--- linux-source-2.6.18.orig/fs/minix/itree_v2.c 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/fs/minix/itree_v2.c 2007-12-16 19:40:06.000000000 -0700
+@@ -23,11 +23,17 @@ static inline block_t *i_data(struct ino
+ static int block_to_path(struct inode * inode, long block, int offsets[DEPTH])
+ {
+ int n = 0;
++ char b[BDEVNAME_SIZE];
++ struct super_block *sb = inode->i_sb;
+
+ if (block < 0) {
+- printk("minix_bmap: block<0\n");
++ printk("MINIX-fs: block_to_path: block %ld < 0 on dev %s\n",
++ block, bdevname(sb->s_bdev, b));
+ } else if (block >= (minix_sb(inode->i_sb)->s_max_size/BLOCK_SIZE)) {
+- printk("minix_bmap: block>big\n");
++ if (printk_ratelimit())
++ printk("MINIX-fs: block_to_path: "
++ "block %ld too big on dev %s\n",
++ block, bdevname(sb->s_bdev, b));
+ } else if (block < 7) {
+ offsets[n++] = block;
+ } else if ((block -= 7) < 256) {
diff --git a/trunk/2.6.18/30053_hrtimer-large-relative-timeouts-overflow.patch b/trunk/2.6.18/30053_hrtimer-large-relative-timeouts-overflow.patch
new file mode 100644
index 0000000..57c2b94
--- /dev/null
+++ b/trunk/2.6.18/30053_hrtimer-large-relative-timeouts-overflow.patch
@@ -0,0 +1,45 @@
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Fri, 7 Dec 2007 18:16:17 +0000 (+0100)
+Subject: hrtimers: avoid overflow for large relative timeouts
+X-Git-Tag: v2.6.24-rc5~49^2~2
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=62f0f61e6673e67151a7c8c0f9a09c7ea43fe2b5;hp=f194d132e4971111f85c18c96067acffb13cee6d
+
+hrtimers: avoid overflow for large relative timeouts
+
+Relative hrtimers with a large timeout value might end up as negative
+timer values, when the current time is added in hrtimer_start().
+
+This in turn is causing the clockevents_set_next() function to set an
+huge timeout and sleep for quite a long time when we have a clock
+source which is capable of long sleeps like HPET. With PIT this almost
+goes unnoticed as the maximum delta is ~27ms. The non-hrt/nohz code
+sorts this out in the next timer interrupt, so we never noticed that
+problem which has been there since the first day of hrtimers.
+
+This bug became more apparent in 2.6.24 which activates HPET on more
+hardware.
+
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+---
+
+Adjusted to apply to Debian's 2.6.18 by dann frazier <dannf@debian.org>
+
+diff -urpN linux-source-2.6.18.orig/kernel/hrtimer.c linux-source-2.6.18/kernel/hrtimer.c
+--- linux-source-2.6.18.orig/kernel/hrtimer.c 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/kernel/hrtimer.c 2007-12-16 18:43:03.000000000 -0700
+@@ -443,6 +443,14 @@ hrtimer_start(struct hrtimer *timer, kti
+ #ifdef CONFIG_TIME_LOW_RES
+ tim = ktime_add(tim, base->resolution);
+ #endif
++ /*
++ * Careful here: User space might have asked for a
++ * very long sleep, so the add above might result in a
++ * negative number, which enqueues the timer in front
++ * of the queue.
++ */
++ if (tim.tv64 < 0)
++ tim.tv64 = KTIME_MAX;
+ }
+ timer->expires = tim;
+
diff --git a/trunk/2.6.18/30054_coredump-only-to-same-uid.patch b/trunk/2.6.18/30054_coredump-only-to-same-uid.patch
new file mode 100644
index 0000000..74af052
--- /dev/null
+++ b/trunk/2.6.18/30054_coredump-only-to-same-uid.patch
@@ -0,0 +1,38 @@
+From: Ingo Molnar <mingo@elte.hu>
+Date: Wed, 28 Nov 2007 12:59:18 +0000 (+0100)
+Subject: vfs: coredumping fix
+X-Git-Tag: v2.6.24-rc4~82
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=c46f739dd39db3b07ab5deb4e3ec81e1c04a91af
+
+vfs: coredumping fix
+
+fix: http://bugzilla.kernel.org/show_bug.cgi?id=3043
+
+only allow coredumping to the same uid that the coredumping
+task runs under.
+
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Acked-by: Alan Cox <alan@redhat.com>
+Acked-by: Christoph Hellwig <hch@lst.de>
+Acked-by: Al Viro <viro@ftp.linux.org.uk>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+---
+
+Adjusted to apply to Debian's 2.6.18 by dann frazier <dannf@debian.org>
+
+diff -urpN linux-source-2.6.18.orig/fs/exec.c linux-source-2.6.18/fs/exec.c
+--- linux-source-2.6.18.orig/fs/exec.c 2007-10-03 12:38:15.000000000 -0600
++++ linux-source-2.6.18/fs/exec.c 2007-12-05 23:41:00.000000000 -0700
+@@ -1524,6 +1524,12 @@ int do_coredump(long signr, int exit_cod
+
+ if (!S_ISREG(inode->i_mode))
+ goto close_fail;
++ /*
++ * Dont allow local users get cute and trick others to coredump
++ * into their pre-created files:
++ */
++ if (inode->i_uid != current->fsuid)
++ goto close_fail;
+ if (!file->f_op)
+ goto close_fail;
+ if (!file->f_op->write)
diff --git a/trunk/2.6.18/30055_isdn-net-overflow.patch b/trunk/2.6.18/30055_isdn-net-overflow.patch
new file mode 100644
index 0000000..9ea5f60
--- /dev/null
+++ b/trunk/2.6.18/30055_isdn-net-overflow.patch
@@ -0,0 +1,54 @@
+From: Karsten Keil <kkeil@suse.de>
+Date: Thu, 22 Nov 2007 11:43:13 +0000 (+0100)
+Subject: isdn: avoid copying overly-long strings
+X-Git-Tag: v2.6.24-rc4~110
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=0f13864e5b24d9cbe18d125d41bfa4b726a82e40
+
+isdn: avoid copying overly-long strings
+
+Addresses http://bugzilla.kernel.org/show_bug.cgi?id=9416
+
+Signed-off-by: Karsten Keil <kkeil@suse.de>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+---
+
+diff -urpN linux-source-2.6.18.orig/drivers/isdn/i4l/isdn_net.c linux-source-2.6.18/drivers/isdn/i4l/isdn_net.c
+--- linux-source-2.6.18.orig/drivers/isdn/i4l/isdn_net.c 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/drivers/isdn/i4l/isdn_net.c 2007-12-04 09:39:24.000000000 -0700
+@@ -2125,7 +2125,7 @@ isdn_net_find_icall(int di, int ch, int
+ u_long flags;
+ isdn_net_dev *p;
+ isdn_net_phone *n;
+- char nr[32];
++ char nr[ISDN_MSNLEN];
+ char *my_eaz;
+
+ /* Search name in netdev-chain */
+@@ -2134,7 +2134,7 @@ isdn_net_find_icall(int di, int ch, int
+ nr[1] = '\0';
+ printk(KERN_INFO "isdn_net: Incoming call without OAD, assuming '0'\n");
+ } else
+- strcpy(nr, setup->phone);
++ strlcpy(nr, setup->phone, ISDN_MSNLEN);
+ si1 = (int) setup->si1;
+ si2 = (int) setup->si2;
+ if (!setup->eazmsn[0]) {
+@@ -2803,7 +2803,7 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg
+ chidx = -1;
+ }
+ }
+- strcpy(lp->msn, cfg->eaz);
++ strlcpy(lp->msn, cfg->eaz, sizeof(lp->msn));
+ lp->pre_device = drvidx;
+ lp->pre_channel = chidx;
+ lp->onhtime = cfg->onhtime;
+@@ -2952,7 +2952,7 @@ isdn_net_addphone(isdn_net_ioctl_phone *
+ if (p) {
+ if (!(n = (isdn_net_phone *) kmalloc(sizeof(isdn_net_phone), GFP_KERNEL)))
+ return -ENOMEM;
+- strcpy(n->num, phone->phone);
++ strlcpy(n->num, phone->phone, sizeof(n->num));
+ n->next = p->local->phone[phone->outgoing & 1];
+ p->local->phone[phone->outgoing & 1] = n;
+ return 0;
diff --git a/trunk/2.6.18/30056_proc-snd-page-alloc-mem-leak.patch b/trunk/2.6.18/30056_proc-snd-page-alloc-mem-leak.patch
new file mode 100644
index 0000000..f11dbcf
--- /dev/null
+++ b/trunk/2.6.18/30056_proc-snd-page-alloc-mem-leak.patch
@@ -0,0 +1,169 @@
+From: Takashi Iwai <tiwai@suse.de>
+Date: Mon, 17 Sep 2007 19:55:10 +0000 (+0200)
+Subject: Convert snd-page-alloc proc file to use seq_file
+X-Git-Tag: v2.6.23-rc8~3
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=ccec6e2c4a74adf76ed4e2478091a311b1806212;hp=7bae705ef2c2daac1993de03e5be93b5c300fc5e
+
+Convert snd-page-alloc proc file to use seq_file
+
+Use seq_file for the proc file read/write of snd-page-alloc module.
+This automatically fixes bugs in the old proc code.
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+---
+
+Backported to Debian's 2.6.18 by dann frazier <dannf@debian.org>
+
+diff -urpN linux-source-2.6.18.orig/sound/core/memalloc.c linux-source-2.6.18/sound/core/memalloc.c
+--- linux-source-2.6.18.orig/sound/core/memalloc.c 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/sound/core/memalloc.c 2007-09-25 17:53:01.000000000 -0600
+@@ -27,6 +27,7 @@
+ #include <linux/pci.h>
+ #include <linux/slab.h>
+ #include <linux/mm.h>
++#include <linux/seq_file.h>
+ #include <asm/uaccess.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/moduleparam.h>
+@@ -483,10 +484,8 @@ static void free_all_reserved_pages(void
+ #define SND_MEM_PROC_FILE "driver/snd-page-alloc"
+ static struct proc_dir_entry *snd_mem_proc;
+
+-static int snd_mem_proc_read(char *page, char **start, off_t off,
+- int count, int *eof, void *data)
++static int snd_mem_proc_read(struct seq_file *seq, void *offset)
+ {
+- int len = 0;
+ long pages = snd_allocated_pages >> (PAGE_SHIFT-12);
+ struct list_head *p;
+ struct snd_mem_list *mem;
+@@ -494,44 +493,47 @@ static int snd_mem_proc_read(char *page,
+ static char *types[] = { "UNKNOWN", "CONT", "DEV", "DEV-SG", "SBUS" };
+
+ mutex_lock(&list_mutex);
+- len += snprintf(page + len, count - len,
+- "pages : %li bytes (%li pages per %likB)\n",
+- pages * PAGE_SIZE, pages, PAGE_SIZE / 1024);
++ seq_printf(seq, "pages : %li bytes (%li pages per %likB)\n",
++ pages * PAGE_SIZE, pages, PAGE_SIZE / 1024);
+ devno = 0;
+ list_for_each(p, &mem_list_head) {
+ mem = list_entry(p, struct snd_mem_list, list);
+ devno++;
+- len += snprintf(page + len, count - len,
+- "buffer %d : ID %08x : type %s\n",
+- devno, mem->id, types[mem->buffer.dev.type]);
+- len += snprintf(page + len, count - len,
+- " addr = 0x%lx, size = %d bytes\n",
+- (unsigned long)mem->buffer.addr, (int)mem->buffer.bytes);
++ seq_printf(seq, "buffer %d : ID %08x : type %s\n",
++ devno, mem->id, types[mem->buffer.dev.type]);
++ seq_printf(seq, " addr = 0x%lx, size = %d bytes\n",
++ (unsigned long)mem->buffer.addr,
++ (int)mem->buffer.bytes);
+ }
+ mutex_unlock(&list_mutex);
+- return len;
++ return 0;
++}
++
++static int snd_mem_proc_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, snd_mem_proc_read, NULL);
+ }
+
+ /* FIXME: for pci only - other bus? */
+ #ifdef CONFIG_PCI
+ #define gettoken(bufp) strsep(bufp, " \t\n")
+
+-static int snd_mem_proc_write(struct file *file, const char __user *buffer,
+- unsigned long count, void *data)
++static ssize_t snd_mem_proc_write(struct file *file, const char __user * buffer,
++ size_t count, loff_t * ppos)
+ {
+ char buf[128];
+ char *token, *p;
+
+- if (count > ARRAY_SIZE(buf) - 1)
+- count = ARRAY_SIZE(buf) - 1;
++ if (count > sizeof(buf) - 1)
++ return -EINVAL;
+ if (copy_from_user(buf, buffer, count))
+ return -EFAULT;
+- buf[ARRAY_SIZE(buf) - 1] = '\0';
++ buf[count] = '\0';
+
+ p = buf;
+ token = gettoken(&p);
+ if (! token || *token == '#')
+- return (int)count;
++ return count;
+ if (strcmp(token, "add") == 0) {
+ char *endp;
+ int vendor, device, size, buffers;
+@@ -552,7 +554,7 @@ static int snd_mem_proc_write(struct fil
+ (buffers = simple_strtol(token, NULL, 0)) <= 0 ||
+ buffers > 4) {
+ printk(KERN_ERR "snd-page-alloc: invalid proc write format\n");
+- return (int)count;
++ return count;
+ }
+ vendor &= 0xffff;
+ device &= 0xffff;
+@@ -564,7 +566,7 @@ static int snd_mem_proc_write(struct fil
+ if (pci_set_dma_mask(pci, mask) < 0 ||
+ pci_set_consistent_dma_mask(pci, mask) < 0) {
+ printk(KERN_ERR "snd-page-alloc: cannot set DMA mask %lx for pci %04x:%04x\n", mask, vendor, device);
+- return (int)count;
++ return count;
+ }
+ }
+ for (i = 0; i < buffers; i++) {
+@@ -574,7 +576,7 @@ static int snd_mem_proc_write(struct fil
+ size, &dmab) < 0) {
+ printk(KERN_ERR "snd-page-alloc: cannot allocate buffer pages (size = %d)\n", size);
+ pci_dev_put(pci);
+- return (int)count;
++ return count;
+ }
+ snd_dma_reserve_buf(&dmab, snd_dma_pci_buf_id(pci));
+ }
+@@ -600,9 +602,21 @@ static int snd_mem_proc_write(struct fil
+ free_all_reserved_pages();
+ else
+ printk(KERN_ERR "snd-page-alloc: invalid proc cmd\n");
+- return (int)count;
++ return count;
+ }
+ #endif /* CONFIG_PCI */
++
++static const struct file_operations snd_mem_proc_fops = {
++ .owner = THIS_MODULE,
++ .open = snd_mem_proc_open,
++ .read = seq_read,
++#ifdef CONFIG_PCI
++ .write = snd_mem_proc_write,
++#endif
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
+ #endif /* CONFIG_PROC_FS */
+
+ /*
+@@ -613,12 +627,8 @@ static int __init snd_mem_init(void)
+ {
+ #ifdef CONFIG_PROC_FS
+ snd_mem_proc = create_proc_entry(SND_MEM_PROC_FILE, 0644, NULL);
+- if (snd_mem_proc) {
+- snd_mem_proc->read_proc = snd_mem_proc_read;
+-#ifdef CONFIG_PCI
+- snd_mem_proc->write_proc = snd_mem_proc_write;
+-#endif
+- }
++ if (snd_mem_proc)
++ snd_mem_proc->proc_fops = &snd_mem_proc_fops;
+ #endif
+ return 0;
+ }
diff --git a/trunk/2.6.18/30057_fat-move-ioctl-compat-code.patch b/trunk/2.6.18/30057_fat-move-ioctl-compat-code.patch
new file mode 100644
index 0000000..cde2538
--- /dev/null
+++ b/trunk/2.6.18/30057_fat-move-ioctl-compat-code.patch
@@ -0,0 +1,167 @@
+From: David Howells <dhowells@redhat.com>
+Date: Thu, 31 Aug 2006 10:50:04 +0000 (+0200)
+Subject: [PATCH] BLOCK: Move the msdos device ioctl compat stuff to the msdos driver [try #6]
+X-Git-Tag: v2.6.19~1581^2~9
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=188f83dfe0eeecd1427d0d255cc97dbf7ef6b4b7
+
+[PATCH] BLOCK: Move the msdos device ioctl compat stuff to the msdos driver [try #6]
+
+Move the msdos device ioctl compat stuff from fs/compat_ioctl.c to the msdos
+driver so that the msdos header file doesn't need to be included.
+
+Signed-Off-By: David Howells <dhowells@redhat.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+---
+
+Backported to Debian's 2.6.18 by dann frazier <dannf@debian.org>
+
+diff -urpN linux-source-2.6.18.orig/fs/compat_ioctl.c linux-source-2.6.18/fs/compat_ioctl.c
+--- linux-source-2.6.18.orig/fs/compat_ioctl.c 2006-09-20 04:42:06.000000000 +0100
++++ linux-source-2.6.18/fs/compat_ioctl.c 2007-06-22 15:57:42.000000000 +0100
+@@ -113,7 +113,6 @@
+ #include <linux/nbd.h>
+ #include <linux/random.h>
+ #include <linux/filter.h>
+-#include <linux/msdos_fs.h>
+ #include <linux/pktcdvd.h>
+
+ #include <linux/hiddev.h>
+@@ -2052,51 +2051,6 @@ static int mtd_rw_oob(unsigned int fd, u
+ return err;
+ }
+
+-#define VFAT_IOCTL_READDIR_BOTH32 _IOR('r', 1, struct compat_dirent[2])
+-#define VFAT_IOCTL_READDIR_SHORT32 _IOR('r', 2, struct compat_dirent[2])
+-
+-static long
+-put_dirent32 (struct dirent *d, struct compat_dirent __user *d32)
+-{
+- if (!access_ok(VERIFY_WRITE, d32, sizeof(struct compat_dirent)))
+- return -EFAULT;
+-
+- __put_user(d->d_ino, &d32->d_ino);
+- __put_user(d->d_off, &d32->d_off);
+- __put_user(d->d_reclen, &d32->d_reclen);
+- if (__copy_to_user(d32->d_name, d->d_name, d->d_reclen))
+- return -EFAULT;
+-
+- return 0;
+-}
+-
+-static int vfat_ioctl32(unsigned fd, unsigned cmd, unsigned long arg)
+-{
+- struct compat_dirent __user *p = compat_ptr(arg);
+- int ret;
+- mm_segment_t oldfs = get_fs();
+- struct dirent d[2];
+-
+- switch(cmd)
+- {
+- case VFAT_IOCTL_READDIR_BOTH32:
+- cmd = VFAT_IOCTL_READDIR_BOTH;
+- break;
+- case VFAT_IOCTL_READDIR_SHORT32:
+- cmd = VFAT_IOCTL_READDIR_SHORT;
+- break;
+- }
+-
+- set_fs(KERNEL_DS);
+- ret = sys_ioctl(fd,cmd,(unsigned long)&d);
+- set_fs(oldfs);
+- if (ret >= 0) {
+- ret |= put_dirent32(&d[0], p);
+- ret |= put_dirent32(&d[1], p + 1);
+- }
+- return ret;
+-}
+-
+ #define REISERFS_IOC_UNPACK32 _IOW(0xCD,1,int)
+
+ static int reiserfs_ioctl32(unsigned fd, unsigned cmd, unsigned long ptr)
+@@ -2866,9 +2820,6 @@ HANDLE_IOCTL(SONET_GETFRSENSE, do_atm_io
+ HANDLE_IOCTL(BLKBSZGET_32, do_blkbszget)
+ HANDLE_IOCTL(BLKBSZSET_32, do_blkbszset)
+ HANDLE_IOCTL(BLKGETSIZE64_32, do_blkgetsize64)
+-/* vfat */
+-HANDLE_IOCTL(VFAT_IOCTL_READDIR_BOTH32, vfat_ioctl32)
+-HANDLE_IOCTL(VFAT_IOCTL_READDIR_SHORT32, vfat_ioctl32)
+ HANDLE_IOCTL(REISERFS_IOC_UNPACK32, reiserfs_ioctl32)
+ /* Raw devices */
+ HANDLE_IOCTL(RAW_SETBIND, raw_ioctl)
+diff -urpN linux-source-2.6.18.orig/fs/fat/dir.c linux-source-2.6.18/fs/fat/dir.c
+--- linux-source-2.6.18.orig/fs/fat/dir.c 2006-09-20 04:42:06.000000000 +0100
++++ linux-source-2.6.18/fs/fat/dir.c 2007-06-22 15:55:53.000000000 +0100
+@@ -20,6 +20,7 @@
+ #include <linux/dirent.h>
+ #include <linux/smp_lock.h>
+ #include <linux/buffer_head.h>
++#include <linux/compat.h>
+ #include <asm/uaccess.h>
+
+ static inline loff_t fat_make_i_pos(struct super_block *sb,
+@@ -741,10 +742,65 @@ static int fat_dir_ioctl(struct inode *
+ return ret;
+ }
+
++#ifdef CONFIG_COMPAT
++#define VFAT_IOCTL_READDIR_BOTH32 _IOR('r', 1, struct compat_dirent[2])
++#define VFAT_IOCTL_READDIR_SHORT32 _IOR('r', 2, struct compat_dirent[2])
++
++static long fat_compat_put_dirent32(struct dirent *d,
++ struct compat_dirent __user *d32)
++{
++ if (!access_ok(VERIFY_WRITE, d32, sizeof(struct compat_dirent)))
++ return -EFAULT;
++
++ __put_user(d->d_ino, &d32->d_ino);
++ __put_user(d->d_off, &d32->d_off);
++ __put_user(d->d_reclen, &d32->d_reclen);
++ if (__copy_to_user(d32->d_name, d->d_name, d->d_reclen))
++ return -EFAULT;
++
++ return 0;
++}
++
++static long fat_compat_dir_ioctl(struct file *file, unsigned cmd,
++ unsigned long arg)
++{
++ struct compat_dirent __user *p = compat_ptr(arg);
++ int ret;
++ mm_segment_t oldfs = get_fs();
++ struct dirent d[2];
++
++ switch (cmd) {
++ case VFAT_IOCTL_READDIR_BOTH32:
++ cmd = VFAT_IOCTL_READDIR_BOTH;
++ break;
++ case VFAT_IOCTL_READDIR_SHORT32:
++ cmd = VFAT_IOCTL_READDIR_SHORT;
++ break;
++ default:
++ return -ENOIOCTLCMD;
++ }
++
++ set_fs(KERNEL_DS);
++ lock_kernel();
++ ret = fat_dir_ioctl(file->f_dentry->d_inode, file,
++ cmd, (unsigned long) &d);
++ unlock_kernel();
++ set_fs(oldfs);
++ if (ret >= 0) {
++ ret |= fat_compat_put_dirent32(&d[0], p);
++ ret |= fat_compat_put_dirent32(&d[1], p + 1);
++ }
++ return ret;
++}
++#endif /* CONFIG_COMPAT */
++
+ const struct file_operations fat_dir_operations = {
+ .read = generic_read_dir,
+ .readdir = fat_readdir,
+ .ioctl = fat_dir_ioctl,
++#ifdef CONFIG_COMPAT
++ .compat_ioctl = fat_compat_dir_ioctl,
++#endif
+ .fsync = file_fsync,
+ };
+
diff --git a/trunk/2.6.18/30058_fat-fix-compat-ioctls.patch b/trunk/2.6.18/30058_fat-fix-compat-ioctls.patch
new file mode 100644
index 0000000..f98c7d1
--- /dev/null
+++ b/trunk/2.6.18/30058_fat-fix-compat-ioctls.patch
@@ -0,0 +1,311 @@
+From: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
+Date: Tue, 8 May 2007 07:31:28 +0000 (-0700)
+Subject: fat: fix VFAT compat ioctls on 64-bit systems
+X-Git-Tag: v2.6.22-rc1~614
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=c483bab099cb89e92b7cad94a52fcdaf37e56657
+
+fat: fix VFAT compat ioctls on 64-bit systems
+
+If you compile and run the below test case in an msdos or vfat directory on
+an x86-64 system with -m32 you'll get garbage in the kernel_dirent struct
+followed by a SIGSEGV.
+
+The patch fixes this.
+
+Reported and initial fix by Bart Oldeman
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+struct kernel_dirent {
+ long d_ino;
+ long d_off;
+ unsigned short d_reclen;
+ char d_name[256]; /* We must not include limits.h! */
+};
+#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct kernel_dirent [2])
+#define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct kernel_dirent [2])
+
+int main(void)
+{
+ int fd = open(".", O_RDONLY);
+ struct kernel_dirent de[2];
+
+ while (1) {
+ int i = ioctl(fd, VFAT_IOCTL_READDIR_BOTH, (long)de);
+ if (i == -1) break;
+ if (de[0].d_reclen == 0) break;
+ printf("SFN: reclen=%2d off=%d ino=%d, %-12s",
+ de[0].d_reclen, de[0].d_off, de[0].d_ino, de[0].d_name);
+ if (de[1].d_reclen)
+ printf("\tLFN: reclen=%2d off=%d ino=%d, %s",
+ de[1].d_reclen, de[1].d_off, de[1].d_ino, de[1].d_name);
+ printf("\n");
+ }
+ return 0;
+}
+
+Signed-off-by: Bart Oldeman <bartoldeman@users.sourceforge.net>
+Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
+Cc: <stable@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+---
+
+Backported to Debian's 2.6.18 by dann frazier <dannf@debian.org>
+
+diff -urpN linux-source-2.6.18.orig/fs/fat/dir.c linux-source-2.6.18/fs/fat/dir.c
+--- linux-source-2.6.18.orig/fs/fat/dir.c 2007-06-22 21:48:00.000000000 -0600
++++ linux-source-2.6.18/fs/fat/dir.c 2007-06-22 21:48:42.000000000 -0600
+@@ -422,7 +422,7 @@ EODir:
+ EXPORT_SYMBOL_GPL(fat_search_long);
+
+ struct fat_ioctl_filldir_callback {
+- struct dirent __user *dirent;
++ void __user *dirent;
+ int result;
+ /* for dir ioctl */
+ const char *longname;
+@@ -647,62 +647,85 @@ static int fat_readdir(struct file *filp
+ return __fat_readdir(inode, filp, dirent, filldir, 0, 0);
+ }
+
+-static int fat_ioctl_filldir(void *__buf, const char *name, int name_len,
+- loff_t offset, ino_t ino, unsigned int d_type)
++#define FAT_IOCTL_FILLDIR_FUNC(func, dirent_type) \
++static int func(void *__buf, const char *name, int name_len, \
++ loff_t offset, ino_t ino, unsigned int d_type) \
++{ \
++ struct fat_ioctl_filldir_callback *buf = __buf; \
++ struct dirent_type __user *d1 = buf->dirent; \
++ struct dirent_type __user *d2 = d1 + 1; \
++ \
++ if (buf->result) \
++ return -EINVAL; \
++ buf->result++; \
++ \
++ if (name != NULL) { \
++ /* dirent has only short name */ \
++ if (name_len >= sizeof(d1->d_name)) \
++ name_len = sizeof(d1->d_name) - 1; \
++ \
++ if (put_user(0, d2->d_name) || \
++ put_user(0, &d2->d_reclen) || \
++ copy_to_user(d1->d_name, name, name_len) || \
++ put_user(0, d1->d_name + name_len) || \
++ put_user(name_len, &d1->d_reclen)) \
++ goto efault; \
++ } else { \
++ /* dirent has short and long name */ \
++ const char *longname = buf->longname; \
++ int long_len = buf->long_len; \
++ const char *shortname = buf->shortname; \
++ int short_len = buf->short_len; \
++ \
++ if (long_len >= sizeof(d1->d_name)) \
++ long_len = sizeof(d1->d_name) - 1; \
++ if (short_len >= sizeof(d1->d_name)) \
++ short_len = sizeof(d1->d_name) - 1; \
++ \
++ if (copy_to_user(d2->d_name, longname, long_len) || \
++ put_user(0, d2->d_name + long_len) || \
++ put_user(long_len, &d2->d_reclen) || \
++ put_user(ino, &d2->d_ino) || \
++ put_user(offset, &d2->d_off) || \
++ copy_to_user(d1->d_name, shortname, short_len) || \
++ put_user(0, d1->d_name + short_len) || \
++ put_user(short_len, &d1->d_reclen)) \
++ goto efault; \
++ } \
++ return 0; \
++efault: \
++ buf->result = -EFAULT; \
++ return -EFAULT; \
++}
++
++FAT_IOCTL_FILLDIR_FUNC(fat_ioctl_filldir, dirent)
++
++static int fat_ioctl_readdir(struct inode *inode, struct file *filp,
++ void __user *dirent, filldir_t filldir,
++ int short_only, int both)
+ {
+- struct fat_ioctl_filldir_callback *buf = __buf;
+- struct dirent __user *d1 = buf->dirent;
+- struct dirent __user *d2 = d1 + 1;
+-
+- if (buf->result)
+- return -EINVAL;
+- buf->result++;
+-
+- if (name != NULL) {
+- /* dirent has only short name */
+- if (name_len >= sizeof(d1->d_name))
+- name_len = sizeof(d1->d_name) - 1;
+-
+- if (put_user(0, d2->d_name) ||
+- put_user(0, &d2->d_reclen) ||
+- copy_to_user(d1->d_name, name, name_len) ||
+- put_user(0, d1->d_name + name_len) ||
+- put_user(name_len, &d1->d_reclen))
+- goto efault;
+- } else {
+- /* dirent has short and long name */
+- const char *longname = buf->longname;
+- int long_len = buf->long_len;
+- const char *shortname = buf->shortname;
+- int short_len = buf->short_len;
+-
+- if (long_len >= sizeof(d1->d_name))
+- long_len = sizeof(d1->d_name) - 1;
+- if (short_len >= sizeof(d1->d_name))
+- short_len = sizeof(d1->d_name) - 1;
+-
+- if (copy_to_user(d2->d_name, longname, long_len) ||
+- put_user(0, d2->d_name + long_len) ||
+- put_user(long_len, &d2->d_reclen) ||
+- put_user(ino, &d2->d_ino) ||
+- put_user(offset, &d2->d_off) ||
+- copy_to_user(d1->d_name, shortname, short_len) ||
+- put_user(0, d1->d_name + short_len) ||
+- put_user(short_len, &d1->d_reclen))
+- goto efault;
++ struct fat_ioctl_filldir_callback buf;
++ int ret;
++
++ buf.dirent = dirent;
++ buf.result = 0;
++ mutex_lock(&inode->i_mutex);
++ ret = -ENOENT;
++ if (!IS_DEADDIR(inode)) {
++ ret = __fat_readdir(inode, filp, &buf, filldir,
++ short_only, both);
+ }
+- return 0;
+-efault:
+- buf->result = -EFAULT;
+- return -EFAULT;
++ mutex_unlock(&inode->i_mutex);
++ if (ret >= 0)
++ ret = buf.result;
++ return ret;
+ }
+
+-static int fat_dir_ioctl(struct inode * inode, struct file * filp,
+- unsigned int cmd, unsigned long arg)
++static int fat_dir_ioctl(struct inode *inode, struct file *filp,
++ unsigned int cmd, unsigned long arg)
+ {
+- struct fat_ioctl_filldir_callback buf;
+- struct dirent __user *d1;
+- int ret, short_only, both;
++ struct dirent __user *d1 = (struct dirent __user *)arg;
++ int short_only, both;
+
+ switch (cmd) {
+ case VFAT_IOCTL_READDIR_SHORT:
+@@ -717,7 +740,6 @@ static int fat_dir_ioctl(struct inode *
+ return fat_generic_ioctl(inode, filp, cmd, arg);
+ }
+
+- d1 = (struct dirent __user *)arg;
+ if (!access_ok(VERIFY_WRITE, d1, sizeof(struct dirent[2])))
+ return -EFAULT;
+ /*
+@@ -728,69 +750,48 @@ static int fat_dir_ioctl(struct inode *
+ if (put_user(0, &d1->d_reclen))
+ return -EFAULT;
+
+- buf.dirent = d1;
+- buf.result = 0;
+- mutex_lock(&inode->i_mutex);
+- ret = -ENOENT;
+- if (!IS_DEADDIR(inode)) {
+- ret = __fat_readdir(inode, filp, &buf, fat_ioctl_filldir,
+- short_only, both);
+- }
+- mutex_unlock(&inode->i_mutex);
+- if (ret >= 0)
+- ret = buf.result;
+- return ret;
++ return fat_ioctl_readdir(inode, filp, d1, fat_ioctl_filldir,
++ short_only, both);
+ }
+
+ #ifdef CONFIG_COMPAT
+ #define VFAT_IOCTL_READDIR_BOTH32 _IOR('r', 1, struct compat_dirent[2])
+ #define VFAT_IOCTL_READDIR_SHORT32 _IOR('r', 2, struct compat_dirent[2])
+
+-static long fat_compat_put_dirent32(struct dirent *d,
+- struct compat_dirent __user *d32)
+-{
+- if (!access_ok(VERIFY_WRITE, d32, sizeof(struct compat_dirent)))
+- return -EFAULT;
++FAT_IOCTL_FILLDIR_FUNC(fat_compat_ioctl_filldir, compat_dirent)
+
+- __put_user(d->d_ino, &d32->d_ino);
+- __put_user(d->d_off, &d32->d_off);
+- __put_user(d->d_reclen, &d32->d_reclen);
+- if (__copy_to_user(d32->d_name, d->d_name, d->d_reclen))
+- return -EFAULT;
+-
+- return 0;
+-}
+-
+-static long fat_compat_dir_ioctl(struct file *file, unsigned cmd,
++static long fat_compat_dir_ioctl(struct file *filp, unsigned cmd,
+ unsigned long arg)
+ {
+- struct compat_dirent __user *p = compat_ptr(arg);
+- int ret;
+- mm_segment_t oldfs = get_fs();
+- struct dirent d[2];
++ struct inode *inode = filp->f_dentry->d_inode;
++ struct compat_dirent __user *d1 = compat_ptr(arg);
++ int short_only, both;
+
+ switch (cmd) {
+- case VFAT_IOCTL_READDIR_BOTH32:
+- cmd = VFAT_IOCTL_READDIR_BOTH;
+- break;
+ case VFAT_IOCTL_READDIR_SHORT32:
+- cmd = VFAT_IOCTL_READDIR_SHORT;
++ short_only = 1;
++ both = 0;
++ break;
++ case VFAT_IOCTL_READDIR_BOTH32:
++ short_only = 0;
++ both = 1;
+ break;
+ default:
+ return -ENOIOCTLCMD;
+ }
+
+- set_fs(KERNEL_DS);
+- lock_kernel();
+- ret = fat_dir_ioctl(file->f_dentry->d_inode, file,
+- cmd, (unsigned long) &d);
+- unlock_kernel();
+- set_fs(oldfs);
+- if (ret >= 0) {
+- ret |= fat_compat_put_dirent32(&d[0], p);
+- ret |= fat_compat_put_dirent32(&d[1], p + 1);
+- }
+- return ret;
++ if (!access_ok(VERIFY_WRITE, d1, sizeof(struct compat_dirent[2])))
++ return -EFAULT;
++ /*
++ * Yes, we don't need this put_user() absolutely. However old
++ * code didn't return the right value. So, app use this value,
++ * in order to check whether it is EOF.
++ */
++ if (put_user(0, &d1->d_reclen))
++ return -EFAULT;
++
++ return fat_ioctl_readdir(inode, filp, d1, fat_compat_ioctl_filldir,
++ short_only, both);
+ }
+ #endif /* CONFIG_COMPAT */
+
diff --git a/trunk/2.6.18/30059_vfs-use-access-mode-flag.patch b/trunk/2.6.18/30059_vfs-use-access-mode-flag.patch
new file mode 100644
index 0000000..ef47e1a
--- /dev/null
+++ b/trunk/2.6.18/30059_vfs-use-access-mode-flag.patch
@@ -0,0 +1,52 @@
+From: Linus Torvalds <torvalds@woody.linux-foundation.org>
+Date: Sat, 12 Jan 2008 22:06:34 +0000 (-0800)
+Subject: Use access mode instead of open flags to determine needed permissions
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=974a9f0b47da74e28f68b9c8645c3786aa5ace1a
+
+Use access mode instead of open flags to determine needed permissions
+
+Way back when (in commit 834f2a4a1554dc5b2598038b3fe8703defcbe467, aka
+"VFS: Allow the filesystem to return a full file pointer on open intent"
+to be exact), Trond changed the open logic to keep track of the original
+flags to a file open, in order to pass down the the intent of a dentry
+lookup to the low-level filesystem.
+
+However, when doing that reorganization, it changed the meaning of
+namei_flags, and thus inadvertently changed the test of access mode for
+directories (and RO filesystem) to use the wrong flag. So fix those
+test back to use access mode ("acc_mode") rather than the open flag
+("flag").
+
+Issue noticed by Bill Roman at Datalight.
+
+Reported-and-tested-by: Bill Roman <bill.roman@datalight.com>
+Acked-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Acked-by: Al Viro <viro@ZenIV.linux.org.uk>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+---
+
+Adjusted to apply to Debian's 2.6.18 by dann frazier <dannf@hp.com>
+
+diff -urpN linux-source-2.6.18.orig/fs/namei.c linux-source-2.6.18/fs/namei.c
+--- linux-source-2.6.18.orig/fs/namei.c 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/fs/namei.c 2008-01-15 16:42:10.000000000 -0700
+@@ -1500,7 +1500,7 @@ int may_open(struct nameidata *nd, int a
+ if (S_ISLNK(inode->i_mode))
+ return -ELOOP;
+
+- if (S_ISDIR(inode->i_mode) && (flag & FMODE_WRITE))
++ if (S_ISDIR(inode->i_mode) && (acc_mode & MAY_WRITE))
+ return -EISDIR;
+
+ error = vfs_permission(nd, acc_mode);
+@@ -1519,7 +1519,7 @@ int may_open(struct nameidata *nd, int a
+ return -EACCES;
+
+ flag &= ~O_TRUNC;
+- } else if (IS_RDONLY(inode) && (flag & FMODE_WRITE))
++ } else if (IS_RDONLY(inode) && (acc_mode & MAY_WRITE))
+ return -EROFS;
+ /*
+ * An append-only file must be opened in append mode for writing.
diff --git a/trunk/2.6.18/30060_i4l-isdn_ioctl-mem-overrun.patch b/trunk/2.6.18/30060_i4l-isdn_ioctl-mem-overrun.patch
new file mode 100644
index 0000000..a44bb5b
--- /dev/null
+++ b/trunk/2.6.18/30060_i4l-isdn_ioctl-mem-overrun.patch
@@ -0,0 +1,56 @@
+From: Karsten Keil <kkeil@suse.de>
+Date: Sat, 1 Dec 2007 20:16:15 +0000 (-0800)
+Subject: I4L: fix isdn_ioctl memory overrun vulnerability
+X-Git-Tag: v2.6.24-rc4~16
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=eafe1aa37e6ec2d56f14732b5240c4dd09f0613a
+
+I4L: fix isdn_ioctl memory overrun vulnerability
+
+Fix possible memory overrun issue in the isdn ioctl code.
+
+Found by ADLAB <adlab@venustech.com.cn>
+
+Signed-off-by: Karsten Keil <kkeil@suse.de>
+Cc: ADLAB <adlab@venustech.com.cn>
+Cc: <stable@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+---
+
+diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
+index c6df292..d695295 100644
+--- a/drivers/isdn/i4l/isdn_common.c
++++ b/drivers/isdn/i4l/isdn_common.c
+@@ -1515,6 +1515,7 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
+ if (copy_from_user(&iocts, argp,
+ sizeof(isdn_ioctl_struct)))
+ return -EFAULT;
++ iocts.drvid[sizeof(iocts.drvid)-1] = 0;
+ if (strlen(iocts.drvid)) {
+ if ((p = strchr(iocts.drvid, ',')))
+ *p = 0;
+@@ -1599,6 +1600,7 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
+ if (copy_from_user(&iocts, argp,
+ sizeof(isdn_ioctl_struct)))
+ return -EFAULT;
++ iocts.drvid[sizeof(iocts.drvid)-1] = 0;
+ if (strlen(iocts.drvid)) {
+ drvidx = -1;
+ for (i = 0; i < ISDN_MAX_DRIVERS; i++)
+@@ -1643,7 +1645,7 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
+ } else {
+ p = (char __user *) iocts.arg;
+ for (i = 0; i < 10; i++) {
+- sprintf(bname, "%s%s",
++ snprintf(bname, sizeof(bname), "%s%s",
+ strlen(dev->drv[drvidx]->msn2eaz[i]) ?
+ dev->drv[drvidx]->msn2eaz[i] : "_",
+ (i < 9) ? "," : "\0");
+@@ -1673,6 +1675,7 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
+ char *p;
+ if (copy_from_user(&iocts, argp, sizeof(isdn_ioctl_struct)))
+ return -EFAULT;
++ iocts.drvid[sizeof(iocts.drvid)-1] = 0;
+ if (strlen(iocts.drvid)) {
+ if ((p = strchr(iocts.drvid, ',')))
+ *p = 0;
diff --git a/trunk/2.6.18/30061_vmsplice-security.patch b/trunk/2.6.18/30061_vmsplice-security.patch
new file mode 100644
index 0000000..248bdba
--- /dev/null
+++ b/trunk/2.6.18/30061_vmsplice-security.patch
@@ -0,0 +1,28 @@
+diff --git a/fs/splice.c b/fs/splice.c
+index 684bca3..2d7e598 100644
+--- a/fs/splice.c
++++ b/fs/splice.c
+@@ -1122,6 +1122,11 @@ static int get_iovec_page_array(const struct iovec __user *iov,
+ size_t len;
+ int i;
+
++ if (!access_ok(VERIFY_READ, iov, sizeof(struct iovec))) {
++ error = -EFAULT;
++ break;
++ }
++
+ /*
+ * Get user address base and length for this iovec.
+ */
+@@ -1141,6 +1146,11 @@ static int get_iovec_page_array(const struct iovec __user *iov,
+ if (unlikely(!base))
+ break;
+
++ if (!access_ok(VERIFY_READ, base, len)) {
++ error = -EFAULT;
++ break;
++ }
++
+ /*
+ * Get this base offset and number of pages, then map
+ * in the user pages.
diff --git a/trunk/2.6.18/30062_clear-spurious-irq.patch b/trunk/2.6.18/30062_clear-spurious-irq.patch
new file mode 100644
index 0000000..6873d8c
--- /dev/null
+++ b/trunk/2.6.18/30062_clear-spurious-irq.patch
@@ -0,0 +1,34 @@
+From: Linus Torvalds <torvalds@woody.linux-foundation.org>
+Date: Tue, 23 Jan 2007 22:16:31 +0000 (-0800)
+Subject: Clear spurious irq stat information when adding irq handler
+X-Git-Tag: v2.6.20-rc6~15
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=8528b0f1de1101c6002036fd53638fb21111d0ea
+
+Clear spurious irq stat information when adding irq handler
+
+Any newly added irq handler may obviously make any old spurious irq
+status invalid, since the new handler may well be the thing that is
+supposed to handle any interrupts that came in.
+
+So just clear the statistics when adding handlers.
+
+Pointed-out-by: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Acked-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+---
+
+diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
+index b385878..8b961ad 100644
+--- a/kernel/irq/manage.c
++++ b/kernel/irq/manage.c
+@@ -315,6 +315,9 @@ int setup_irq(unsigned int irq, struct irqaction *new)
+ /* Undo nested disables: */
+ desc->depth = 1;
+ }
++ /* Reset broken irq detection when installing new handler */
++ desc->irq_count = 0;
++ desc->irqs_unhandled = 0;
+ spin_unlock_irqrestore(&desc->lock, flags);
+
+ new->irq = irq;