--- /dev/null
+From 7786ce192fc4917fb9b789dd823476ff8fd6cf66 Mon Sep 17 00:00:00 2001
+From: Jeff Garzik <jeff@garzik.org>
+Date: Tue, 17 Oct 2006 00:10:40 -0700
+Subject: [PATCH] ISDN: check for userspace copy faults
+
+Most of the ISDN ->readstat() implementations needed to check
+copy_to_user() and put_user() return values.
+
+Signed-off-by: Jeff Garzik <jeff@garzik.org>
+Cc: Karsten Keil <kkeil@suse.de>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Linus Torvalds <torvalds@osdl.org>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ drivers/isdn/capi/capidrv.c | 3 ++-
+ drivers/isdn/hisax/config.c | 6 ++++--
+ drivers/isdn/icn/icn.c | 3 ++-
+ drivers/isdn/isdnloop/isdnloop.c | 3 ++-
+ drivers/isdn/pcbit/drv.c | 16 ++++++++++------
+ 5 files changed, 20 insertions(+), 11 deletions(-)
+
+--- linux-2.6.18.1.orig/drivers/isdn/capi/capidrv.c
++++ linux-2.6.18.1/drivers/isdn/capi/capidrv.c
+@@ -1907,7 +1907,8 @@ static int if_readstat(u8 __user *buf, i
+ }
+
+ for (p=buf, count=0; count < len; p++, count++) {
+- put_user(*card->q931_read++, p);
++ if (put_user(*card->q931_read++, p))
++ return -EFAULT;
+ if (card->q931_read > card->q931_end)
+ card->q931_read = card->q931_buf;
+ }
+--- linux-2.6.18.1.orig/drivers/isdn/hisax/config.c
++++ linux-2.6.18.1/drivers/isdn/hisax/config.c
+@@ -631,7 +631,8 @@ static int HiSax_readstatus(u_char __use
+ count = cs->status_end - cs->status_read + 1;
+ if (count >= len)
+ count = len;
+- copy_to_user(p, cs->status_read, count);
++ if (copy_to_user(p, cs->status_read, count))
++ return -EFAULT;
+ cs->status_read += count;
+ if (cs->status_read > cs->status_end)
+ cs->status_read = cs->status_buf;
+@@ -642,7 +643,8 @@ static int HiSax_readstatus(u_char __use
+ cnt = HISAX_STATUS_BUFSIZE;
+ else
+ cnt = count;
+- copy_to_user(p, cs->status_read, cnt);
++ if (copy_to_user(p, cs->status_read, cnt))
++ return -EFAULT;
+ p += cnt;
+ cs->status_read += cnt % HISAX_STATUS_BUFSIZE;
+ count -= cnt;
+--- linux-2.6.18.1.orig/drivers/isdn/icn/icn.c
++++ linux-2.6.18.1/drivers/isdn/icn/icn.c
+@@ -1010,7 +1010,8 @@ icn_readstatus(u_char __user *buf, int l
+ for (p = buf, count = 0; count < len; p++, count++) {
+ if (card->msg_buf_read == card->msg_buf_write)
+ return count;
+- put_user(*card->msg_buf_read++, p);
++ if (put_user(*card->msg_buf_read++, p))
++ return -EFAULT;
+ if (card->msg_buf_read > card->msg_buf_end)
+ card->msg_buf_read = card->msg_buf;
+ }
+--- linux-2.6.18.1.orig/drivers/isdn/isdnloop/isdnloop.c
++++ linux-2.6.18.1/drivers/isdn/isdnloop/isdnloop.c
+@@ -451,7 +451,8 @@ isdnloop_readstatus(u_char __user *buf,
+ for (p = buf, count = 0; count < len; p++, count++) {
+ if (card->msg_buf_read == card->msg_buf_write)
+ return count;
+- put_user(*card->msg_buf_read++, p);
++ if (put_user(*card->msg_buf_read++, p))
++ return -EFAULT;
+ if (card->msg_buf_read > card->msg_buf_end)
+ card->msg_buf_read = card->msg_buf;
+ }
+--- linux-2.6.18.1.orig/drivers/isdn/pcbit/drv.c
++++ linux-2.6.18.1/drivers/isdn/pcbit/drv.c
+@@ -725,23 +725,27 @@ static int pcbit_stat(u_char __user *buf
+
+ if (stat_st < stat_end)
+ {
+- copy_to_user(buf, statbuf + stat_st, len);
++ if (copy_to_user(buf, statbuf + stat_st, len))
++ return -EFAULT;
+ stat_st += len;
+ }
+ else
+ {
+ if (len > STATBUF_LEN - stat_st)
+ {
+- copy_to_user(buf, statbuf + stat_st,
+- STATBUF_LEN - stat_st);
+- copy_to_user(buf, statbuf,
+- len - (STATBUF_LEN - stat_st));
++ if (copy_to_user(buf, statbuf + stat_st,
++ STATBUF_LEN - stat_st))
++ return -EFAULT;
++ if (copy_to_user(buf, statbuf,
++ len - (STATBUF_LEN - stat_st)))
++ return -EFAULT;
+
+ stat_st = len - (STATBUF_LEN - stat_st);
+ }
+ else
+ {
+- copy_to_user(buf, statbuf + stat_st, len);
++ if (copy_to_user(buf, statbuf + stat_st, len))
++ return -EFAULT;
+
+ stat_st += len;
+