diff options
author | Guy Martin <gmsoft@gentoo.org> | 2005-01-10 17:44:18 +0000 |
---|---|---|
committer | Guy Martin <gmsoft@gentoo.org> | 2005-01-10 17:44:18 +0000 |
commit | cdca06bba0b0eab3b43cb8e19125cbbc69fef10b (patch) | |
tree | a5e3f821292ea3c03b0d06334454a8ff0b53751e /sys-kernel/hppa-sources | |
parent | Stable on sparc (diff) | |
download | historical-cdca06bba0b0eab3b43cb8e19125cbbc69fef10b.tar.gz historical-cdca06bba0b0eab3b43cb8e19125cbbc69fef10b.tar.bz2 historical-cdca06bba0b0eab3b43cb8e19125cbbc69fef10b.zip |
Version bump. Fix security issues (#77094, #77025). Remove old sources.
Diffstat (limited to 'sys-kernel/hppa-sources')
24 files changed, 505 insertions, 3963 deletions
diff --git a/sys-kernel/hppa-sources/ChangeLog b/sys-kernel/hppa-sources/ChangeLog index e83c4d292dc8..3abab071a455 100644 --- a/sys-kernel/hppa-sources/ChangeLog +++ b/sys-kernel/hppa-sources/ChangeLog @@ -1,6 +1,18 @@ # ChangeLog for sys-kernel/hppa-sources # Copyright 2002-2005 Gentoo Foundation; Distributed under the GPL v2 -# $Header: /var/cvsroot/gentoo-x86/sys-kernel/hppa-sources/ChangeLog,v 1.50 2005/01/09 01:45:52 gmsoft Exp $ +# $Header: /var/cvsroot/gentoo-x86/sys-kernel/hppa-sources/ChangeLog,v 1.51 2005/01/10 17:44:18 gmsoft Exp $ + +*hppa-sources-2.6.10_p10 (10 Jan 2005) + + 10 Jan 2005; Guy Martin <gmsoft@gentoo.org> -files/AF_UNIX-security.patch, + -files/CAN-2004-0394.patch, -files/CAN-2004-0495-2.4-sparse.patch, + -files/CAN-2004-0497.patch, -files/CAN-2004-0535-2.4-e1000.patch, + -files/CAN-2004-0814.patch, -files/CAN-2004-0882-0883.patch, + -files/CAN-2004-1074.patch, +files/CAN-2004-1235.patch, + -files/CAN-2004-685.patch, +files/LKA-20050107.patch, + -files/NFS-XDR-security.patch, -files/binfmt_elf-loader-security.patch, + -files/security-proc-cmdline.patch, +hppa-sources-2.6.10_p10.ebuild: + Version bump. Fix security issues (#77094, #77025). Remove old sources. *hppa-sources-2.6.10_p6 (09 Jan 2005) diff --git a/sys-kernel/hppa-sources/Manifest b/sys-kernel/hppa-sources/Manifest index 02fd2d3e6a04..d5e8cfc12d6a 100644 --- a/sys-kernel/hppa-sources/Manifest +++ b/sys-kernel/hppa-sources/Manifest @@ -1,34 +1,20 @@ +MD5 f176b7d1c3f6ed8055e2d49209e0fa90 hppa-sources-2.6.10_p10.ebuild 781 +MD5 fbfd4f9cf611b51f445dc4d48ae0b3da ChangeLog 9407 MD5 cbcc313360e342751159394094cc7a91 hppa-sources-2.4.26_p6-r1.ebuild 2292 MD5 6065b6be713a1b35043dc723a2a4113e hppa-sources-2.4.26_p7-r1.ebuild 2788 -MD5 d8189a6d07a8c842dc8bda25932e315b hppa-sources-2.4.26_p7.ebuild 2470 -MD5 9cfa49a935c84e6fd5ac3bd761ec17a2 hppa-sources-2.4.27_p4.ebuild 2077 MD5 05ed5731534e9423f109cbec1aa7e993 metadata.xml 223 +MD5 d8189a6d07a8c842dc8bda25932e315b hppa-sources-2.4.26_p7.ebuild 2470 MD5 10fd255ebe40865f3882ba5eb379a572 hppa-sources-2.4.27_p4-r1.ebuild 2419 MD5 3acd524873881040a638ee146acab19b hppa-sources-2.4.27_p4-r2.ebuild 2482 -MD5 0a4ebd23dbdbec245c59ff529772e6ee ChangeLog 8756 MD5 dcf6adc464035c767d3183e5f7774b26 hppa-sources-2.6.10_p1.ebuild 692 MD5 074dd720871b3b04b90e6f39c3664c7c hppa-sources-2.6.10_p2.ebuild 717 MD5 ca691817130aedfb73c935b3cda1e75b hppa-sources-2.6.10_p4.ebuild 717 MD5 53ec312f4db825cb5bf2971f99f3d35f hppa-sources-2.6.10_p6.ebuild 717 -MD5 d4a740ae56c2049247083af387a22a85 files/CAN-2004-0394.patch 350 -MD5 dc18e982f8149588a291956481885a8c files/CAN-2004-0495-2.4-sparse.patch 17549 -MD5 3bdf00d5f80fe9dfbfe8220e076cd04c files/CAN-2004-0497.patch 707 -MD5 0f66013f643c79c97fda489618a4e2fd files/CAN-2004-0535-2.4-e1000.patch 476 -MD5 60d25ff310fc6abfdce39ec9e47345af files/CAN-2004-685.patch 2809 -MD5 ff11f350435d0871b62d2f7a62bc463c files/digest-hppa-sources-2.4.26_p6-r1 224 -MD5 cf38cb04fc6f56768ff1fce46e5da41c files/digest-hppa-sources-2.4.26_p7 302 -MD5 fac8b9be67d8fe295b751bbf2b6c608c files/digest-hppa-sources-2.4.26_p7-r1 378 -MD5 c449f3e3ac5fd27c7771268cb03ee5ae files/digest-hppa-sources-2.4.27_p4 302 -MD5 222e890035f4ad3152f0c2a625a9ea67 files/security-proc-cmdline.patch 693 -MD5 4b99df79dcc18b17eb41489b96ff9689 files/CAN-2004-0814.patch 81529 -MD5 2b3ddb8b8b15f8da35ade38544b57857 files/NFS-XDR-security.patch 1499 -MD5 1e1fe7bb98c80db4644f4b7fd7dd5d32 files/CAN-2004-0882-0883.patch 3434 -MD5 24c53f49954dab29cfc172d4a3ba1a31 files/binfmt_elf-loader-security.patch 1928 -MD5 c449f3e3ac5fd27c7771268cb03ee5ae files/digest-hppa-sources-2.4.27_p4-r1 302 +MD5 9cfa49a935c84e6fd5ac3bd761ec17a2 hppa-sources-2.4.27_p4.ebuild 2077 +MD5 bd7b5cad7b0cadde6daab1e2c3abd13e files/digest-hppa-sources-2.6.10_p10 132 +MD5 cd0a7533c43364e377348613c6d76bb7 files/CAN-2004-1235.patch 9736 +MD5 b4f71191d0b9bc4439cdb8645ff474a7 files/LKA-20050107.patch 6122 MD5 001b0a631c9fc28133013a1f8f78f74c files/CAN-2004-1056.patch 8458 -MD5 b0a1f80aff51d6601e8924329023b241 files/AF_UNIX-security.patch 515 -MD5 39df49f91309f3c7b23bf87194885f5d files/CAN-2004-1074.patch 1877 -MD5 c449f3e3ac5fd27c7771268cb03ee5ae files/digest-hppa-sources-2.4.27_p4-r2 302 MD5 9d48df2d294a63b45bb9159d718000a2 files/digest-hppa-sources-2.6.10_p1 131 MD5 818ff61f20404922a662b3383416b453 files/digest-hppa-sources-2.6.10_p2 131 MD5 47f5d83813a16f62c031edd2e0c1b79b files/digest-hppa-sources-2.6.10_p4 131 diff --git a/sys-kernel/hppa-sources/files/AF_UNIX-security.patch b/sys-kernel/hppa-sources/files/AF_UNIX-security.patch deleted file mode 100644 index 6ced78404a2d..000000000000 --- a/sys-kernel/hppa-sources/files/AF_UNIX-security.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- linux-2.4.27/net/unix/af_unix.c 2004-11-24 08:23:21 -08:00 -+++ linux-2.4.28/net/unix/af_unix.c 2004-11-24 08:23:21 -08:00 -@@ -1403,9 +1403,11 @@ - - msg->msg_namelen = 0; - -+ down(&sk->protinfo.af_unix.readsem); -+ - skb = skb_recv_datagram(sk, flags, noblock, &err); - if (!skb) -- goto out; -+ goto out_unlock; - - wake_up_interruptible(&sk->protinfo.af_unix.peer_wait); - -@@ -1449,6 +1451,8 @@ - - out_free: - skb_free_datagram(sk,skb); -+out_unlock: -+ up(&sk->protinfo.af_unix.readsem); - out: - return err; - } diff --git a/sys-kernel/hppa-sources/files/CAN-2004-0394.patch b/sys-kernel/hppa-sources/files/CAN-2004-0394.patch deleted file mode 100644 index 273f1a52046f..000000000000 --- a/sys-kernel/hppa-sources/files/CAN-2004-0394.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- linux-2.4.22-oM3-orig/kernel/panic.c Tue Mar 30 15:37:18 2004 -+++ linux-2.4.22-oM3-mod/kernel/panic.c Mon May 17 18:44:01 2004 -@@ -51,7 +51,7 @@ - - bust_spinlocks(1); - va_start(args, fmt); -- vsprintf(buf, fmt, args); -+ vsnprintf(buf, sizeof(buf), fmt, args); - va_end(args); - printk(KERN_EMERG "Kernel panic: %s\n",buf); - if (in_interrupt()) diff --git a/sys-kernel/hppa-sources/files/CAN-2004-0495-2.4-sparse.patch b/sys-kernel/hppa-sources/files/CAN-2004-0495-2.4-sparse.patch deleted file mode 100644 index bea80eac69a9..000000000000 --- a/sys-kernel/hppa-sources/files/CAN-2004-0495-2.4-sparse.patch +++ /dev/null @@ -1,655 +0,0 @@ ---- linux/net/decnet/dn_dev.c.bak Wed Jun 16 14:42:24 2004 -+++ linux/net/decnet/dn_dev.c Wed Jun 16 14:42:34 2004 -@@ -1070,31 +1070,39 @@ int dnet_gifconf(struct net_device *dev, - { - struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr; - struct dn_ifaddr *ifa; -- struct ifreq *ifr = (struct ifreq *)buf; -+ char buffer[DN_IFREQ_SIZE]; -+ struct ifreq *ifr = (struct ifreq *)buffer; -+ struct sockaddr_dn *addr = (struct sockaddr_dn *)&ifr->ifr_addr; - int done = 0; - - if ((dn_db == NULL) || ((ifa = dn_db->ifa_list) == NULL)) - return 0; - - for(; ifa; ifa = ifa->ifa_next) { -- if (!ifr) { -+ if (!buf) { - done += sizeof(DN_IFREQ_SIZE); - continue; - } - if (len < DN_IFREQ_SIZE) - return done; -- memset(ifr, 0, DN_IFREQ_SIZE); -+ memset(buffer, 0, DN_IFREQ_SIZE); - - if (ifa->ifa_label) - strcpy(ifr->ifr_name, ifa->ifa_label); - else - strcpy(ifr->ifr_name, dev->name); - -- (*(struct sockaddr_dn *) &ifr->ifr_addr).sdn_family = AF_DECnet; -- (*(struct sockaddr_dn *) &ifr->ifr_addr).sdn_add.a_len = 2; -- (*(dn_address *)(*(struct sockaddr_dn *) &ifr->ifr_addr).sdn_add.a_addr) = ifa->ifa_local; -+ addr->sdn_family = AF_DECnet; -+ addr->sdn_add.a_len = 2; -+ memcpy(addr->sdn_add.a_addr, &ifa->ifa_local, -+ sizeof(dn_address)); - -- ifr = (struct ifreq *)((char *)ifr + DN_IFREQ_SIZE); -+ if (copy_to_user(buf, buffer, DN_IFREQ_SIZE)) { -+ done = -EFAULT; -+ break; -+ } -+ -+ buf += DN_IFREQ_SIZE; - len -= DN_IFREQ_SIZE; - done += DN_IFREQ_SIZE; - } ---- linux-2.4.21/drivers/net/wireless/airo.c 2003-06-13 15:51:35.000000000 +0100 -+++ linux-2.4.21/drivers/net/wireless/airo.c.plasmaroo 2004-06-24 11:09:08.260352168 +0100 -@@ -3012,19 +3012,22 @@ - size_t len, - loff_t *offset ) - { -- int i; -- int pos; -+ loff_t pos = *offset; - struct proc_data *priv = (struct proc_data*)file->private_data; - -- if( !priv->rbuffer ) return -EINVAL; -+ if (!priv->rbuffer) -+ return -EINVAL; - -- pos = *offset; -- for( i = 0; i+pos < priv->readlen && i < len; i++ ) { -- if (put_user( priv->rbuffer[i+pos], buffer+i )) -- return -EFAULT; -- } -- *offset += i; -- return i; -+ if (pos < 0) -+ return -EINVAL; -+ if (pos >= priv->readlen) -+ return 0; -+ if (len > priv->readlen - pos) -+ len = priv->readlen - pos; -+ if (copy_to_user(buffer, priv->rbuffer + pos, len)) -+ return -EFAULT; -+ *offset = pos + len; -+ return len; - } - - /* -@@ -3036,24 +3039,24 @@ - size_t len, - loff_t *offset ) - { -- int i; -- int pos; -+ loff_t pos = *offset; - struct proc_data *priv = (struct proc_data*)file->private_data; - -- if ( !priv->wbuffer ) { -+ if (!priv->wbuffer) - return -EINVAL; -- } -- -- pos = *offset; - -- for( i = 0; i + pos < priv->maxwritelen && -- i < len; i++ ) { -- if (get_user( priv->wbuffer[i+pos], buffer + i )) -- return -EFAULT; -- } -- if ( i+pos > priv->writelen ) priv->writelen = i+file->f_pos; -- *offset += i; -- return i; -+ if (pos < 0) -+ return -EINVAL; -+ if (pos >= priv->maxwritelen) -+ return 0; -+ if (len > priv->maxwritelen - pos) -+ len = priv->maxwritelen - pos; -+ if (copy_from_user(priv->wbuffer + pos, buffer, len)) -+ return -EFAULT; -+ if (pos + len > priv->writelen) -+ priv->writelen = pos + len; -+ *offset = pos + len; -+ return len; - } - - static int proc_status_open( struct inode *inode, struct file *file ) { ---- linux/drivers/sound/mpu401.c.bak Wed Jun 16 14:42:24 2004 -+++ linux/drivers/sound/mpu401.c Wed Jun 16 14:42:34 2004 -@@ -1493,14 +1493,16 @@ static unsigned long mpu_timer_get_time( - static int mpu_timer_ioctl(int dev, unsigned int command, caddr_t arg) - { - int midi_dev = sound_timer_devs[dev]->devlink; -+ int *p = (int *)arg; - - switch (command) - { - case SNDCTL_TMR_SOURCE: - { - int parm; -- -- parm = *(int *) arg; -+ -+ if (get_user(parm, p)) -+ return -EFAULT; - parm &= timer_caps; - - if (parm != 0) -@@ -1512,7 +1514,9 @@ static int mpu_timer_ioctl(int dev, unsi - else if (timer_mode & TMR_MODE_SMPTE) - mpu_cmd(midi_dev, 0x3d, 0); /* Use SMPTE sync */ - } -- return (*(int *) arg = timer_mode); -+ if (put_user(timer_mode, p)) -+ return -EFAULT; -+ return timer_mode; - } - break; - -@@ -1537,10 +1541,13 @@ static int mpu_timer_ioctl(int dev, unsi - { - int val; - -- val = *(int *) arg; -+ if (get_user(val, p)) -+ return -EFAULT; - if (val) - set_timebase(midi_dev, val); -- return (*(int *) arg = curr_timebase); -+ if (put_user(curr_timebase, p)) -+ return -EFAULT; -+ return curr_timebase; - } - break; - -@@ -1549,7 +1556,8 @@ static int mpu_timer_ioctl(int dev, unsi - int val; - int ret; - -- val = *(int *) arg; -+ if (get_user(val, p)) -+ return -EFAULT; - - if (val) - { -@@ -1564,7 +1572,9 @@ static int mpu_timer_ioctl(int dev, unsi - } - curr_tempo = val; - } -- return (*(int *) arg = curr_tempo); -+ if (put_user(curr_tempo, p)) -+ return -EFAULT; -+ return curr_tempo; - } - break; - -@@ -1572,18 +1582,25 @@ static int mpu_timer_ioctl(int dev, unsi - { - int val; - -- val = *(int *) arg; -+ if (get_user(val, p)) -+ return -EFAULT; - if (val != 0) /* Can't change */ - return -EINVAL; -- return (*(int *) arg = ((curr_tempo * curr_timebase) + 30) / 60); -+ val = (curr_tempo * curr_timebase + 30) / 60; -+ if (put_user(val, p)) -+ return -EFAULT; -+ return val; - } - break; - - case SNDCTL_SEQ_GETTIME: -- return (*(int *) arg = curr_ticks); -+ if (put_user(curr_ticks, p)) -+ return -EFAULT; -+ return curr_ticks; - - case SNDCTL_TMR_METRONOME: -- metronome_mode = *(int *) arg; -+ if (get_user(metronome_mode, p)) -+ return -EFAULT; - setup_metronome(midi_dev); - return 0; - ---- linux/drivers/sound/msnd.c.bak Wed Jun 16 14:42:24 2004 -+++ linux/drivers/sound/msnd.c Wed Jun 16 14:42:34 2004 -@@ -155,13 +155,10 @@ void msnd_fifo_make_empty(msnd_fifo *f) - f->len = f->tail = f->head = 0; - } - --int msnd_fifo_write(msnd_fifo *f, const char *buf, size_t len, int user) -+int msnd_fifo_write(msnd_fifo *f, const char *buf, size_t len) - { - int count = 0; - -- if (f->len == f->n) -- return 0; -- - while ((count < len) && (f->len != f->n)) { - - int nwritten; -@@ -177,11 +174,7 @@ int msnd_fifo_write(msnd_fifo *f, const - nwritten = len - count; - } - -- if (user) { -- if (copy_from_user(f->data + f->tail, buf, nwritten)) -- return -EFAULT; -- } else -- isa_memcpy_fromio(f->data + f->tail, (unsigned long) buf, nwritten); -+ isa_memcpy_fromio(f->data + f->tail, (unsigned long) buf, nwritten); - - count += nwritten; - buf += nwritten; -@@ -193,13 +186,10 @@ int msnd_fifo_write(msnd_fifo *f, const - return count; - } - --int msnd_fifo_read(msnd_fifo *f, char *buf, size_t len, int user) -+int msnd_fifo_read(msnd_fifo *f, char *buf, size_t len) - { - int count = 0; - -- if (f->len == 0) -- return f->len; -- - while ((count < len) && (f->len > 0)) { - - int nread; -@@ -215,11 +205,7 @@ int msnd_fifo_read(msnd_fifo *f, char *b - nread = len - count; - } - -- if (user) { -- if (copy_to_user(buf, f->data + f->head, nread)) -- return -EFAULT; -- } else -- isa_memcpy_toio((unsigned long) buf, f->data + f->head, nread); -+ isa_memcpy_toio((unsigned long) buf, f->data + f->head, nread); - - count += nread; - buf += nread; ---- linux/drivers/sound/msnd.h.bak Wed Jun 16 14:42:24 2004 -+++ linux/drivers/sound/msnd.h Wed Jun 16 14:42:34 2004 -@@ -266,8 +266,8 @@ void msnd_fifo_init(msnd_fifo *f); - void msnd_fifo_free(msnd_fifo *f); - int msnd_fifo_alloc(msnd_fifo *f, size_t n); - void msnd_fifo_make_empty(msnd_fifo *f); --int msnd_fifo_write(msnd_fifo *f, const char *buf, size_t len, int user); --int msnd_fifo_read(msnd_fifo *f, char *buf, size_t len, int user); -+int msnd_fifo_write(msnd_fifo *f, const char *buf, size_t len); -+int msnd_fifo_read(msnd_fifo *f, char *buf, size_t len); - - int msnd_wait_TXDE(multisound_dev_t *dev); - int msnd_wait_HC0(multisound_dev_t *dev); ---- linux/drivers/sound/msnd_pinnacle.c.bak Wed Jun 16 14:42:24 2004 -+++ linux/drivers/sound/msnd_pinnacle.c Wed Jun 16 14:42:34 2004 -@@ -804,7 +804,7 @@ static int dev_release(struct inode *ino - - static __inline__ int pack_DARQ_to_DARF(register int bank) - { -- register int size, n, timeout = 3; -+ register int size, timeout = 3; - register WORD wTmp; - LPDAQD DAQD; - -@@ -825,13 +825,10 @@ static __inline__ int pack_DARQ_to_DARF( - /* Read data from the head (unprotected bank 1 access okay - since this is only called inside an interrupt) */ - outb(HPBLKSEL_1, dev.io + HP_BLKS); -- if ((n = msnd_fifo_write( -+ msnd_fifo_write( - &dev.DARF, - (char *)(dev.base + bank * DAR_BUFF_SIZE), -- size, 0)) <= 0) { -- outb(HPBLKSEL_0, dev.io + HP_BLKS); -- return n; -- } -+ size); - outb(HPBLKSEL_0, dev.io + HP_BLKS); - - return 1; -@@ -853,21 +850,16 @@ static __inline__ int pack_DAPF_to_DAPQ( - if (protect) { - /* Critical section: protect fifo in non-interrupt */ - spin_lock_irqsave(&dev.lock, flags); -- if ((n = msnd_fifo_read( -+ n = msnd_fifo_read( - &dev.DAPF, - (char *)(dev.base + bank_num * DAP_BUFF_SIZE), -- DAP_BUFF_SIZE, 0)) < 0) { -- spin_unlock_irqrestore(&dev.lock, flags); -- return n; -- } -+ DAP_BUFF_SIZE); - spin_unlock_irqrestore(&dev.lock, flags); - } else { -- if ((n = msnd_fifo_read( -+ n = msnd_fifo_read( - &dev.DAPF, - (char *)(dev.base + bank_num * DAP_BUFF_SIZE), -- DAP_BUFF_SIZE, 0)) < 0) { -- return n; -- } -+ DAP_BUFF_SIZE); - } - if (!n) - break; -@@ -894,30 +886,43 @@ static __inline__ int pack_DAPF_to_DAPQ( - static int dsp_read(char *buf, size_t len) - { - int count = len; -+ char *page = (char *)__get_free_page(PAGE_SIZE); -+ -+ if (!page) -+ return -ENOMEM; - - while (count > 0) { -- int n; -+ int n, k; - unsigned long flags; - -+ k = PAGE_SIZE; -+ if (k > count) -+ k = count; -+ - /* Critical section: protect fifo in non-interrupt */ - spin_lock_irqsave(&dev.lock, flags); -- if ((n = msnd_fifo_read(&dev.DARF, buf, count, 1)) < 0) { -- printk(KERN_WARNING LOGNAME ": FIFO read error\n"); -- spin_unlock_irqrestore(&dev.lock, flags); -- return n; -- } -+ n = msnd_fifo_read(&dev.DARF, page, k); - spin_unlock_irqrestore(&dev.lock, flags); -+ if (copy_to_user(buf, page, n)) { -+ free_page((unsigned long)page); -+ return -EFAULT; -+ } - buf += n; - count -= n; - -+ if (n == k && count) -+ continue; -+ - if (!test_bit(F_READING, &dev.flags) && dev.mode & FMODE_READ) { - dev.last_recbank = -1; - if (chk_send_dsp_cmd(&dev, HDEX_RECORD_START) == 0) - set_bit(F_READING, &dev.flags); - } - -- if (dev.rec_ndelay) -+ if (dev.rec_ndelay) { -+ free_page((unsigned long)page); - return count == len ? -EAGAIN : len - count; -+ } - - if (count > 0) { - set_bit(F_READBLOCK, &dev.flags); -@@ -926,41 +931,57 @@ static int dsp_read(char *buf, size_t le - get_rec_delay_jiffies(DAR_BUFF_SIZE))) - clear_bit(F_READING, &dev.flags); - clear_bit(F_READBLOCK, &dev.flags); -- if (signal_pending(current)) -+ if (signal_pending(current)) { -+ free_page((unsigned long)page); - return -EINTR; -+ } - } - } -- -+ free_page((unsigned long)page); - return len - count; - } - - static int dsp_write(const char *buf, size_t len) - { - int count = len; -+ char *page = (char *)__get_free_page(GFP_KERNEL); -+ -+ if (!page) -+ return -ENOMEM; - - while (count > 0) { -- int n; -+ int n, k; - unsigned long flags; - -+ k = PAGE_SIZE; -+ if (k > count) -+ k = count; -+ -+ if (copy_from_user(page, buf, k)) { -+ free_page((unsigned long)page); -+ return -EFAULT; -+ } -+ - /* Critical section: protect fifo in non-interrupt */ - spin_lock_irqsave(&dev.lock, flags); -- if ((n = msnd_fifo_write(&dev.DAPF, buf, count, 1)) < 0) { -- printk(KERN_WARNING LOGNAME ": FIFO write error\n"); -- spin_unlock_irqrestore(&dev.lock, flags); -- return n; -- } -+ n = msnd_fifo_write(&dev.DAPF, page, k); - spin_unlock_irqrestore(&dev.lock, flags); - buf += n; - count -= n; - -+ if (count && n == k) -+ continue; -+ - if (!test_bit(F_WRITING, &dev.flags) && (dev.mode & FMODE_WRITE)) { - dev.last_playbank = -1; - if (pack_DAPF_to_DAPQ(1) > 0) - set_bit(F_WRITING, &dev.flags); - } - -- if (dev.play_ndelay) -+ if (dev.play_ndelay) { -+ free_page((unsigned long)page); - return count == len ? -EAGAIN : len - count; -+ } - - if (count > 0) { - set_bit(F_WRITEBLOCK, &dev.flags); -@@ -968,11 +989,14 @@ static int dsp_write(const char *buf, si - &dev.writeblock, - get_play_delay_jiffies(DAP_BUFF_SIZE)); - clear_bit(F_WRITEBLOCK, &dev.flags); -- if (signal_pending(current)) -+ if (signal_pending(current)) { -+ free_page((unsigned long)page); - return -EINTR; -+ } - } - } - -+ free_page((unsigned long)page); - return len - count; - } - ---- linux/drivers/sound/pss.c.bak Wed Jun 16 14:42:24 2004 -+++ linux/drivers/sound/pss.c Wed Jun 16 14:42:34 2004 -@@ -450,20 +450,36 @@ static void pss_mixer_reset(pss_confdata - } - } - --static void arg_to_volume_mono(unsigned int volume, int *aleft) -+static int set_volume_mono(caddr_t p, int *aleft) - { - int left; -+ unsigned volume; -+ if (get_user(volume, (unsigned *)p)) -+ return -EFAULT; - -- left = volume & 0x00ff; -+ left = volume & 0xff; - if (left > 100) - left = 100; - *aleft = left; -+ return 0; - } - --static void arg_to_volume_stereo(unsigned int volume, int *aleft, int *aright) -+static int set_volume_stereo(caddr_t p, int *aleft, int *aright) - { -- arg_to_volume_mono(volume, aleft); -- arg_to_volume_mono(volume >> 8, aright); -+ int left, right; -+ unsigned volume; -+ if (get_user(volume, (unsigned *)p)) -+ return -EFAULT; -+ -+ left = volume & 0xff; -+ if (left > 100) -+ left = 100; -+ right = (volume >> 8) & 0xff; -+ if (right > 100) -+ right = 100; -+ *aleft = left; -+ *aright = right; -+ return 0; - } - - static int ret_vol_mono(int left) -@@ -510,33 +526,38 @@ static int pss_mixer_ioctl (int dev, uns - return call_ad_mixer(devc, cmd, arg); - else - { -- if (*(int *)arg != 0) -+ int v; -+ if (get_user(v, (int *)arg)) -+ return -EFAULT; -+ if (v != 0) - return -EINVAL; - return 0; - } - case SOUND_MIXER_VOLUME: -- arg_to_volume_stereo(*(unsigned int *)arg, &devc->mixer.volume_l, -- &devc->mixer.volume_r); -+ if (set_volume_stereo(arg, -+ &devc->mixer.volume_l, -+ &devc->mixer.volume_r)) -+ return -EFAULT; - set_master_volume(devc, devc->mixer.volume_l, - devc->mixer.volume_r); - return ret_vol_stereo(devc->mixer.volume_l, - devc->mixer.volume_r); - - case SOUND_MIXER_BASS: -- arg_to_volume_mono(*(unsigned int *)arg, -- &devc->mixer.bass); -+ if (set_volume_mono(arg, &devc->mixer.bass)) -+ return -EFAULT; - set_bass(devc, devc->mixer.bass); - return ret_vol_mono(devc->mixer.bass); - - case SOUND_MIXER_TREBLE: -- arg_to_volume_mono(*(unsigned int *)arg, -- &devc->mixer.treble); -+ if (set_volume_mono(arg, &devc->mixer.treble)) -+ return -EFAULT; - set_treble(devc, devc->mixer.treble); - return ret_vol_mono(devc->mixer.treble); - - case SOUND_MIXER_SYNTH: -- arg_to_volume_mono(*(unsigned int *)arg, -- &devc->mixer.synth); -+ if (set_volume_mono(arg, &devc->mixer.synth)) -+ return -EFAULT; - set_synth_volume(devc, devc->mixer.synth); - return ret_vol_mono(devc->mixer.synth); - -@@ -546,54 +567,67 @@ static int pss_mixer_ioctl (int dev, uns - } - else - { -+ int val, and_mask = 0, or_mask = 0; - /* - * Return parameters - */ - switch (cmdf) - { -- - case SOUND_MIXER_DEVMASK: - if (call_ad_mixer(devc, cmd, arg) == -EINVAL) -- *(int *)arg = 0; /* no mixer devices */ -- return (*(int *)arg |= SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE | SOUND_MASK_SYNTH); -+ break; -+ and_mask = ~0; -+ or_mask = SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE | SOUND_MASK_SYNTH; -+ break; - - case SOUND_MIXER_STEREODEVS: - if (call_ad_mixer(devc, cmd, arg) == -EINVAL) -- *(int *)arg = 0; /* no stereo devices */ -- return (*(int *)arg |= SOUND_MASK_VOLUME); -+ break; -+ and_mask = ~0; -+ or_mask = SOUND_MASK_VOLUME; -+ break; - - case SOUND_MIXER_RECMASK: - if (devc->ad_mixer_dev != NO_WSS_MIXER) - return call_ad_mixer(devc, cmd, arg); -- else -- return (*(int *)arg = 0); /* no record devices */ -+ break; - - case SOUND_MIXER_CAPS: - if (devc->ad_mixer_dev != NO_WSS_MIXER) - return call_ad_mixer(devc, cmd, arg); -- else -- return (*(int *)arg = SOUND_CAP_EXCL_INPUT); -+ or_mask = SOUND_CAP_EXCL_INPUT; -+ break; - - case SOUND_MIXER_RECSRC: - if (devc->ad_mixer_dev != NO_WSS_MIXER) - return call_ad_mixer(devc, cmd, arg); -- else -- return (*(int *)arg = 0); /* no record source */ -+ break; - - case SOUND_MIXER_VOLUME: -- return (*(int *)arg = ret_vol_stereo(devc->mixer.volume_l, devc->mixer.volume_r)); -+ or_mask = ret_vol_stereo(devc->mixer.volume_l, devc->mixer.volume_r); -+ break; - - case SOUND_MIXER_BASS: -- return (*(int *)arg = ret_vol_mono(devc->mixer.bass)); -+ or_mask = ret_vol_mono(devc->mixer.bass); -+ break; - - case SOUND_MIXER_TREBLE: -- return (*(int *)arg = ret_vol_mono(devc->mixer.treble)); -+ or_mask = ret_vol_mono(devc->mixer.treble); -+ break; - - case SOUND_MIXER_SYNTH: -- return (*(int *)arg = ret_vol_mono(devc->mixer.synth)); -+ or_mask = ret_vol_mono(devc->mixer.synth); -+ break; - default: - return -EINVAL; - } -+ if (get_user(val, (int *)arg)) -+ return -EFAULT; -+ val &= and_mask; -+ val |= or_mask; -+ if (put_user(val, (int *)arg)) -+ return -EFAULT; -+ return val; - } - } - diff --git a/sys-kernel/hppa-sources/files/CAN-2004-0497.patch b/sys-kernel/hppa-sources/files/CAN-2004-0497.patch deleted file mode 100644 index 9503e9efe57b..000000000000 --- a/sys-kernel/hppa-sources/files/CAN-2004-0497.patch +++ /dev/null @@ -1,23 +0,0 @@ -# ChangeSet -# -# fs/attr.c -# 2004/07/03 18:28:30-03:00 marcelo@logos.cnet +1 -0 -# Thomas Biege: Fix missing DAC check on sys_chown -# -# fs/attr.c -# 2004/07/03 19:28:29-03:00 marcelo@logos.cnet +1 -1 -# Add missing bracket to inode_change_ok() fix -# -diff -Nru a/fs/attr.c b.plasmaroo/fs/attr.c ---- a/fs/attr.c 2004-07-08 17:05:20 -07:00 -+++ b.plasmaroo/fs/attr.c 2004-07-08 17:05:20 -07:00 -@@ -35,7 +35,8 @@ - - /* Make sure caller can chgrp. */ - if ((ia_valid & ATTR_GID) && -- (!in_group_p(attr->ia_gid) && attr->ia_gid != inode->i_gid) && -+ (current->fsuid != inode->i_uid || -+ (!in_group_p(attr->ia_gid) && attr->ia_gid != inode->i_gid)) && - !capable(CAP_CHOWN)) - goto error; - diff --git a/sys-kernel/hppa-sources/files/CAN-2004-0535-2.4-e1000.patch b/sys-kernel/hppa-sources/files/CAN-2004-0535-2.4-e1000.patch deleted file mode 100644 index 669fc5fd32fb..000000000000 --- a/sys-kernel/hppa-sources/files/CAN-2004-0535-2.4-e1000.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- drivers/net/e1000/e1000_ethtool.c 2003-06-13 15:51:34.000000000 +0100 -+++ drivers/net/e1000/e1000_ethtool.c.plasmaroo 2004-06-24 11:23:32.524963976 +0100 -@@ -468,6 +468,9 @@ - - if(copy_from_user(®s, addr, sizeof(regs))) - return -EFAULT; -+ memset(regs_buff, 0, sizeof(regs_buff)); -+ if (regs.len > E1000_REGS_LEN) -+ regs.len = E1000_REGS_LEN; - e1000_ethtool_gregs(adapter, ®s, regs_buff); - if(copy_to_user(addr, ®s, sizeof(regs))) - return -EFAULT; diff --git a/sys-kernel/hppa-sources/files/CAN-2004-0814.patch b/sys-kernel/hppa-sources/files/CAN-2004-0814.patch deleted file mode 100644 index bf62e3540583..000000000000 --- a/sys-kernel/hppa-sources/files/CAN-2004-0814.patch +++ /dev/null @@ -1,2805 +0,0 @@ -diff -Nur linux-2.4.27/Documentation/tty.txt linux-2.4.27-plasmaroo/Documentation/tty.txt ---- linux-2.4.27/Documentation/tty.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.27-plasmaroo/Documentation/tty.txt 2004-11-07 14:02:20.344653040 +0000 -@@ -0,0 +1,194 @@ -+ -+ The Lockronomicon -+ -+Your guide to the ancient and twisted locking policies of the tty layer and -+the warped logic behind them. Beware all ye who read on. -+ -+FIXME: still need to work out the full set of BKL assumptions and document -+them so they can eventually be killed off. -+ -+ -+Line Discipline -+--------------- -+ -+Line disciplines are registered with tty_register_ldisc() passing the -+discipline number and the ldisc structure. At the point of registration the -+discipline must be ready to use and it is possible it will get used before -+the call returns success. If the call returns an error then it won't get -+called. Do not re-use ldisc numbers as they are part of the userspace ABI -+and writing over an existing ldisc will cause demons to eat your computer. -+After the return the ldisc data has been copied so you may free your own -+copy of the structure. You must not re-register over the top of the line -+discipline even with the same data or your computer again will be eaten by -+demons. -+ -+In order to remove a line discipline call tty_register_ldisc passing NULL. -+In ancient times this always worked. In modern times the function will -+return -EBUSY if the ldisc is currently in use. Since the ldisc referencing -+code manages the module counts this should not usually be a concern. -+ -+Heed this warning: the reference count field of the registered copies of the -+tty_ldisc structure in the ldisc table counts the number of lines using this -+discipline. The reference count of the tty_ldisc structure within a tty -+counts the number of active users of the ldisc at this instant. In effect it -+counts the number of threads of execution within an ldisc method (plus those -+about to enter and exit although this detail matters not). -+ -+Line Discipline Methods -+----------------------- -+ -+TTY side interfaces: -+ -+close() - This is called on a terminal when the line -+ discipline is being unplugged. At the point of -+ execution no further users will enter the -+ ldisc code for this tty. Can sleep. -+ -+open() - Called when the line discipline is attached to -+ the terminal. No other call into the line -+ discipline for this tty will occur until it -+ completes successfully. Can sleep. -+ -+write() - A process is writing data from user space -+ through the line discipline. Multiple write calls -+ are serialized by the tty layer for the ldisc. May -+ sleep. -+ -+flush_buffer() - May be called at any point between open and close. -+ -+chars_in_buffer() - Report the number of bytes in the buffer. -+ -+set_termios() - Called on termios structure changes. The caller -+ passes the old termios data and the current data -+ is in the tty. Currently can be parallel entered -+ and ordering isn't predictable - FIXME -+ -+read() - Move data from the line discipline to the user. -+ Multiple read calls may occur in parallel and the -+ ldisc must deal with serialization issues. May -+ sleep. -+ -+poll() - Check the status for the poll/select calls. Multiple -+ poll calls may occur in parallel. May sleep. -+ -+ioctl() - Called when an ioctl is handed to the tty layer -+ that might be for the ldisc. Multiple ioctl calls -+ may occur in parallel. May sleep. -+ -+Driver Side Interfaces: -+ -+receive_buf() - Hand buffers of bytes from the driver to the ldisc -+ for processing. Semantics currently rather -+ mysterious 8( -+ -+receive_room() - Can be called by the driver layer at any time when -+ the ldisc is opened. The ldisc must be able to -+ handle the reported amount of data at that instant. -+ Synchronization between active receive_buf and -+ receive_room calls is down to the driver not the -+ ldisc. Must not sleep. -+ -+write_wakeup() - May be called at any point between open and close. -+ The TTY_DO_WRITE_WAKEUP flag indicates if a call -+ is needed but always races versus calls. Thus the -+ ldisc must be careful about setting order and to -+ handle unexpected calls. Must not sleep. -+ -+ -+Locking -+ -+Callers to the line discipline functions from the tty layer are required to -+take line discipline locks. The same is true of calls from the driver side -+but not yet enforced. -+ -+Three calls are now provided -+ -+ ldisc = tty_ldisc_ref(tty); -+ -+takes a handle to the line discipline in the tty and returns it. If no ldisc -+is currently attached or the ldisc is being closed and re-opened at this -+point then NULL is returned. While this handle is held the ldisc will not -+change or go away. -+ -+ tty_ldisc_deref(ldisc) -+ -+Returns the ldisc reference and allows the ldisc to be closed. Returning the -+reference takes away your right to call the ldisc functions until you take -+a new reference. -+ -+ ldisc = tty_ldisc_ref_wait(tty); -+ -+Performs the same function as tty_ldisc_ref except that it will wait for an -+ldisc change to complete and then return a reference to the new ldisc. -+ -+While these functions are slightly slower than the old code they should have -+minimal impact as most receive logic uses the flip buffers and they only -+need to take a reference when they push bits up through the driver. -+ -+A caution: The ldisc->open(), ldisc->close() and driver->set_ldisc -+functions are called with the ldisc unavailable. Thus tty_ldisc_ref will -+fail in this situation if used within these functions. Ldisc and driver -+code calling its own functions must be careful in this case. -+ -+ -+Driver Interface -+---------------- -+ -+open() - Called when a device is opened. May sleep -+ -+close() - Called when a device is closed. At the point of -+ return from this call the driver must make no -+ further ldisc calls of any kind. May sleep -+ -+write() - Called to write bytes to the device. May not -+ sleep. May occur in parallel in special cases. -+ Because this includes panic paths drivers generally -+ shouldn't try and do clever locking here. -+ -+put_char() - Stuff a single character onto the queue. The -+ driver is guaranteed following up calls to -+ flush_chars. -+ -+flush_chars() - Ask the kernel to write put_char queue -+ -+write_room() - Return the number of characters tht can be stuffed -+ into the port buffers without overflow (or less). -+ The ldisc is responsible for being intelligent -+ about multi-threading of write_room/write calls -+ -+ioctl() - Called when an ioctl may be for the driver -+ -+set_termios() - Called on termios change, may get parallel calls, -+ may block for now (may change that) -+ -+set_ldisc() - Notifier for discipline change. At the point this -+ is done the discipline is not yet usable. Can now -+ sleep (I think) -+ -+throttle() - Called by the ldisc to ask the driver to do flow -+ control. Serialization including with unthrottle -+ is the job of the ldisc layer. -+ -+unthrottle() - Called by the ldisc to ask the driver to stop flow -+ control. -+ -+stop() - Ldisc notifier to the driver to stop output. As with -+ throttle the serializations with start() are down -+ to the ldisc layer. -+ -+start() - Ldisc notifier to the driver to start output. -+ -+hangup() - Ask the tty driver to cause a hangup initiated -+ from the host side. [Can sleep ??] -+ -+break_ctl() - Send RS232 break. Can sleep. Can get called in -+ parallel, driver must serialize (for now), and -+ with write calls. -+ -+wait_until_sent() - Wait for characters to exit the hardware queue -+ of the driver. Can sleep -+ -+send_xchar() - Send XON/XOFF and if possible jump the queue with -+ it in order to get fast flow control responses. -+ Cannot sleep ?? -+ -diff -Nur linux-2.4.27/drivers/bluetooth/hci_ldisc.c linux-2.4.27-plasmaroo/drivers/bluetooth/hci_ldisc.c ---- linux-2.4.27/drivers/bluetooth/hci_ldisc.c 2004-08-08 00:26:04.000000000 +0100 -+++ linux-2.4.27-plasmaroo/drivers/bluetooth/hci_ldisc.c 2004-11-07 14:02:20.343653192 +0000 -@@ -181,6 +181,7 @@ - { - struct hci_uart *hu = (struct hci_uart *) hdev->driver_data; - struct tty_struct *tty = hu->tty; -+ struct tty_ldisc *ld = tty_ldisc_ref(tty); - - BT_DBG("hdev %p tty %p", hdev, tty); - -@@ -188,9 +189,11 @@ - kfree_skb(hu->tx_skb); hu->tx_skb = NULL; - } - -- /* Flush any pending characters in the driver and discipline. */ -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ if (ld) { -+ if(ld->flush_buffer) -+ ld->flush_buffer(tty); -+ tty_ldisc_deref(ld); -+ } - - if (tty->driver.flush_buffer) - tty->driver.flush_buffer(tty); -@@ -283,7 +286,9 @@ - - spin_lock_init(&hu->rx_lock); - -- /* Flush any pending characters in the driver and line discipline */ -+ /* Flush any pending characters in the driver and line discipline. */ -+ /* FIXME: why is this needed. Note don't use ldisc_ref here as the -+ open path is before the ldisc is referencable */ - if (tty->ldisc.flush_buffer) - tty->ldisc.flush_buffer(tty); - -diff -Nur linux-2.4.27/drivers/char/amiserial.c linux-2.4.27-plasmaroo/drivers/char/amiserial.c ---- linux-2.4.27/drivers/char/amiserial.c 2002-11-28 23:53:12.000000000 +0000 -+++ linux-2.4.27-plasmaroo/drivers/char/amiserial.c 2004-11-07 14:02:20.143683592 +0000 -@@ -575,9 +575,7 @@ - return; - - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - } -@@ -1041,9 +1039,7 @@ - info->xmit.head = info->xmit.tail = 0; - restore_flags(flags); - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - /* -@@ -1526,6 +1522,7 @@ - struct async_struct * info = (struct async_struct *)tty->driver_data; - struct serial_state *state; - unsigned long flags; -+ struct tty_ldisc *ld; - - if (!info || serial_paranoia_check(info, tty->device, "rs_close")) - return; -@@ -1608,8 +1605,12 @@ - shutdown(info); - if (tty->driver.flush_buffer) - tty->driver.flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ ld = tty_ldisc_ref(tty); -+ if (ld != NULL) { -+ if (ld->flush_buffer) -+ ld->flush_buffer(tty); -+ tty_ldisc_deref(ld); -+ } - tty->closing = 0; - info->event = 0; - info->tty = 0; -diff -Nur linux-2.4.27/drivers/char/cyclades.c linux-2.4.27-plasmaroo/drivers/char/cyclades.c ---- linux-2.4.27/drivers/char/cyclades.c 2003-06-13 15:51:32.000000000 +0100 -+++ linux-2.4.27-plasmaroo/drivers/char/cyclades.c 2004-11-07 14:02:20.157681464 +0000 -@@ -1000,10 +1000,7 @@ - wake_up_interruptible(&info->delta_msr_wait); - } - if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) { -- if((tty->flags & (1<< TTY_DO_WRITE_WAKEUP)) -- && tty->ldisc.write_wakeup){ -- (tty->ldisc.write_wakeup)(tty); -- } -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - #ifdef Z_WAKE -@@ -2801,6 +2798,7 @@ - cy_close(struct tty_struct *tty, struct file *filp) - { - struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; -+ struct tty_ldisc *ld; - unsigned long flags; - - #ifdef CY_DEBUG_OTHER -@@ -2918,8 +2916,13 @@ - shutdown(info); - if (tty->driver.flush_buffer) - tty->driver.flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ -+ ld = tty_ldisc_ref(tty); -+ if (ld) { -+ if (ld->flush_buffer) -+ ld->flush_buffer(tty); -+ tty_ldisc_deref(ld); -+ } - CY_LOCK(info, flags); - - tty->closing = 0; -@@ -4689,10 +4692,8 @@ - } - CY_UNLOCK(info, flags); - } -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) -- && tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); - } /* cy_flush_buffer */ - - -diff -Nur linux-2.4.27/drivers/char/dz.c linux-2.4.27-plasmaroo/drivers/char/dz.c ---- linux-2.4.27/drivers/char/dz.c 2004-02-18 13:36:31.000000000 +0000 -+++ linux-2.4.27-plasmaroo/drivers/char/dz.c 2004-11-07 14:02:20.289661400 +0000 -@@ -1112,10 +1112,10 @@ - info->event = 0; - info->tty = 0; - -- if (tty->ldisc.num != ldiscs[N_TTY].num) { -+ if (tty->ldisc.num != N_TTY) { - if (tty->ldisc.close) - (tty->ldisc.close) (tty); -- tty->ldisc = ldiscs[N_TTY]; -+ tty->ldisc = *(tty_ldisc_get(N_TTY)); - tty->termios->c_line = N_TTY; - if (tty->ldisc.open) - (tty->ldisc.open) (tty); -diff -Nur linux-2.4.27/drivers/char/epca.c linux-2.4.27-plasmaroo/drivers/char/epca.c ---- linux-2.4.27/drivers/char/epca.c 2003-06-13 15:51:33.000000000 +0100 -+++ linux-2.4.27-plasmaroo/drivers/char/epca.c 2004-11-07 14:02:20.182677664 +0000 -@@ -524,6 +524,7 @@ - - if ((ch = verifyChannel(tty)) != NULL) - { /* Begin if ch != NULL */ -+ struct tty_ldisc *ld; - - save_flags(flags); - cli(); -@@ -585,8 +586,12 @@ - if (tty->driver.flush_buffer) - tty->driver.flush_buffer(tty); - -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ ld = tty_ldisc_ref(tty); -+ if (ld != NULL) { -+ if(ld->flush_buffer) -+ ld->flush_buffer(tty); -+ tty_ldisc_deref(ld); -+ } - - shutdown(ch); - tty->closing = 0; -@@ -687,12 +692,20 @@ - { /* Begin if ch != NULL */ - - unsigned long flags; -+ struct tty_ldisc *ld; - - save_flags(flags); - cli(); - if (tty->driver.flush_buffer) - tty->driver.flush_buffer(tty); - -+ ld = tty_ldisc_ref(tty); -+ if (ld != NULL) { -+ if (ld->flush_buffer) -+ ld->flush_buffer(tty); -+ tty_ldisc_deref(ld); -+ } -+ - if (tty->ldisc.flush_buffer) - tty->ldisc.flush_buffer(tty); - -@@ -1176,8 +1189,7 @@ - restore_flags(flags); - - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - - } /* End pc_flush_buffer */ - -@@ -2383,9 +2395,7 @@ - { /* Begin if LOWWAIT */ - - ch->statusflags &= ~LOWWAIT; -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - - } /* End if LOWWAIT */ -@@ -2402,9 +2412,7 @@ - { /* Begin if EMPTYWAIT */ - - ch->statusflags &= ~EMPTYWAIT; -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - - wake_up_interruptible(&tty->write_wait); - -@@ -3255,6 +3263,7 @@ - } - else - { -+ /* ldisc lock already held in ioctl */ - if (tty->ldisc.flush_buffer) - tty->ldisc.flush_buffer(tty); - } -diff -Nur linux-2.4.27/drivers/char/generic_serial.c linux-2.4.27-plasmaroo/drivers/char/generic_serial.c ---- linux-2.4.27/drivers/char/generic_serial.c 2002-11-28 23:53:12.000000000 +0000 -+++ linux-2.4.27-plasmaroo/drivers/char/generic_serial.c 2004-11-07 14:02:20.187676904 +0000 -@@ -440,9 +440,7 @@ - restore_flags(flags); - - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - func_exit (); - } - -@@ -582,9 +580,7 @@ - if (!tty) return; - - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - func_exit (); -@@ -729,8 +725,9 @@ - { - unsigned long flags; - struct gs_port *port; -- -- func_enter (); -+ struct tty_ldisc *ld; -+ -+ func_enter(); - - if (!tty) return; - -@@ -803,8 +800,12 @@ - - if (tty->driver.flush_buffer) - tty->driver.flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ ld = tty_ldisc_ref(tty); -+ if (ld != NULL) { -+ if (ld->flush_buffer) -+ ld->flush_buffer(tty); -+ tty_ldisc_deref(ld); -+ } - tty->closing = 0; - - port->event = 0; -diff -Nur linux-2.4.27/drivers/char/isicom.c linux-2.4.27-plasmaroo/drivers/char/isicom.c ---- linux-2.4.27/drivers/char/isicom.c 2003-06-13 15:51:33.000000000 +0100 -+++ linux-2.4.27-plasmaroo/drivers/char/isicom.c 2004-11-07 14:02:20.195675688 +0000 -@@ -502,10 +502,8 @@ - - if (!tty) - return; -- -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - -@@ -1144,6 +1142,7 @@ - struct isi_port * port = (struct isi_port *) tty->driver_data; - struct isi_board * card = port->card; - unsigned long flags; -+ struct tty_ldisc *ld; - - if (!port) - return; -@@ -1199,6 +1198,12 @@ - isicom_shutdown_port(port); - if (tty->driver.flush_buffer) - tty->driver.flush_buffer(tty); -+ ld = tty_ldisc_ref(tty); -+ if (ld != NULL) { -+ if (ld->flush_buffer) -+ ld->flush_buffer(tty); -+ tty_ldisc_deref(ld); -+ } - if (tty->ldisc.flush_buffer) - tty->ldisc.flush_buffer(tty); - tty->closing = 0; -@@ -1671,9 +1676,7 @@ - restore_flags(flags); - - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - -diff -Nur linux-2.4.27/drivers/char/moxa.c linux-2.4.27-plasmaroo/drivers/char/moxa.c ---- linux-2.4.27/drivers/char/moxa.c 2001-10-25 21:53:47.000000000 +0100 -+++ linux-2.4.27-plasmaroo/drivers/char/moxa.c 2004-11-07 14:02:20.200674928 +0000 -@@ -620,6 +620,7 @@ - { - struct moxa_str *ch; - int port; -+ struct tty_ldisc *ld; - - port = PORTNO(tty); - if (port == MAX_PORTS) { -@@ -677,8 +678,13 @@ - - if (tty->driver.flush_buffer) - tty->driver.flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ -+ ld = tty_ldisc_ref(tty); -+ if (ld != NULL) { -+ if (ld->flush_buffer) -+ ld->flush_buffer(tty); -+ tty_ldisc_deref(ld); -+ } - tty->closing = 0; - ch->event = 0; - ch->tty = 0; -@@ -754,9 +760,7 @@ - if (ch == NULL) - return; - MoxaPortFlushData(ch->port, 1); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup) (tty); -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - -@@ -992,7 +996,6 @@ - moxaTimer.function = moxa_poll; - moxaTimer.expires = jiffies + (HZ / 50); - moxaTimer_on = 1; -- add_timer(&moxaTimer); - return; - } - for (card = 0; card < MAX_BOARDS; card++) { -@@ -1011,9 +1014,7 @@ - if (MoxaPortTxQueue(ch->port) <= WAKEUP_CHARS) { - if (!tp->stopped) { - ch->statusflags &= ~LOWWAIT; -- if ((tp->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tp->ldisc.write_wakeup) -- (tp->ldisc.write_wakeup) (tp); -+ tty_wakeup(tp); - wake_up_interruptible(&tp->write_wait); - } - } -@@ -1203,9 +1204,7 @@ - if (ch->tty && (ch->statusflags & EMPTYWAIT)) { - if (MoxaPortTxQueue(ch->port) == 0) { - ch->statusflags &= ~EMPTYWAIT; -- if ((ch->tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- ch->tty->ldisc.write_wakeup) -- (ch->tty->ldisc.write_wakeup) (ch->tty); -+ tty_wakeup(ch->tty); - wake_up_interruptible(&ch->tty->write_wait); - return; - } -diff -Nur linux-2.4.27/drivers/char/mxser.c linux-2.4.27-plasmaroo/drivers/char/mxser.c ---- linux-2.4.27/drivers/char/mxser.c 2002-11-28 23:53:12.000000000 +0000 -+++ linux-2.4.27-plasmaroo/drivers/char/mxser.c 2004-11-07 14:02:20.212673104 +0000 -@@ -725,9 +725,7 @@ - tty = info->tty; - if (tty) { - if (test_and_clear_bit(MXSER_EVENT_TXLOW, &info->event)) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup) (tty); -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - if (test_and_clear_bit(MXSER_EVENT_HANGUP, &info->event)) { -@@ -810,6 +808,7 @@ - struct mxser_struct *info = (struct mxser_struct *) tty->driver_data; - unsigned long flags; - unsigned long timeout; -+ struct tty_ldisc *ld; - - if (PORTNO(tty) == MXSER_PORTS) - return; -@@ -890,6 +889,12 @@ - mxser_shutdown(info); - if (tty->driver.flush_buffer) - tty->driver.flush_buffer(tty); -+ ld = tty_ldisc_ref(tty); -+ if (ld) { -+ if (ld->flush_buffer) -+ ld->flush_buffer(tty); -+ tty_ldisc_deref(ld); -+ } - if (tty->ldisc.flush_buffer) - tty->ldisc.flush_buffer(tty); - tty->closing = 0; -@@ -1051,9 +1056,7 @@ - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - restore_flags(flags); - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup) (tty); -+ tty_wakeup(tty); - } - - static int mxser_ioctl(struct tty_struct *tty, struct file *file, -diff -Nur linux-2.4.27/drivers/char/n_tty.c linux-2.4.27-plasmaroo/drivers/char/n_tty.c ---- linux-2.4.27/drivers/char/n_tty.c 2003-08-25 12:44:41.000000000 +0100 -+++ linux-2.4.27-plasmaroo/drivers/char/n_tty.c 2004-11-07 14:02:20.219672040 +0000 -@@ -112,11 +112,18 @@ - spin_unlock_irqrestore(&tty->read_lock, flags); - } - --/* -- * Check whether to call the driver.unthrottle function. -- * We test the TTY_THROTTLED bit first so that it always -- * indicates the current state. -+/** -+ * check_unthrottle - allow new receive data -+ * @tty; tty device -+ * -+ * Check whether to call the driver.unthrottle function. -+ * We test the TTY_THROTTLED bit first so that it always -+ * indicates the current state. The decision about whether -+ * it is worth allowing more input has been taken by the caller. -+ * Can sleep, may be called under the atomic_read semaphore but -+ * this is not guaranteed. - */ -+ - static void check_unthrottle(struct tty_struct * tty) - { - if (tty->count && -@@ -125,10 +132,13 @@ - tty->driver.unthrottle(tty); - } - --/* -- * Reset the read buffer counters, clear the flags, -- * and make sure the driver is unthrottled. Called -- * from n_tty_open() and n_tty_flush_buffer(). -+/** -+ * reset_buffer_flags - reset buffer state -+ * @tty: terminal to reset -+ * -+ * Reset the read buffer counters, clear the flags, -+ * and make sure the driver is unthrottled. Called -+ * from n_tty_open() and n_tty_flush_buffer(). - */ - static void reset_buffer_flags(struct tty_struct *tty) - { -@@ -142,9 +152,19 @@ - check_unthrottle(tty); - } - --/* -- * Flush the input buffer -+/** -+ * n_tty_flush_buffer - clean input queue -+ * @tty: terminal device -+ * -+ * Flush the input buffer. Called when the line discipline is -+ * being closed, when the tty layer wants the buffer flushed (eg -+ * at hangup) or when the N_TTY line discipline internally has to -+ * clean the pending queue (for example some signals). -+ * -+ * FIXME: tty->ctrl_status is not spinlocked and relies on -+ * lock_kernel() still. - */ -+ - void n_tty_flush_buffer(struct tty_struct * tty) - { - /* clear everything and unthrottle the driver */ -@@ -159,9 +179,14 @@ - } - } - --/* -- * Return number of characters buffered to be delivered to user -+/** -+ * n_tty_chars_in_buffer - report available bytes -+ * @tty: tty device -+ * -+ * Report the number of characters buffered to be delivered to user -+ * at this instant in time. - */ -+ - ssize_t n_tty_chars_in_buffer(struct tty_struct *tty) - { - unsigned long flags; -@@ -242,10 +267,20 @@ - return 0; - } - --/* -- * opost_block --- to speed up block console writes, among other -- * things. -+/** -+ * opost_block - block postprocess -+ * @tty: terminal device -+ * @inbuf: user buffer -+ * @nr: number of bytes -+ * -+ * This path is used to speed up block console writes, among other -+ * things when processing blocks of output data. It handles only -+ * the simple cases normally found and helps to generate blocks of -+ * symbols for the console driver and thus improve performance. -+ * -+ * Called from write_chan under the tty layer write lock. - */ -+ - static ssize_t opost_block(struct tty_struct * tty, - const unsigned char * inbuf, unsigned int nr) - { -@@ -334,6 +369,16 @@ - } - } - -+/** -+ * eraser - handle erase function -+ * @c: character input -+ * @tty: terminal device -+ * -+ * Perform erase and neccessary output when an erase character is -+ * present in the stream from the driver layer. Handles the complexities -+ * of UTF-8 multibyte symbols. -+ */ -+ - static void eraser(unsigned char c, struct tty_struct *tty) - { - enum { ERASE, WERASE, KILL } kill_type; -@@ -450,6 +495,18 @@ - finish_erasing(tty); - } - -+/** -+ * isig - handle the ISIG optio -+ * @sig: signal -+ * @tty: terminal -+ * @flush: force flush -+ * -+ * Called when a signal is being sent due to terminal input. This -+ * may caus terminal flushing to take place according to the termios -+ * settings and character used. Called from the driver receive_buf -+ * path so serialized. -+ */ -+ - static inline void isig(int sig, struct tty_struct *tty, int flush) - { - if (tty->pgrp > 0) -@@ -461,6 +518,16 @@ - } - } - -+/** -+ * n_tty_receive_break - handle break -+ * @tty: terminal -+ * -+ * An RS232 break event has been hit in the incoming bitstream. This -+ * can cause a variety of events depending upon the termios settings. -+ * -+ * Called from the receive_buf path so single threaded. -+ */ -+ - static inline void n_tty_receive_break(struct tty_struct *tty) - { - if (I_IGNBRK(tty)) -@@ -477,19 +544,40 @@ - wake_up_interruptible(&tty->read_wait); - } - -+/** -+ * n_tty_receive_overrun - handle overrun reporting -+ * @tty: terminal -+ * -+ * Data arrived faster than we could process it. While the tty -+ * driver has flagged this the bits that were missed are gone -+ * forever. -+ * -+ * Called from the receive_buf path so single threaded. Does not -+ * need locking as num_overrun and overrun_time are function -+ * private. -+ */ -+ - static inline void n_tty_receive_overrun(struct tty_struct *tty) - { - char buf[64]; - - tty->num_overrun++; - if (time_before(tty->overrun_time, jiffies - HZ)) { -- printk("%s: %d input overrun(s)\n", tty_name(tty, buf), -+ printk(KERN_WARNING "%s: %d input overrun(s)\n", tty_name(tty, buf), - tty->num_overrun); - tty->overrun_time = jiffies; - tty->num_overrun = 0; - } - } - -+/** -+ * n_tty_receive_parity_error - error notifier -+ * @tty: terminal device -+ * @c: character -+ * -+ * Process a parity error and queue the right data to indicate -+ * the error case if neccessary. Locking as per n_tty_receive_buf. -+ */ - static inline void n_tty_receive_parity_error(struct tty_struct *tty, - unsigned char c) - { -@@ -507,6 +595,16 @@ - wake_up_interruptible(&tty->read_wait); - } - -+/** -+ * n_tty_receive_char - perform processing -+ * @tty: terminal device -+ * @c: character -+ * -+ * Process an individual character of input received from the driver. -+ * This is serialized with respect to itself by the rules for the -+ * driver above. -+ */ -+ - static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) - { - unsigned long flags; -@@ -698,6 +796,16 @@ - put_tty_queue(c, tty); - } - -+/** -+ * n_tty_receive_room - receive space -+ * @tty: terminal -+ * -+ * Called by the driver to find out how much data it is -+ * permitted to feed to the line discipline without any being lost -+ * and thus to manage flow control. Not serialized. Answers for the -+ * "instant". -+ */ -+ - static int n_tty_receive_room(struct tty_struct *tty) - { - int left = N_TTY_BUF_SIZE - tty->read_cnt - 1; -@@ -716,10 +824,13 @@ - return 0; - } - --/* -- * Required for the ptys, serial driver etc. since processes -- * that attach themselves to the master and rely on ASYNC -- * IO must be woken up -+/** -+ * n_tty_write_wakeup - asynchronous I/O notifier -+ * @tty: tty device -+ * -+ * Required for the ptys, serial driver etc. since processes -+ * that attach themselves to the master and rely on ASYNC -+ * IO must be woken up - */ - - static void n_tty_write_wakeup(struct tty_struct *tty) -@@ -732,6 +843,19 @@ - return; - } - -+/** -+ * n_tty_receive_buf - data receive -+ * @tty: terminal device -+ * @cp: buffer -+ * @fp: flag buffer -+ * @count: characters -+ * -+ * Called by the terminal driver when a block of characters has -+ * been received. This function must be called from soft contexts -+ * not from interrupt context. The driver is responsible for making -+ * calls one at a time and in order (or using queue_ldisc) -+ */ -+ - static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) - { -@@ -813,6 +937,18 @@ - current->sig->action[sig-1].sa.sa_handler == SIG_IGN); - } - -+/** -+ * n_tty_set_termios - termios data changed -+ * @tty: terminal -+ * @old: previous data -+ * -+ * Called by the tty layer when the user changes termios flags so -+ * that the line discipline can plan ahead. This function cannot sleep -+ * and is protected from re-entry by the tty layer. The user is -+ * guaranteed that this function will not be re-entered or in progress -+ * when the ldisc is closed. -+ */ -+ - static void n_tty_set_termios(struct tty_struct *tty, struct termios * old) - { - if (!tty) -@@ -828,7 +964,6 @@ - I_ICRNL(tty) || I_INLCR(tty) || L_ICANON(tty) || - I_IXON(tty) || L_ISIG(tty) || L_ECHO(tty) || - I_PARMRK(tty)) { -- cli(); - memset(tty->process_char_map, 0, 256/8); - - if (I_IGNCR(tty) || I_ICRNL(tty)) -@@ -864,7 +999,6 @@ - set_bit(SUSP_CHAR(tty), &tty->process_char_map); - } - clear_bit(__DISABLED_CHAR, &tty->process_char_map); -- sti(); - tty->raw = 0; - tty->real_raw = 0; - } else { -@@ -878,6 +1012,16 @@ - } - } - -+/** -+ * n_tty_close - close the ldisc for this tty -+ * @tty: device -+ * -+ * Called from the terminal layer when this line discipline is -+ * being shut down, either because of a close or becsuse of a -+ * discipline change. The function will not be called while other -+ * ldisc methods are in progress. -+ */ -+ - static void n_tty_close(struct tty_struct *tty) - { - n_tty_flush_buffer(tty); -@@ -887,11 +1031,22 @@ - } - } - -+/** -+ * n_tty_open - open an ldisc -+ * @tty: terminal to open -+ * -+ * Called when this line discipline is being attached to the -+ * terminal device. Can sleep. Called serialized so that no -+ * other events will occur in parallel. No further open will occur -+ * until a close. -+ */ -+ - static int n_tty_open(struct tty_struct *tty) - { - if (!tty) - return -EINVAL; - -+ /* This one is ugly. Currently a malloc failure here can panic */ - if (!tty->read_buf) { - tty->read_buf = alloc_buf(); - if (!tty->read_buf) -@@ -917,14 +1072,23 @@ - return 0; - } - --/* -- * Helper function to speed up read_chan. It is only called when -- * ICANON is off; it copies characters straight from the tty queue to -- * user space directly. It can be profitably called twice; once to -- * drain the space from the tail pointer to the (physical) end of the -- * buffer, and once to drain the space from the (physical) beginning of -- * the buffer to head pointer. -+/** -+ * copy_from_read_buf - copy read data directly -+ * @tty: terminal device -+ * @b: user data -+ * @nr: size of data -+ * -+ * Helper function to speed up read_chan. It is only called when -+ * ICANON is off; it copies characters straight from the tty queue to -+ * user space directly. It can be profitably called twice; once to -+ * drain the space from the tail pointer to the (physical) end of the -+ * buffer, and once to drain the space from the (physical) beginning of -+ * the buffer to head pointer. -+ * -+ * Called under the tty->atomic_read sem and with TTY_DONT_FLIP set -+ * - */ -+ - static inline int copy_from_read_buf(struct tty_struct *tty, - unsigned char **b, - size_t *nr) -@@ -952,25 +1116,18 @@ - return retval; - } - --static ssize_t read_chan(struct tty_struct *tty, struct file *file, -- unsigned char *buf, size_t nr) --{ -- unsigned char *b = buf; -- DECLARE_WAITQUEUE(wait, current); -- int c; -- int minimum, time; -- ssize_t retval = 0; -- ssize_t size; -- long timeout; -- unsigned long flags; -- --do_it_again: -- -- if (!tty->read_buf) { -- printk("n_tty_read_chan: called with read_buf == NULL?!?\n"); -- return -EIO; -- } -+/** -+ * job_control - check job control -+ * @tty: tty -+ * @file: file handle -+ * -+ * Perform job control management checks on this file/tty descriptor -+ * and if appropriate send any needed signals and return a negative -+ * error code if action should be taken. -+ */ - -+static int job_control(struct tty_struct *tty, struct file *file) -+{ - /* Job control check -- must be done at start and after - every sleep (POSIX.1 7.1.1.4). */ - /* NOTE: not yet done after every sleep pending a thorough -@@ -989,7 +1146,48 @@ - return -ERESTARTSYS; - } - } -+ return 0; -+} -+ - -+/** -+ * read_chan - read function for tty -+ * @tty: tty device -+ * @file: file object -+ * @buf: userspace buffer pointer -+ * @nr: size of I/O -+ * -+ * Perform reads for the line discipline. We are guaranteed that the -+ * line discipline will not be closed under us but we may get multiple -+ * parallel readers and must handle this ourselves. We may also get -+ * a hangup. Always called in user context, may sleep. -+ * -+ * This code must be sure never to sleep through a hangup. -+ */ -+ -+static ssize_t read_chan(struct tty_struct *tty, struct file *file, -+ unsigned char __user *buf, size_t nr) -+{ -+ unsigned char __user *b = buf; -+ DECLARE_WAITQUEUE(wait, current); -+ int c; -+ int minimum, time; -+ ssize_t retval = 0; -+ ssize_t size; -+ long timeout; -+ unsigned long flags; -+ -+do_it_again: -+ -+ if (!tty->read_buf) { -+ printk("n_tty_read_chan: called with read_buf == NULL?!?\n"); -+ return -EIO; -+ } -+ -+ c = job_control(tty, file); -+ if(c < 0) -+ return c; -+ - minimum = time = 0; - timeout = MAX_SCHEDULE_TIMEOUT; - if (!tty->icanon) { -@@ -1011,6 +1209,9 @@ - } - } - -+ /* -+ * Internal serialization of reads. -+ */ - if (file->f_flags & O_NONBLOCK) { - if (down_trylock(&tty->atomic_read)) - return -EAGAIN; -@@ -1146,6 +1347,21 @@ - return retval; - } - -+/** -+ * write_chan - write function for tty -+ * @tty: tty device -+ * @file: file object -+ * @buf: userspace buffer pointer -+ * @nr: size of I/O -+ * -+ * Write function of the terminal device. This is serialized with -+ * respect to other write callers but not to termios changes, reads -+ * and other such events. We must be careful with N_TTY as the receive -+ * code will echo characters, thus calling driver write methods. -+ * -+ * This code must be sure never to sleep through a hangup. -+ */ -+ - static ssize_t write_chan(struct tty_struct * tty, struct file * file, - const unsigned char * buf, size_t nr) - { -@@ -1217,7 +1433,25 @@ - return (b - buf) ? b - buf : retval; - } - --/* Called without the kernel lock held - fine */ -+/** -+ * normal_poll - poll method for N_TTY -+ * @tty: terminal device -+ * @file: file accessing it -+ * @wait: poll table -+ * -+ * Called when the line discipline is asked to poll() for data or -+ * for special events. This code is not serialized with respect to -+ * other events save open/close. -+ * -+ * This code must be sure never to sleep through a hangup. -+ * Called without the kernel lock held - fine -+ * -+ * FIXME: if someone changes the VMIN or discipline settings for the -+ * terminal while another process is in poll() the poll does not -+ * recompute the new limits. Possibly set_termios should issue -+ * a read wakeup to fix this bug. -+ */ -+ - static unsigned int normal_poll(struct tty_struct * tty, struct file * file, poll_table *wait) - { - unsigned int mask = 0; -diff -Nur linux-2.4.27/drivers/char/pcmcia/synclink_cs.c linux-2.4.27-plasmaroo/drivers/char/pcmcia/synclink_cs.c ---- linux-2.4.27/drivers/char/pcmcia/synclink_cs.c 2003-11-28 18:26:20.000000000 +0000 -+++ linux-2.4.27-plasmaroo/drivers/char/pcmcia/synclink_cs.c 2004-11-07 14:02:20.108688912 +0000 -@@ -553,6 +553,40 @@ - static void* mgslpc_get_text_ptr(void); - static void* mgslpc_get_text_ptr() {return mgslpc_get_text_ptr;} - -+/** -+ * line discipline callback wrappers -+ * -+ * The wrappers maintain line discipline references -+ * while calling into the line discipline. -+ * -+ * ldisc_flush_buffer - flush line discipline receive buffers -+ * ldisc_receive_buf - pass receive data to line discipline -+ */ -+ -+static void ldisc_flush_buffer(struct tty_struct *tty) -+{ -+ struct tty_ldisc *ld = tty_ldisc_ref(tty); -+ if (ld) { -+ if (ld->flush_buffer) -+ ld->flush_buffer(tty); -+ tty_ldisc_deref(ld); -+ } -+} -+ -+static void ldisc_receive_buf(struct tty_struct *tty, -+ const __u8 *data, char *flags, int count) -+{ -+ struct tty_ldisc *ld; -+ if (!tty) -+ return; -+ ld = tty_ldisc_ref(tty); -+ if (ld) { -+ if (ld->receive_buf) -+ ld->receive_buf(tty, data, flags, count); -+ tty_ldisc_deref(ld); -+ } -+} -+ - static dev_link_t *mgslpc_attach(void) - { - MGSLPC_INFO *info; -@@ -1027,13 +1061,7 @@ - printk("bh_transmit() entry on %s\n", info->device_name); - - if (tty) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) { -- if ( debug_level >= DEBUG_LEVEL_BH ) -- printk( "%s(%d):calling ldisc.write_wakeup on %s\n", -- __FILE__,__LINE__,info->device_name); -- (tty->ldisc.write_wakeup)(tty); -- } -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - } -@@ -1917,11 +1945,9 @@ - info->tx_count = info->tx_put = info->tx_get = 0; - del_timer(&info->tx_timer); - spin_unlock_irqrestore(&info->lock,flags); -- -+ - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - /* Send a high-priority XON/XOFF character -@@ -2685,9 +2711,8 @@ - - if (tty->driver.flush_buffer) - tty->driver.flush_buffer(tty); -- -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ -+ ldisc_flush_buffer(tty); - - shutdown(info); - -@@ -4199,11 +4224,7 @@ - } - else - #endif -- { -- /* Call the line discipline receive callback directly. */ -- if (tty && tty->ldisc.receive_buf) -- tty->ldisc.receive_buf(tty, buf->data, info->flag_buf, framesize); -- } -+ ldisc_receive_buf(tty, buf->data, info->flag_buf, framesize); - } - } - -diff -Nur linux-2.4.27/drivers/char/pcxx.c linux-2.4.27-plasmaroo/drivers/char/pcxx.c ---- linux-2.4.27/drivers/char/pcxx.c 2002-11-28 23:53:12.000000000 +0000 -+++ linux-2.4.27-plasmaroo/drivers/char/pcxx.c 2004-11-07 14:02:20.296660336 +0000 -@@ -632,10 +632,10 @@ - ** please send me a note. brian@ilinx.com - ** Don't know either what this is supposed to do christoph@lameter.com. - */ -- if(tty->ldisc.num != ldiscs[N_TTY].num) { -+ if(tty->ldisc.num != N_TTY) { - if(tty->ldisc.close) - (tty->ldisc.close)(tty); -- tty->ldisc = ldiscs[N_TTY]; -+ tty->ldisc = *(tty_ldisc_get(N_TTY)); - tty->termios->c_line = N_TTY; - if(tty->ldisc.open) - (tty->ldisc.open)(tty); -diff -Nur linux-2.4.27/drivers/char/pty.c linux-2.4.27-plasmaroo/drivers/char/pty.c ---- linux-2.4.27/drivers/char/pty.c 2002-08-03 01:39:43.000000000 +0100 -+++ linux-2.4.27-plasmaroo/drivers/char/pty.c 2004-11-07 14:02:20.220671888 +0000 -@@ -137,6 +137,10 @@ - * (2) avoid redundant copying for cases where count >> receive_room - * N.B. Calls from user space may now return an error code instead of - * a count. -+ * -+ * FIXME: Our pty_write method is called with our ldisc lock held but -+ * not our partners. We can't just take the other one blindly without -+ * risking deadlocks. There is also the small matter of TTY_DONT_FLIP - */ - static int pty_write(struct tty_struct * tty, int from_user, - const unsigned char *buf, int count) -diff -Nur linux-2.4.27/drivers/char/riscom8.c linux-2.4.27-plasmaroo/drivers/char/riscom8.c ---- linux-2.4.27/drivers/char/riscom8.c 2001-09-13 23:21:32.000000000 +0100 -+++ linux-2.4.27-plasmaroo/drivers/char/riscom8.c 2004-11-07 14:02:20.231670216 +0000 -@@ -1133,6 +1133,7 @@ - struct riscom_board *bp; - unsigned long flags; - unsigned long timeout; -+ struct tty_ldisc *ld; - - if (!port || rc_paranoia_check(port, tty->device, "close")) - return; -@@ -1200,6 +1201,12 @@ - rc_shutdown_port(bp, port); - if (tty->driver.flush_buffer) - tty->driver.flush_buffer(tty); -+ ld = tty_ldisc_ref(tty); -+ if (ld != NULL) { -+ if(ld->flush_buffer) -+ ld->flush_buffer(tty); -+ tty_ldisc_deref(ld); -+ } - if (tty->ldisc.flush_buffer) - tty->ldisc.flush_buffer(tty); - tty->closing = 0; -@@ -1375,9 +1382,7 @@ - restore_flags(flags); - - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - static int rc_get_modem_info(struct riscom_port * port, unsigned int *value) -@@ -1734,9 +1739,7 @@ - return; - - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - } -diff -Nur linux-2.4.27/drivers/char/selection.c linux-2.4.27-plasmaroo/drivers/char/selection.c ---- linux-2.4.27/drivers/char/selection.c 2001-09-07 17:28:38.000000000 +0100 -+++ linux-2.4.27-plasmaroo/drivers/char/selection.c 2004-11-07 14:02:20.236669456 +0000 -@@ -290,9 +290,11 @@ - { - struct vt_struct *vt = (struct vt_struct *) tty->driver_data; - int pasted = 0, count; -+ struct tty_ldisc *ld; - DECLARE_WAITQUEUE(wait, current); - - poke_blanked_console(); -+ ld = tty_ldisc_ref_wait(tty); - add_wait_queue(&vt->paste_wait, &wait); - while (sel_buffer && sel_buffer_lth > pasted) { - set_current_state(TASK_INTERRUPTIBLE); -@@ -307,6 +309,8 @@ - } - remove_wait_queue(&vt->paste_wait, &wait); - current->state = TASK_RUNNING; -+ -+ tty_ldisc_deref(ld); - return 0; - } - -diff -Nur linux-2.4.27/drivers/char/serial167.c linux-2.4.27-plasmaroo/drivers/char/serial167.c ---- linux-2.4.27/drivers/char/serial167.c 2002-11-28 23:53:12.000000000 +0000 -+++ linux-2.4.27-plasmaroo/drivers/char/serial167.c 2004-11-07 14:02:20.300659728 +0000 -@@ -1920,10 +1920,10 @@ - tty->ldisc.flush_buffer(tty); - info->event = 0; - info->tty = 0; -- if (tty->ldisc.num != ldiscs[N_TTY].num) { -+ if (tty->ldisc.num != N_TTY) { - if (tty->ldisc.close) - (tty->ldisc.close)(tty); -- tty->ldisc = ldiscs[N_TTY]; -+ tty->ldisc = *(tty_ldisc_get(N_TTY)); - tty->termios->c_line = N_TTY; - if (tty->ldisc.open) - (tty->ldisc.open)(tty); -diff -Nur linux-2.4.27/drivers/char/sgiserial.c linux-2.4.27-plasmaroo/drivers/char/sgiserial.c ---- linux-2.4.27/drivers/char/sgiserial.c 2004-02-18 13:36:31.000000000 +0000 -+++ linux-2.4.27-plasmaroo/drivers/char/sgiserial.c 2004-11-07 14:02:20.303659272 +0000 -@@ -1498,10 +1498,10 @@ - tty->closing = 0; - info->event = 0; - info->tty = 0; -- if (tty->ldisc.num != ldiscs[N_TTY].num) { -+ if (tty->ldisc.num != N_TTY) { - if (tty->ldisc.close) - (tty->ldisc.close)(tty); -- tty->ldisc = ldiscs[N_TTY]; -+ tty->ldisc = *(tty_ldisc_get(N_TTY)); - tty->termios->c_line = N_TTY; - if (tty->ldisc.open) - (tty->ldisc.open)(tty); -diff -Nur linux-2.4.27/drivers/char/synclink.c linux-2.4.27-plasmaroo/drivers/char/synclink.c ---- linux-2.4.27/drivers/char/synclink.c 2003-11-28 18:26:20.000000000 +0000 -+++ linux-2.4.27-plasmaroo/drivers/char/synclink.c 2004-11-07 14:02:20.270664288 +0000 -@@ -1011,6 +1011,40 @@ - return 0; - } - -+/** -+ * line discipline callback wrappers -+ * -+ * The wrappers maintain line discipline references -+ * while calling into the line discipline. -+ * -+ * ldisc_flush_buffer - flush line discipline receive buffers -+ * ldisc_receive_buf - pass receive data to line discipline -+ */ -+ -+static void ldisc_flush_buffer(struct tty_struct *tty) -+{ -+ struct tty_ldisc *ld = tty_ldisc_ref(tty); -+ if (ld) { -+ if (ld->flush_buffer) -+ ld->flush_buffer(tty); -+ tty_ldisc_deref(ld); -+ } -+} -+ -+static void ldisc_receive_buf(struct tty_struct *tty, -+ const __u8 *data, char *flags, int count) -+{ -+ struct tty_ldisc *ld; -+ if (!tty) -+ return; -+ ld = tty_ldisc_ref(tty); -+ if (ld) { -+ if (ld->receive_buf) -+ ld->receive_buf(tty, data, flags, count); -+ tty_ldisc_deref(ld); -+ } -+} -+ - /* mgsl_stop() throttle (stop) transmitter - * - * Arguments: tty pointer to tty info structure -@@ -1170,13 +1204,7 @@ - __FILE__,__LINE__,info->device_name); - - if (tty) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) { -- if ( debug_level >= DEBUG_LEVEL_BH ) -- printk( "%s(%d):calling ldisc.write_wakeup on %s\n", -- __FILE__,__LINE__,info->device_name); -- (tty->ldisc.write_wakeup)(tty); -- } -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - -@@ -2434,11 +2462,8 @@ - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- --} /* end of mgsl_flush_buffer() */ -+ tty_wakeup(tty); -+} - - /* mgsl_send_xchar() - * -@@ -3342,9 +3367,8 @@ - - if (tty->driver.flush_buffer) - tty->driver.flush_buffer(tty); -- -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ -+ ldisc_flush_buffer(tty); - - shutdown(info); - -@@ -7007,11 +7031,7 @@ - } - else - #endif -- { -- /* Call the line discipline receive callback directly. */ -- if ( tty && tty->ldisc.receive_buf ) -- tty->ldisc.receive_buf(tty, info->intermediate_rxbuffer, info->flag_buf, framesize); -- } -+ ldisc_receive_buf(tty, info->intermediate_rxbuffer, info->flag_buf, framesize); - } - } - /* Free the buffers used by this frame. */ -@@ -7183,9 +7203,7 @@ - memcpy( info->intermediate_rxbuffer, pBufEntry->virt_addr, framesize); - info->icount.rxok++; - -- /* Call the line discipline receive callback directly. */ -- if ( tty && tty->ldisc.receive_buf ) -- tty->ldisc.receive_buf(tty, info->intermediate_rxbuffer, info->flag_buf, framesize); -+ ldisc_receive_buf(tty, info->intermediate_rxbuffer, info->flag_buf, framesize); - } - - /* Free the buffers used by this frame. */ -diff -Nur linux-2.4.27/drivers/char/synclinkmp.c linux-2.4.27-plasmaroo/drivers/char/synclinkmp.c ---- linux-2.4.27/drivers/char/synclinkmp.c 2003-11-28 18:26:20.000000000 +0000 -+++ linux-2.4.27-plasmaroo/drivers/char/synclinkmp.c 2004-11-07 14:02:20.281662616 +0000 -@@ -735,6 +735,40 @@ - return 0; - } - -+/** -+ * line discipline callback wrappers -+ * -+ * The wrappers maintain line discipline references -+ * while calling into the line discipline. -+ * -+ * ldisc_flush_buffer - flush line discipline receive buffers -+ * ldisc_receive_buf - pass receive data to line discipline -+ */ -+ -+static void ldisc_flush_buffer(struct tty_struct *tty) -+{ -+ struct tty_ldisc *ld = tty_ldisc_ref(tty); -+ if (ld) { -+ if (ld->flush_buffer) -+ ld->flush_buffer(tty); -+ tty_ldisc_deref(ld); -+ } -+} -+ -+static void ldisc_receive_buf(struct tty_struct *tty, -+ const __u8 *data, char *flags, int count) -+{ -+ struct tty_ldisc *ld; -+ if (!tty) -+ return; -+ ld = tty_ldisc_ref(tty); -+ if (ld) { -+ if (ld->receive_buf) -+ ld->receive_buf(tty, data, flags, count); -+ tty_ldisc_deref(ld); -+ } -+} -+ - /* tty callbacks */ - - /* Called when a port is opened. Init and enable port. -@@ -906,8 +940,7 @@ - if (tty->driver.flush_buffer) - tty->driver.flush_buffer(tty); - -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ ldisc_flush_buffer(tty); - - shutdown(info); - -@@ -1315,9 +1348,7 @@ - spin_unlock_irqrestore(&info->lock,flags); - - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - /* throttle (stop) transmitter -@@ -1983,13 +2014,7 @@ - __FILE__,__LINE__,info->device_name); - - if (tty) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) { -- if ( debug_level >= DEBUG_LEVEL_BH ) -- printk( "%s(%d):%s calling ldisc.write_wakeup\n", -- __FILE__,__LINE__,info->device_name); -- (tty->ldisc.write_wakeup)(tty); -- } -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - } -@@ -4986,15 +5011,8 @@ - } - else - #endif -- { -- if ( tty && tty->ldisc.receive_buf ) { -- /* Call the line discipline receive callback directly. */ -- tty->ldisc.receive_buf(tty, -- info->tmp_rx_buf, -- info->flag_buf, -- framesize); -- } -- } -+ ldisc_receive_buf(tty,info->tmp_rx_buf, -+ info->flag_buf, framesize); - } - } - /* Free the buffers used by this frame. */ -diff -Nur linux-2.4.27/drivers/char/tty_io.c linux-2.4.27-plasmaroo/drivers/char/tty_io.c ---- linux-2.4.27/drivers/char/tty_io.c 2004-04-14 14:05:29.000000000 +0100 -+++ linux-2.4.27-plasmaroo/drivers/char/tty_io.c 2004-11-07 14:02:20.113688152 +0000 -@@ -118,9 +118,10 @@ - #define TTY_PARANOIA_CHECK 1 - #define CHECK_TTY_COUNT 1 - -+/* Lock for tty_termios changes - private to tty_io/tty_ioctl */ -+spinlock_t tty_termios_lock = SPIN_LOCK_UNLOCKED; - struct termios tty_std_termios; /* for the benefit of tty drivers */ - struct tty_driver *tty_drivers; /* linked list of tty drivers */ --struct tty_ldisc ldiscs[NR_LDISCS]; /* line disc dispatch table */ - - #ifdef CONFIG_UNIX98_PTYS - extern struct tty_driver ptm_driver[]; /* Unix98 pty masters; for /dev/ptmx */ -@@ -260,46 +261,264 @@ - return 0; - } - -+/* -+ * This is probably overkill for real world processors but -+ * they are not on hot paths so a little discipline won't do -+ * any harm. -+ */ -+ -+static void tty_set_termios_ldisc(struct tty_struct *tty, int num) -+{ -+ unsigned long flags; -+ spin_lock_irqsave(&tty_termios_lock, flags); -+ tty->termios->c_line = num; -+ spin_unlock_irqrestore(&tty_termios_lock, flags); -+} -+ -+/* -+ * This guards the refcounted line discipline lists. The lock -+ * must be taken with irqs off because there are hangup path -+ * callers who will do ldisc lookups and cannot sleep. -+ */ -+ -+spinlock_t tty_ldisc_lock = SPIN_LOCK_UNLOCKED; -+DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); -+struct tty_ldisc tty_ldiscs[NR_LDISCS]; /* line disc dispatch table */ -+ - int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc) - { -+ -+ unsigned long flags; -+ int ret = 0; -+ - if (disc < N_TTY || disc >= NR_LDISCS) - return -EINVAL; -- -+ -+ spin_lock_irqsave(&tty_ldisc_lock, flags); - if (new_ldisc) { -- ldiscs[disc] = *new_ldisc; -- ldiscs[disc].flags |= LDISC_FLAG_DEFINED; -- ldiscs[disc].num = disc; -- } else -- memset(&ldiscs[disc], 0, sizeof(struct tty_ldisc)); -+ tty_ldiscs[disc] = *new_ldisc; -+ tty_ldiscs[disc].num = disc; -+ tty_ldiscs[disc].flags |= LDISC_FLAG_DEFINED; -+ tty_ldiscs[disc].refcount = 0; -+ } else { -+ if(tty_ldiscs[disc].refcount) -+ ret = -EBUSY; -+ else -+ tty_ldiscs[disc].flags &= ~LDISC_FLAG_DEFINED; -+ } -+ spin_unlock_irqrestore(&tty_ldisc_lock, flags); - -- return 0; -+ return ret; -+ - } - -+ - EXPORT_SYMBOL(tty_register_ldisc); - --/* Set the discipline of a tty line. */ -+struct tty_ldisc *tty_ldisc_get(int disc) -+{ -+ unsigned long flags; -+ struct tty_ldisc *ld; -+ -+ if (disc < N_TTY || disc >= NR_LDISCS) -+ return NULL; -+ -+ spin_lock_irqsave(&tty_ldisc_lock, flags); -+ -+ ld = &tty_ldiscs[disc]; -+ /* Check the entry is defined */ -+ if(ld->flags & LDISC_FLAG_DEFINED) -+ ld->refcount++; -+ else -+ ld = NULL; -+ spin_unlock_irqrestore(&tty_ldisc_lock, flags); -+ return ld; -+} -+ -+EXPORT_SYMBOL_GPL(tty_ldisc_get); -+ -+void tty_ldisc_put(int disc) -+{ -+ struct tty_ldisc *ld; -+ unsigned long flags; -+ -+ if (disc < N_TTY || disc >= NR_LDISCS) -+ BUG(); -+ -+ spin_lock_irqsave(&tty_ldisc_lock, flags); -+ ld = &tty_ldiscs[disc]; -+ if(ld->refcount <= 0) -+ BUG(); -+ ld->refcount--; -+ spin_unlock_irqrestore(&tty_ldisc_lock, flags); -+} -+ -+EXPORT_SYMBOL_GPL(tty_ldisc_put); -+ -+void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld) -+{ -+ tty->ldisc = *ld; -+ tty->ldisc.refcount = 0; -+} -+ -+/** -+ * tty_ldisc_try - internal helper -+ * @tty: the tty -+ * -+ * Make a single attempt to grab and bump the refcount on -+ * the tty ldisc. Return 0 on failure or 1 on success. This is -+ * used to implement both the waiting and non waiting versions -+ * of tty_ldisc_ref -+ */ -+ -+static int tty_ldisc_try(struct tty_struct *tty) -+{ -+ unsigned long flags; -+ struct tty_ldisc *ld; -+ int ret = 0; -+ -+ spin_lock_irqsave(&tty_ldisc_lock, flags); -+ ld = &tty->ldisc; -+ if(test_bit(TTY_LDISC, &tty->flags)) -+ { -+ ld->refcount++; -+ ret = 1; -+ } -+ spin_unlock_irqrestore(&tty_ldisc_lock, flags); -+ return ret; -+} -+ -+/** -+ * tty_ldisc_ref_wait - wait for the tty ldisc -+ * @tty: tty device -+ * -+ * Dereference the line discipline for the terminal and take a -+ * reference to it. If the line discipline is in flux then -+ * wait patiently until it changes. -+ * -+ * Note: Must not be called from an IRQ/timer context. The caller -+ * must also be careful not to hold other locks that will deadlock -+ * against a discipline change, such as an existing ldisc reference -+ * (which we check for) -+ */ -+ -+struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty) -+{ -+ /* wait_event is a macro */ -+ wait_event(tty_ldisc_wait, tty_ldisc_try(tty)); -+ return &tty->ldisc; -+} -+ -+EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait); -+ -+/** -+ * tty_ldisc_ref - get the tty ldisc -+ * @tty: tty device -+ * -+ * Dereference the line discipline for the terminal and take a -+ * reference to it. If the line discipline is in flux then -+ * return NULL. Can be called from IRQ and timer functions. -+ */ -+ -+struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty) -+{ -+ if(tty_ldisc_try(tty)) -+ return &tty->ldisc; -+ return NULL; -+} -+ -+EXPORT_SYMBOL_GPL(tty_ldisc_ref); -+ -+ -+void tty_ldisc_deref(struct tty_ldisc *ld) -+{ -+ -+ unsigned long flags; -+ -+ if(ld == NULL) -+ BUG(); -+ -+ spin_lock_irqsave(&tty_ldisc_lock, flags); -+ if(ld->refcount == 0) -+ printk(KERN_EMERG "tty_ldisc_deref: no references.\n"); -+ else -+ ld->refcount--; -+ if(ld->refcount == 0) -+ wake_up(&tty_ldisc_wait); -+ spin_unlock_irqrestore(&tty_ldisc_lock, flags); -+} -+ -+EXPORT_SYMBOL_GPL(tty_ldisc_deref); -+ -+/** -+ * tty_set_ldisc - set line discipline -+ * @tty: the terminal to set -+ * @ldisc: the line discipline -+ * -+ * Set the discipline of a tty line. Must be called from a process -+ * context. -+ */ -+ - static int tty_set_ldisc(struct tty_struct *tty, int ldisc) - { - int retval = 0; - struct tty_ldisc o_ldisc; - char buf[64]; -+ int work; -+ unsigned long flags; -+ struct tty_ldisc *ld; - - if ((ldisc < N_TTY) || (ldisc >= NR_LDISCS)) - return -EINVAL; -+ -+restart: -+ -+ if (tty->ldisc.num == ldisc) -+ return 0; /* We are already in the desired discipline */ -+ -+ ld = tty_ldisc_get(ldisc); - /* Eduardo Blanco <ejbs@cs.cs.com.uy> */ - /* Cyrus Durgin <cider@speakeasy.org> */ -- if (!(ldiscs[ldisc].flags & LDISC_FLAG_DEFINED)) { -+ if (ld == NULL) -+ { - char modname [20]; -- sprintf(modname, "tty-ldisc-%d", ldisc); -- request_module (modname); -+ sprintf(modname, "tty-ldisc-%d", ldisc); -+ request_module (modname); -+ ld = tty_ldisc_get(ldisc); - } -- if (!(ldiscs[ldisc].flags & LDISC_FLAG_DEFINED)) -+ -+ if (ld == NULL) - return -EINVAL; - -- if (tty->ldisc.num == ldisc) -- return 0; /* We are already in the desired discipline */ -- o_ldisc = tty->ldisc; -+ /* -+ * Make sure we don't change while someone holds a -+ * reference to the line discipline. The TTY_LDISC bit -+ * prevents anyone taking a reference once it is clear. -+ * We need the lock to avoid racing reference takers. -+ */ -+ -+ spin_lock_irqsave(&tty_ldisc_lock, flags); -+ if(tty->ldisc.refcount) -+ { -+ /* Free the new ldisc we grabbed. Must drop the lock -+ first. */ -+ spin_unlock_irqrestore(&tty_ldisc_lock, flags); -+ tty_ldisc_put(ldisc); -+ if(wait_event_interruptible(tty_ldisc_wait, tty->ldisc.refcount == 0) < 0) -+ return -ERESTARTSYS; -+ goto restart; -+ } -+ clear_bit(TTY_LDISC, &tty->flags); -+ clear_bit(TTY_DONT_FLIP, &tty->flags); -+ spin_unlock_irqrestore(&tty_ldisc_lock, flags); - -+ /* -+ * From this point on we know nobody has an ldisc -+ * usage reference, nor can they obtain one until -+ * we say so later on. -+ */ -+ -+ o_ldisc = tty->ldisc; - tty_wait_until_sent(tty, 0); - - /* Shutdown the current discipline. */ -@@ -307,16 +526,20 @@ - (tty->ldisc.close)(tty); - - /* Now set up the new line discipline. */ -- tty->ldisc = ldiscs[ldisc]; -- tty->termios->c_line = ldisc; -+ tty_ldisc_assign(tty, ld); -+ tty_set_termios_ldisc(tty, ldisc); - if (tty->ldisc.open) - retval = (tty->ldisc.open)(tty); - if (retval < 0) { -- tty->ldisc = o_ldisc; -- tty->termios->c_line = tty->ldisc.num; -+ tty_ldisc_put(ldisc); -+ /* There is an outstanding reference here so this is safe */ -+ tty_ldisc_assign(tty, tty_ldisc_get(o_ldisc.num)); -+ tty_set_termios_ldisc(tty, tty->ldisc.num); - if (tty->ldisc.open && (tty->ldisc.open(tty) < 0)) { -- tty->ldisc = ldiscs[N_TTY]; -- tty->termios->c_line = N_TTY; -+ tty_ldisc_put(o_ldisc.num); -+ /* This driver is always present */ -+ tty_ldisc_assign(tty, tty_ldisc_get(N_TTY)); -+ tty_set_termios_ldisc(tty, N_TTY); - if (tty->ldisc.open) { - int r = tty->ldisc.open(tty); - -@@ -327,8 +550,23 @@ - } - } - } -+ /* At this point we hold a reference to the new ldisc and a -+ reference to the old ldisc. If we ended up flipping back -+ to the existing ldisc we have two references to it */ -+ - if (tty->ldisc.num != o_ldisc.num && tty->driver.set_ldisc) - tty->driver.set_ldisc(tty); -+ -+ tty_ldisc_put(o_ldisc.num); -+ -+ /* -+ * Allow ldisc referencing to occur as soon as the driver -+ * ldisc callback completes. -+ */ -+ -+ set_bit(TTY_LDISC, &tty->flags); -+ wake_up(&tty_ldisc_wait); -+ - return retval; - } - -@@ -430,6 +668,27 @@ - - static spinlock_t redirect_lock = SPIN_LOCK_UNLOCKED; - static struct file *redirect; -+ -+/* -+ * Internal and external helper for wakeups of tty -+ */ -+ -+void tty_wakeup(struct tty_struct *tty) -+{ -+ struct tty_ldisc *ld; -+ -+ if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) { -+ ld = tty_ldisc_ref(tty); -+ if(ld) { -+ if(ld->write_wakeup) -+ ld->write_wakeup(tty); -+ tty_ldisc_deref(ld); -+ } -+ } -+} -+ -+EXPORT_SYMBOL_GPL(tty_wakeup); -+ - /* - * This can be called by the "eventd" kernel thread. That is process synchronous, - * but doesn't hold any locks, so we need to make sure we have the appropriate -@@ -442,6 +701,7 @@ - struct file *f = NULL; - struct task_struct *p; - struct list_head *l; -+ struct tty_ldisc *ld; - int closecount = 0, n; - - if (!tty) -@@ -475,18 +735,17 @@ - file_list_unlock(); - - /* FIXME! What are the locking issues here? This may me overdoing things.. */ -+ ld = tty_ldisc_ref(tty); -+ if(ld != NULL) - { -- unsigned long flags; -- -- save_flags(flags); cli(); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ if (ld->flush_buffer) -+ ld->flush_buffer(tty); - if (tty->driver.flush_buffer) - tty->driver.flush_buffer(tty); -- if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- restore_flags(flags); -+ if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) && ld->write_wakeup) -+ ld->write_wakeup(tty); -+ //if (ld->hangup) -+ // ld->hangup(tty); - } - - wake_up_interruptible(&tty->write_wait); -@@ -496,21 +755,18 @@ - * Shutdown the current line discipline, and reset it to - * N_TTY. - */ -+ - if (tty->driver.flags & TTY_DRIVER_RESET_TERMIOS) -- *tty->termios = tty->driver.init_termios; -- if (tty->ldisc.num != ldiscs[N_TTY].num) { -- if (tty->ldisc.close) -- (tty->ldisc.close)(tty); -- tty->ldisc = ldiscs[N_TTY]; -- tty->termios->c_line = N_TTY; -- if (tty->ldisc.open) { -- int i = (tty->ldisc.open)(tty); -- if (i < 0) -- printk(KERN_ERR "do_tty_hangup: N_TTY open: " -- "error %d\n", -i); -- } -+ { -+ unsigned long flags; -+ spin_lock_irqsave(&tty_termios_lock, flags); -+ *tty->termios = tty->driver.init_termios; -+ spin_unlock_irqrestore(&tty_termios_lock, flags); - } -- -+ -+ /* Defer ldisc switch */ -+ /* tty_deferred_ldisc_switch(N_TTY); -+ - read_lock(&tasklist_lock); - for_each_task(p) { - if ((tty->session > 0) && (p->session == tty->session) && -@@ -541,6 +797,15 @@ - tty->driver.close(tty, cons_filp); - } else if (tty->driver.hangup) - (tty->driver.hangup)(tty); -+ -+ /* We don't want to have driver/ldisc interactions beyond -+ the ones we did here. The driver layer expects no -+ calls after ->hangup() from the ldisc side. However we -+ can't yet guarantee all that */ -+ -+ set_bit(TTY_HUPPED, &tty->flags); -+ if(ld) -+ tty_ldisc_deref(ld); - unlock_kernel(); - if (f) - fput(f); -@@ -644,9 +909,8 @@ - } - if (tty->driver.start) - (tty->driver.start)(tty); -- if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ /* If we have a running line discipline it may need kicking */ -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - -@@ -656,6 +920,7 @@ - int i; - struct tty_struct * tty; - struct inode *inode; -+ struct tty_ldisc *ld; - - /* Can't seek (pread) on ttys. */ - if (ppos != &file->f_pos) -@@ -684,11 +949,15 @@ - return -ERESTARTSYS; - } - #endif -+ /* We want to wait for the line discipline to sort out in this -+ situation */ -+ ld = tty_ldisc_ref_wait(tty); - lock_kernel(); -- if (tty->ldisc.read) -- i = (tty->ldisc.read)(tty,file,buf,count); -+ if (ld->read) -+ i = (ld->read)(tty,file,buf,count); - else - i = -EIO; -+ tty_ldisc_deref(ld); - unlock_kernel(); - if (i > 0) - inode->i_atime = CURRENT_TIME; -@@ -757,6 +1026,8 @@ - int is_console; - struct tty_struct * tty; - struct inode *inode = file->f_dentry->d_inode; -+ ssize_t ret; -+ struct tty_ldisc *ld; - - /* Can't seek (pwrite) on ttys. */ - if (ppos != &file->f_pos) -@@ -803,10 +1074,15 @@ - } - } - #endif -- if (!tty->ldisc.write) -- return -EIO; -- return do_tty_write(tty->ldisc.write, tty, file, -- (const unsigned char *)buf, count); -+ -+ ld = tty_ldisc_ref_wait(tty); -+ if (!ld->write) -+ ret = -EIO; -+ else -+ ret = do_tty_write(ld->write, tty, file, -+ (const unsigned char __user *)buf, count); -+ tty_ldisc_deref(ld); -+ return ret; - } - - /* Semaphore to protect creating and releasing a tty */ -@@ -971,7 +1247,9 @@ - (tty->ldisc.close)(tty); - goto release_mem_out; - } -+ set_bit(TTY_LDISC, &o_tty->flags); - } -+ set_bit(TTY_LDISC, &tty->flags); - goto success; - - /* -@@ -999,7 +1277,9 @@ - } - tty->count++; - tty->driver = *driver; /* N.B. why do this every time?? */ -- -+ /* FIXME */ -+ if(!test_bit(TTY_LDISC, &tty->flags)) -+ printk(KERN_ERR "init_dev but no ldisc\n"); - success: - *ret_tty = tty; - -@@ -1080,6 +1360,7 @@ - int pty_master, tty_closing, o_tty_closing, do_sleep; - int idx; - char buf[64]; -+ unsigned long flags; - - tty = (struct tty_struct *)filp->private_data; - if (tty_paranoia_check(tty, filp->f_dentry->d_inode->i_rdev, "release_dev")) -@@ -1272,17 +1553,51 @@ - #endif - - /* -+ * Prevent flush_to_ldisc() from rescheduling the work for later. Then -+ * kill any delayed work. As this is the final close it does not -+ * race with the set_ldisc code path. -+ */ -+ clear_bit(TTY_LDISC, &tty->flags); -+ clear_bit(TTY_DONT_FLIP, &tty->flags); -+ -+ /* -+ * Wait for any short term users (we know they are just driver -+ * side waiters as the file is closing so user count on the file -+ * side is zero. -+ */ -+ -+ spin_lock_irqsave(&tty_ldisc_lock, flags); -+ while(tty->ldisc.refcount) -+ { -+ spin_unlock_irqrestore(&tty_ldisc_lock, flags); -+ wait_event(tty_ldisc_wait, tty->ldisc.refcount == 0); -+ spin_lock_irqsave(&tty_ldisc_lock, flags); -+ } -+ spin_unlock_irqrestore(&tty_ldisc_lock, flags); -+ -+ /* - * Shutdown the current line discipline, and reset it to N_TTY. - * N.B. why reset ldisc when we're releasing the memory?? -+ * FIXME: this MUST get fixed for the new reflocking - */ - if (tty->ldisc.close) - (tty->ldisc.close)(tty); -- tty->ldisc = ldiscs[N_TTY]; -- tty->termios->c_line = N_TTY; -+ tty_ldisc_put(tty->ldisc.num); -+ -+ /* -+ * Switch the line discipline back -+ */ -+ tty_ldisc_assign(tty, tty_ldisc_get(N_TTY)); -+ tty_set_termios_ldisc(tty,N_TTY); -+ - if (o_tty) { -+ /* FIXME: could o_tty be in setldisc here ? */ -+ clear_bit(TTY_LDISC, &o_tty->flags); - if (o_tty->ldisc.close) - (o_tty->ldisc.close)(o_tty); -- o_tty->ldisc = ldiscs[N_TTY]; -+ tty_ldisc_put(o_tty->ldisc.num); -+ tty_ldisc_assign(o_tty, tty_ldisc_get(N_TTY)); -+ tty_set_termios_ldisc(o_tty,N_TTY); - } - - /* -@@ -1464,14 +1779,18 @@ - static unsigned int tty_poll(struct file * filp, poll_table * wait) - { - struct tty_struct * tty; -+ struct tty_ldisc *ld; -+ int ret = 0; - - tty = (struct tty_struct *)filp->private_data; - if (tty_paranoia_check(tty, filp->f_dentry->d_inode->i_rdev, "tty_poll")) - return 0; - -- if (tty->ldisc.poll) -- return (tty->ldisc.poll)(tty, filp, wait); -- return 0; -+ ld = tty_ldisc_ref_wait(tty); -+ if (ld->poll) -+ ret = (ld->poll)(tty, filp, wait); -+ tty_ldisc_deref(ld); -+ return ret; - } - - static int tty_fasync(int fd, struct file * filp, int on) -@@ -1505,12 +1824,15 @@ - static int tiocsti(struct tty_struct *tty, char * arg) - { - char ch, mbz = 0; -+ struct tty_ldisc *ld; - - if ((current->tty != tty) && !suser()) - return -EPERM; - if (get_user(ch, arg)) - return -EFAULT; -- tty->ldisc.receive_buf(tty, &ch, &mbz, 1); -+ ld = tty_ldisc_ref_wait(tty); -+ ld->receive_buf(tty, &ch, &mbz, 1); -+ tty_ldisc_deref(ld); - return 0; - } - -@@ -1718,6 +2040,7 @@ - { - struct tty_struct *tty, *real_tty; - int retval; -+ struct tty_ldisc *ld; - - tty = (struct tty_struct *)file->private_data; - if (tty_paranoia_check(tty, inode->i_rdev, "tty_ioctl")) -@@ -1808,6 +2131,7 @@ - case TIOCGSID: - return tiocgsid(tty, real_tty, (pid_t *) arg); - case TIOCGETD: -+ /* FIXME: check this is ok */ - return put_user(tty->ldisc.num, (int *) arg); - case TIOCSETD: - return tiocsetd(tty, (int *) arg); -@@ -1841,16 +2165,20 @@ - return send_break(tty, arg ? arg*(HZ/10) : HZ/4); - } - if (tty->driver.ioctl) { -- int retval = (tty->driver.ioctl)(tty, file, cmd, arg); -+ retval = (tty->driver.ioctl)(tty, file, cmd, arg); - if (retval != -ENOIOCTLCMD) - return retval; - } -- if (tty->ldisc.ioctl) { -- int retval = (tty->ldisc.ioctl)(tty, file, cmd, arg); -- if (retval != -ENOIOCTLCMD) -- return retval; -+ ld = tty_ldisc_ref_wait(tty); -+ retval = -EINVAL; -+ if (ld->ioctl) { -+ if(likely(test_bit(TTY_LDISC, &tty->flags))) -+ retval = ld->ioctl(tty, file, cmd, arg); -+ if (retval == -ENOIOCTLCMD) -+ retval = -EINVAL; - } -- return -EINVAL; -+ tty_ldisc_deref(ld); -+ return retval; - } - - -@@ -1883,14 +2211,20 @@ - int session; - int i; - struct file *filp; -+ struct tty_ldisc *disc; - - if (!tty) - return; - session = tty->session; -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ /* We don't want an ldisc switch during this */ -+ disc = tty_ldisc_ref(tty); -+ if (disc && disc->flush_buffer) -+ disc->flush_buffer(tty); -+ tty_ldisc_deref(disc); -+ - if (tty->driver.flush_buffer) - tty->driver.flush_buffer(tty); -+ - read_lock(&tasklist_lock); - for_each_task(p) { - if ((p->tty == tty) || -@@ -1942,11 +2276,16 @@ - unsigned char *cp; - char *fp; - int count; -- unsigned long flags; -+ unsigned long flags; -+ struct tty_ldisc *disc; -+ -+ disc = tty_ldisc_ref(tty); -+ if (disc == NULL) /* !TTY_LDISC */ -+ return; - - if (test_bit(TTY_DONT_FLIP, &tty->flags)) { - queue_task(&tty->flip.tqueue, &tq_timer); -- return; -+ goto out; - } - if (tty->flip.buf_num) { - cp = tty->flip.char_buf + TTY_FLIPBUF_SIZE; -@@ -1969,7 +2308,31 @@ - tty->flip.count = 0; - restore_flags(flags); - -- tty->ldisc.receive_buf(tty, cp, fp, count); -+ disc->receive_buf(tty, cp, fp, count); -+out: -+ tty_ldisc_deref(disc); -+} -+ -+/* -+ * Call the ldisc flush directly from a driver. This function may -+ * return an error and need retrying by the user. -+ */ -+ -+int tty_push_data(struct tty_struct *tty, unsigned char *cp, unsigned char *fp, int count) -+{ -+ int ret = 0; -+ struct tty_ldisc *disc; -+ -+ disc = tty_ldisc_ref(tty); -+ if(test_bit(TTY_DONT_FLIP, &tty->flags)) -+ ret = -EAGAIN; -+ else if(disc == NULL) -+ ret = -EIO; -+ else -+ disc->receive_buf(tty, cp, fp, count); -+ tty_ldisc_deref(disc); -+ return ret; -+ - } - - /* -@@ -2032,7 +2395,7 @@ - { - memset(tty, 0, sizeof(struct tty_struct)); - tty->magic = TTY_MAGIC; -- tty->ldisc = ldiscs[N_TTY]; -+ tty_ldisc_assign(tty, tty_ldisc_get(N_TTY)); - tty->pgrp = -1; - tty->flip.char_buf_ptr = tty->flip.char_buf; - tty->flip.flag_buf_ptr = tty->flip.flag_buf; -@@ -2217,7 +2580,7 @@ - void __init console_init(void) - { - /* Setup the default TTY line discipline. */ -- memset(ldiscs, 0, sizeof(ldiscs)); -+ memset(tty_ldiscs, 0, NR_LDISCS*sizeof(struct tty_ldisc)); - (void) tty_register_ldisc(N_TTY, &tty_ldisc_N_TTY); - - /* -diff -Nur linux-2.4.27/drivers/char/tty_ioctl.c linux-2.4.27-plasmaroo/drivers/char/tty_ioctl.c ---- linux-2.4.27/drivers/char/tty_ioctl.c 2002-11-28 23:53:12.000000000 +0000 -+++ linux-2.4.27-plasmaroo/drivers/char/tty_ioctl.c 2004-11-07 14:03:04.506939352 +0000 -@@ -29,6 +29,8 @@ - - #undef DEBUG - -+extern spinlock_t tty_termios_lock; -+ - /* - * Internal flag options for termios setting behavior - */ -@@ -96,8 +98,17 @@ - { - int canon_change; - struct termios old_termios = *tty->termios; -+ struct tty_ldisc *ld; -+ unsigned long flags; -+ -+ /* -+ * Perform the actual termios internal changes under lock. -+ */ -+ -+ /* FIXME: we need to decide on some locking/ordering semantics -+ for the set_termios notification eventually */ -+ spin_lock_irqsave(&tty_termios_lock, flags); - -- cli(); - *tty->termios = *new_termios; - unset_locked_termios(tty->termios, &old_termios, tty->termios_locked); - canon_change = (old_termios.c_lflag ^ tty->termios->c_lflag) & ICANON; -@@ -107,7 +118,6 @@ - tty->canon_data = 0; - tty->erasing = 0; - } -- sti(); - if (canon_change && !L_ICANON(tty) && tty->read_cnt) - /* Get characters left over from canonical mode. */ - wake_up_interruptible(&tty->read_wait); -@@ -131,16 +141,20 @@ - } - } - -- if (tty->driver.set_termios) -- (*tty->driver.set_termios)(tty, &old_termios); -+ ld = tty_ldisc_ref(tty); -+ if (ld != NULL) { -+ if (ld->set_termios) -+ (ld->set_termios)(tty, &old_termios); -+ tty_ldisc_deref(ld); -+ } -+ spin_unlock_irqrestore(&tty_termios_lock, flags); - -- if (tty->ldisc.set_termios) -- (*tty->ldisc.set_termios)(tty, &old_termios); - } - - static int set_termios(struct tty_struct * tty, unsigned long arg, int opt) - { - struct termios tmp_termios; -+ struct tty_ldisc *ld; - int retval = tty_check_change(tty); - - if (retval) -@@ -157,8 +171,13 @@ - return -EFAULT; - } - -- if ((opt & TERMIOS_FLUSH) && tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ ld = tty_ldisc_ref(tty); -+ -+ if (ld != NULL) { -+ if ((opt & TERMIOS_FLUSH) && ld->flush_buffer) -+ ld->flush_buffer(tty); -+ tty_ldisc_deref(ld); -+ } - - if (opt & TERMIOS_WAIT) { - tty_wait_until_sent(tty, 0); -@@ -223,12 +242,16 @@ - static int get_sgttyb(struct tty_struct * tty, struct sgttyb * sgttyb) - { - struct sgttyb tmp; -+ unsigned long flags; - -+ spin_lock_irqsave(&tty_termios_lock, flags); - tmp.sg_ispeed = 0; - tmp.sg_ospeed = 0; - tmp.sg_erase = tty->termios->c_cc[VERASE]; - tmp.sg_kill = tty->termios->c_cc[VKILL]; - tmp.sg_flags = get_sgflags(tty); -+ spin_unlock_irqrestore(&tty_termios_lock, flags); -+ - return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0; - } - -@@ -263,16 +286,19 @@ - int retval; - struct sgttyb tmp; - struct termios termios; -+ unsigned long flags; - - retval = tty_check_change(tty); - if (retval) - return retval; -- termios = *tty->termios; - if (copy_from_user(&tmp, sgttyb, sizeof(tmp))) - return -EFAULT; -+ spin_lock_irqsave(&tty_termios_lock, flags); -+ termios = *tty->termios; - termios.c_cc[VERASE] = tmp.sg_erase; - termios.c_cc[VKILL] = tmp.sg_kill; - set_sgflags(&termios, tmp.sg_flags); -+ spin_unlock_irqrestore(&tty_termios_lock, flags); - change_termios(tty, &termios); - return 0; - } -@@ -362,6 +388,8 @@ - { - struct tty_struct * real_tty; - int retval; -+ struct tty_ldisc *ld; -+ unsigned long flags; - - if (tty->driver.type == TTY_DRIVER_TYPE_PTY && - tty->driver.subtype == PTY_TYPE_MASTER) -@@ -440,22 +468,26 @@ - retval = tty_check_change(tty); - if (retval) - return retval; -+ -+ ld = tty_ldisc_ref(tty); - switch (arg) { - case TCIFLUSH: -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ if (ld->flush_buffer) -+ ld->flush_buffer(tty); - break; - case TCIOFLUSH: -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ if (ld->flush_buffer) -+ ld->flush_buffer(tty); - /* fall through */ - case TCOFLUSH: - if (tty->driver.flush_buffer) - tty->driver.flush_buffer(tty); - break; - default: -+ tty_ldisc_deref(ld); - return -EINVAL; - } -+ tty_ldisc_deref(ld); - return 0; - case TIOCOUTQ: - return put_user(tty->driver.chars_in_buffer ? -@@ -501,9 +533,11 @@ - case TIOCSSOFTCAR: - if (get_user(arg, (unsigned int *) arg)) - return -EFAULT; -+ spin_lock_irqsave(&tty_termios_lock, flags); - tty->termios->c_cflag = - ((tty->termios->c_cflag & ~CLOCAL) | - (arg ? CLOCAL : 0)); -+ spin_unlock_irqrestore(&tty_termios_lock, flags); - return 0; - default: - return -ENOIOCTLCMD; -diff -Nur linux-2.4.27/drivers/net/ppp_async.c linux-2.4.27-plasmaroo/drivers/net/ppp_async.c ---- linux-2.4.27/drivers/net/ppp_async.c 2002-08-03 01:39:44.000000000 +0100 -+++ linux-2.4.27-plasmaroo/drivers/net/ppp_async.c 2004-11-07 14:02:20.057696664 +0000 -@@ -117,6 +117,9 @@ - * frees the memory that ppp_asynctty_receive is using. The best - * way to fix this is to use a rwlock in the tty struct, but for now - * we use a single global rwlock for all ttys in ppp line discipline. -+ * -+ * FIXME: this is no longer true. The _close path for the ldisc is -+ * now guaranteed to be sane. - */ - static rwlock_t disc_data_lock = RW_LOCK_UNLOCKED; - -@@ -139,7 +142,8 @@ - } - - /* -- * Called when a tty is put into PPP line discipline. -+ * Called when a tty is put into PPP line discipline. Called in process -+ * context. - */ - static int - ppp_asynctty_open(struct tty_struct *tty) -@@ -248,6 +252,11 @@ - return -EAGAIN; - } - -+/* -+ * Called in process context only. May be re-entered by multiple -+ * ioctl calling threads. -+ */ -+ - static int - ppp_asynctty_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) -@@ -714,7 +723,8 @@ - - /* - * Flush output from our internal buffers. -- * Called for the TCFLSH ioctl. -+ * Called for the TCFLSH ioctl. Can be entered in parallel -+ * but this is covered by the xmit_lock. - */ - static void - ppp_async_flush_output(struct asyncppp *ap) -@@ -819,7 +829,9 @@ - ppp_input_error(&ap->chan, code); - } - --/* called when the tty driver has data for us. */ -+/* Called when the tty driver has data for us. Runs parallel with the -+ other ldisc functions but will not be re-entered */ -+ - static void - ppp_async_input(struct asyncppp *ap, const unsigned char *buf, - char *flags, int count) -diff -Nur linux-2.4.27/drivers/net/ppp_synctty.c linux-2.4.27-plasmaroo/drivers/net/ppp_synctty.c ---- linux-2.4.27/drivers/net/ppp_synctty.c 2002-08-03 01:39:44.000000000 +0100 -+++ linux-2.4.27-plasmaroo/drivers/net/ppp_synctty.c 2004-11-07 14:02:20.077693624 +0000 -@@ -172,6 +172,8 @@ - * frees the memory that ppp_synctty_receive is using. The best - * way to fix this is to use a rwlock in the tty struct, but for now - * we use a single global rwlock for all ttys in ppp line discipline. -+ * -+ * FIXME: Fixed in tty_io nowdays. - */ - static rwlock_t disc_data_lock = RW_LOCK_UNLOCKED; - -diff -Nur linux-2.4.27/drivers/net/slip.c linux-2.4.27-plasmaroo/drivers/net/slip.c ---- linux-2.4.27/drivers/net/slip.c 2002-11-28 23:53:14.000000000 +0000 -+++ linux-2.4.27-plasmaroo/drivers/net/slip.c 2004-11-07 14:02:20.086692256 +0000 -@@ -670,7 +670,9 @@ - * Handle the 'receiver data ready' interrupt. - * This function is called by the 'tty_io' module in the kernel when - * a block of SLIP data has been received, which can now be decapsulated -- * and sent on to some IP layer for further processing. -+ * and sent on to some IP layer for further processing. This will not -+ * be re-entered while running but other ldisc functions may be called -+ * in parallel - */ - - static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) -@@ -826,9 +828,11 @@ - * SLIP line discipline is called for. Because we are - * sure the tty line exists, we only have to link it to - * a free SLIP channel... -+ * -+ * Called in process context serialized from other ldisc calls. - */ --static int --slip_open(struct tty_struct *tty) -+ -+static int slip_open(struct tty_struct *tty) - { - struct slip *sl; - int err; -@@ -910,6 +914,9 @@ - } - - /* -+ -+ FIXME: 1,2 are fixed 3 was never true anyway. -+ - Let me to blame a bit. - 1. TTY module calls this funstion on soft interrupt. - 2. TTY module calls this function WITH MASKED INTERRUPTS! -@@ -928,9 +935,8 @@ - - /* - * Close down a SLIP channel. -- * This means flushing out any pending queues, and then restoring the -- * TTY line discipline to what it was before it got hooked to SLIP -- * (which usually is TTY again). -+ * This means flushing out any pending queues, and then returning. This -+ * call is serialized against other ldisc functions. - */ - static void - slip_close(struct tty_struct *tty) -diff -Nur linux-2.4.27/drivers/sbus/char/zs.c linux-2.4.27-plasmaroo/drivers/sbus/char/zs.c ---- linux-2.4.27/drivers/sbus/char/zs.c 2002-08-03 01:39:44.000000000 +0100 -+++ linux-2.4.27-plasmaroo/drivers/sbus/char/zs.c 2004-11-07 14:02:20.331655016 +0000 -@@ -1605,10 +1605,10 @@ - tty->closing = 0; - info->event = 0; - info->tty = 0; -- if (tty->ldisc.num != ldiscs[N_TTY].num) { -+ if (tty->ldisc.num != N_TTY) { - if (tty->ldisc.close) - (tty->ldisc.close)(tty); -- tty->ldisc = ldiscs[N_TTY]; -+ tty->ldisc = *(tty_ldisc_get(N_TTY)); - tty->termios->c_line = N_TTY; - if (tty->ldisc.open) - (tty->ldisc.open)(tty); -diff -Nur linux-2.4.27/fs/proc/proc_tty.c linux-2.4.27-plasmaroo/fs/proc/proc_tty.c ---- linux-2.4.27/fs/proc/proc_tty.c 2000-04-21 23:17:57.000000000 +0100 -+++ linux-2.4.27-plasmaroo/fs/proc/proc_tty.c 2004-11-07 14:02:20.042698944 +0000 -@@ -15,8 +15,6 @@ - #include <asm/bitops.h> - - extern struct tty_driver *tty_drivers; /* linked list of tty drivers */ --extern struct tty_ldisc ldiscs[]; -- - - static int tty_drivers_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data); -@@ -106,12 +104,15 @@ - int i; - int len = 0; - off_t begin = 0; -- -+ struct tty_ldisc *ld; -+ - for (i=0; i < NR_LDISCS; i++) { -- if (!(ldiscs[i].flags & LDISC_FLAG_DEFINED)) -+ ld = tty_ldisc_get(i); -+ if (ld == NULL) - continue; - len += sprintf(page+len, "%-10s %2d\n", -- ldiscs[i].name ? ldiscs[i].name : "???", i); -+ ld->name ? ld->name : "???", i); -+ tty_ldisc_put(i); - if (len+begin > off+count) - break; - if (len+begin < off) { -diff -Nur linux-2.4.27/include/linux/tty.h linux-2.4.27-plasmaroo/include/linux/tty.h ---- linux-2.4.27/include/linux/tty.h 2003-06-13 15:51:39.000000000 +0100 -+++ linux-2.4.27-plasmaroo/include/linux/tty.h 2004-11-07 14:02:20.043698792 +0000 -@@ -322,26 +322,28 @@ - * tty->write. Thus, you must use the inline functions set_bit() and - * clear_bit() to make things atomic. - */ --#define TTY_THROTTLED 0 --#define TTY_IO_ERROR 1 --#define TTY_OTHER_CLOSED 2 --#define TTY_EXCLUSIVE 3 --#define TTY_DEBUG 4 --#define TTY_DO_WRITE_WAKEUP 5 --#define TTY_PUSH 6 --#define TTY_CLOSING 7 --#define TTY_DONT_FLIP 8 --#define TTY_HW_COOK_OUT 14 --#define TTY_HW_COOK_IN 15 --#define TTY_PTY_LOCK 16 --#define TTY_NO_WRITE_SPLIT 17 -+#define TTY_THROTTLED 0 /* Call unthrottle() at threshold min */ -+#define TTY_IO_ERROR 1 /* Canse an I/O error (may be no ldisc too) */ -+#define TTY_OTHER_CLOSED 2 /* Other side (if any) has closed */ -+#define TTY_EXCLUSIVE 3 /* Exclusive open mode */ -+#define TTY_DEBUG 4 /* Debugging */ -+#define TTY_DO_WRITE_WAKEUP 5 /* Call write_wakeup after queuing new */ -+#define TTY_PUSH 6 /* n_tty private */ -+#define TTY_CLOSING 7 /* ->close() in progress */ -+#define TTY_DONT_FLIP 8 /* Defer buffer flip */ -+#define TTY_LDISC 9 /* Line discipline attached */ -+#define TTY_HW_COOK_OUT 14 /* Hardware can do output cooking */ -+#define TTY_HW_COOK_IN 15 /* Hardware can do input cooking */ -+#define TTY_PTY_LOCK 16 /* pty private */ -+#define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */ -+#define TTY_HUPPED 18 /* Post driver->hangup() */ - - #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty)) - - extern void tty_write_flush(struct tty_struct *); - - extern struct termios tty_std_termios; --extern struct tty_ldisc ldiscs[]; -+extern struct tty_ldisc tty_ldiscs[]; - extern int fg_console, last_console, want_console; - - extern int kmsg_redirect; -@@ -396,6 +398,16 @@ - extern void tty_flip_buffer_push(struct tty_struct *tty); - extern int tty_get_baud_rate(struct tty_struct *tty); - -+extern struct tty_ldisc *tty_ldisc_ref(struct tty_struct *); -+extern void tty_ldisc_deref(struct tty_ldisc *); -+extern struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *); -+ -+extern struct tty_ldisc *tty_ldisc_get(int); -+extern void tty_ldisc_put(int); -+ -+extern void tty_wakeup(struct tty_struct *tty); -+ -+ - /* n_tty.c */ - extern struct tty_ldisc tty_ldisc_N_TTY; - -diff -Nur linux-2.4.27/include/linux/tty_ldisc.h linux-2.4.27-plasmaroo/include/linux/tty_ldisc.h ---- linux-2.4.27/include/linux/tty_ldisc.h 2001-11-22 19:46:19.000000000 +0000 -+++ linux-2.4.27-plasmaroo/include/linux/tty_ldisc.h 2004-11-07 14:02:20.044698640 +0000 -@@ -129,6 +129,7 @@ - char *fp, int count); - int (*receive_room)(struct tty_struct *); - void (*write_wakeup)(struct tty_struct *); -+ int refcount; - }; - - #define TTY_LDISC_MAGIC 0x5403 diff --git a/sys-kernel/hppa-sources/files/CAN-2004-0882-0883.patch b/sys-kernel/hppa-sources/files/CAN-2004-0882-0883.patch deleted file mode 100644 index 63c5ba30403f..000000000000 --- a/sys-kernel/hppa-sources/files/CAN-2004-0882-0883.patch +++ /dev/null @@ -1,97 +0,0 @@ -diff -ur linux-2.4.27/fs/smbfs/proc.c linux-2.4.28/fs/smbfs/proc.c ---- linux-2.4.27/fs/smbfs/proc.c 2004-11-12 19:32:24.000000000 +0000 -+++ linux-2.4.28/fs/smbfs/proc.c 2004-11-19 20:18:27.000000000 +0000 -@@ -1289,10 +1289,12 @@ - data_len = WVAL(buf, 1); - - /* we can NOT simply trust the data_len given by the server ... */ -- if (data_len > server->packet_size - (buf+3 - server->packet)) { -- printk(KERN_ERR "smb_proc_read: invalid data length!! " -- "%d > %d - (%p - %p)\n", -- data_len, server->packet_size, buf+3, server->packet); -+ if (data_len > count || -+ (buf+3 - server->packet) + data_len > server->packet_size) { -+ printk(KERN_ERR "smb_proc_read: invalid data length/offset!! " -+ "%d > %d || (%p - %p) + %d > %d\n", -+ data_len, count, -+ buf+3, server->packet, data_len, server->packet_size); - result = -EIO; - goto out; - } -@@ -1378,10 +1380,12 @@ - buf = smb_base(server->packet) + data_off; - - /* we can NOT simply trust the info given by the server ... */ -- if (data_len > server->packet_size - (buf - server->packet)) { -- printk(KERN_ERR "smb_proc_read: invalid data length!! " -- "%d > %d - (%p - %p)\n", -- data_len, server->packet_size, buf, server->packet); -+ if (data_len > count || -+ (buf - server->packet) + data_len > server->packet_size) { -+ printk(KERN_ERR "smb_proc_readX: invalid data length/offset!! " -+ "%d > %d || (%p - %p) + %d > %d\n", -+ data_len, count, -+ buf, server->packet, data_len, server->packet_size); - result = -EIO; - goto out; - } -diff -ur linux-2.4.27/fs/smbfs/sock.c linux-2.4.28/fs/smbfs/sock.c ---- linux-2.4.27/fs/smbfs/sock.c 2004-11-12 19:32:24.000000000 +0000 -+++ linux-2.4.28/fs/smbfs/sock.c 2004-11-19 20:18:27.000000000 +0000 -@@ -571,7 +571,11 @@ - parm_disp, parm_offset, parm_count, - data_disp, data_offset, data_count); - *parm = base + parm_offset; -+ if (*parm - inbuf + parm_tot > server->packet_size) -+ goto out_bad_parm; - *data = base + data_offset; -+ if (*data - inbuf + data_tot > server->packet_size) -+ goto out_bad_data; - goto success; - } - -@@ -591,6 +595,8 @@ - rcv_buf = smb_vmalloc(buf_len); - if (!rcv_buf) - goto out_no_mem; -+ memset(rcv_buf, 0, buf_len); -+ - *parm = rcv_buf; - *data = rcv_buf + total_p; - } else if (data_tot > total_d || parm_tot > total_p) -@@ -598,8 +604,12 @@ - - if (parm_disp + parm_count > total_p) - goto out_bad_parm; -+ if (parm_offset + parm_count > server->packet_size) -+ goto out_bad_parm; - if (data_disp + data_count > total_d) - goto out_bad_data; -+ if (data_offset + data_count > server->packet_size) -+ goto out_bad_data; - memcpy(*parm + parm_disp, base + parm_offset, parm_count); - memcpy(*data + data_disp, base + data_offset, data_count); - -@@ -610,8 +620,11 @@ - * Check whether we've received all of the data. Note that - * we use the packet totals -- total lengths might shrink! - */ -- if (data_len >= data_tot && parm_len >= parm_tot) -+ if (data_len >= data_tot && parm_len >= parm_tot) { -+ data_len = data_tot; -+ parm_len = parm_tot; - break; -+ } - } - - /* -@@ -625,6 +638,9 @@ - server->packet = rcv_buf; - rcv_buf = inbuf; - } else { -+ if (parm_len + data_len > buf_len) -+ goto out_data_grew; -+ - PARANOIA("copying data, old size=%d, new size=%u\n", - server->packet_size, buf_len); - memcpy(inbuf, rcv_buf, parm_len + data_len); diff --git a/sys-kernel/hppa-sources/files/CAN-2004-1074.patch b/sys-kernel/hppa-sources/files/CAN-2004-1074.patch deleted file mode 100644 index 11846801b90d..000000000000 --- a/sys-kernel/hppa-sources/files/CAN-2004-1074.patch +++ /dev/null @@ -1,63 +0,0 @@ -diff -uNr linux-2.4.27-pa4-r2.orig/fs/binfmt_aout.c linux-2.4.27-pa4-r2/fs/binfmt_aout.c ---- linux-2.4.27-pa4-r2.orig/fs/binfmt_aout.c 2004-12-08 18:24:03.899156592 +0100 -+++ linux-2.4.27-pa4-r2/fs/binfmt_aout.c 2004-12-08 18:24:25.898812136 +0100 -@@ -39,13 +39,18 @@ - NULL, THIS_MODULE, load_aout_binary, load_aout_library, aout_core_dump, PAGE_SIZE - }; - --static void set_brk(unsigned long start, unsigned long end) -+#define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE) -+ -+static int set_brk(unsigned long start, unsigned long end) - { - start = PAGE_ALIGN(start); - end = PAGE_ALIGN(end); -- if (end <= start) -- return; -- do_brk(start, end - start); -+ if (end > start) { -+ unsigned long addr = do_brk(start, end - start); -+ if (BAD_ADDR(addr)) -+ return addr; -+ } -+ return 0; - } - - /* -@@ -405,7 +410,11 @@ - beyond_if: - set_binfmt(&aout_format); - -- set_brk(current->mm->start_brk, current->mm->brk); -+ retval = set_brk(current->mm->start_brk, current->mm->brk); -+ if (retval < 0) { -+ send_sig(SIGKILL, current, 0); -+ return retval; -+ } - - retval = setup_arg_pages(bprm); - if (retval < 0) { -diff -uNr linux-2.4.27-pa4-r2.orig/fs/exec.c linux-2.4.27-pa4-r2/fs/exec.c ---- linux-2.4.27-pa4-r2.orig/fs/exec.c 2004-12-08 18:24:03.808170424 +0100 -+++ linux-2.4.27-pa4-r2/fs/exec.c 2004-12-08 18:26:20.552382144 +0100 -@@ -382,6 +382,7 @@ - - down_write(¤t->mm->mmap_sem); - { -+ struct vm_area_struct *vma; - mpnt->vm_mm = mm; - #ifdef ARCH_STACK_GROWSUP - mpnt->vm_start = stack_base; -@@ -397,6 +398,12 @@ - mpnt->vm_pgoff = 0; - mpnt->vm_file = NULL; - mpnt->vm_private_data = (void *) 0; -+ vma = find_vma(current->mm, mpnt->vm_start); -+ if (vma) { -+ up_write(¤t->mm->mmap_sem); -+ kmem_cache_free(vm_area_cachep, mpnt); -+ return -ENOMEM; -+ } - insert_vm_struct(mm, mpnt); - mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; - } diff --git a/sys-kernel/hppa-sources/files/CAN-2004-1235.patch b/sys-kernel/hppa-sources/files/CAN-2004-1235.patch new file mode 100644 index 000000000000..6095e844d5f1 --- /dev/null +++ b/sys-kernel/hppa-sources/files/CAN-2004-1235.patch @@ -0,0 +1,303 @@ +diff -ur linux-2.6.10/arch/mips/kernel/irixelf.c linux-2.6.10.plasmaroo/arch/mips/kernel/irixelf.c +--- linux-2.6.10/arch/mips/kernel/irixelf.c 2004-12-24 21:35:50.000000000 +0000 ++++ linux-2.6.10.plasmaroo/arch/mips/kernel/irixelf.c 2005-01-07 15:36:00.383356800 +0000 +@@ -127,7 +127,7 @@ + end = PAGE_ALIGN(end); + if (end <= start) + return; +- do_brk(start, end - start); ++ do_brk_locked(start, end - start); + } + + +@@ -375,7 +375,7 @@ + + /* Map the last of the bss segment */ + if (last_bss > len) { +- do_brk(len, (last_bss - len)); ++ do_brk_locked(len, (last_bss - len)); + } + kfree(elf_phdata); + +@@ -562,7 +562,7 @@ + unsigned long v; + struct prda *pp; + +- v = do_brk (PRDA_ADDRESS, PAGE_SIZE); ++ v = do_brk_locked (PRDA_ADDRESS, PAGE_SIZE); + + if (v < 0) + return; +@@ -853,7 +853,7 @@ + len = (elf_phdata->p_filesz + elf_phdata->p_vaddr+ 0xfff) & 0xfffff000; + bss = elf_phdata->p_memsz + elf_phdata->p_vaddr; + if (bss > len) +- do_brk(len, bss-len); ++ do_brk_locked(len, bss-len); + kfree(elf_phdata); + return 0; + } +diff -ur linux-2.6.10/arch/sparc64/kernel/binfmt_aout32.c linux-2.6.10.plasmaroo/arch/sparc64/kernel/binfmt_aout32.c +--- linux-2.6.10/arch/sparc64/kernel/binfmt_aout32.c 2004-12-24 21:34:45.000000000 +0000 ++++ linux-2.6.10.plasmaroo/arch/sparc64/kernel/binfmt_aout32.c 2005-01-07 15:36:00.432349352 +0000 +@@ -49,7 +49,7 @@ + end = PAGE_ALIGN(end); + if (end <= start) + return; +- do_brk(start, end - start); ++ do_brk_locked(start, end - start); + } + + /* +@@ -246,10 +246,10 @@ + if (N_MAGIC(ex) == NMAGIC) { + loff_t pos = fd_offset; + /* Fuck me plenty... */ +- error = do_brk(N_TXTADDR(ex), ex.a_text); ++ error = do_brk_locked(N_TXTADDR(ex), ex.a_text); + bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex), + ex.a_text, &pos); +- error = do_brk(N_DATADDR(ex), ex.a_data); ++ error = do_brk_locked(N_DATADDR(ex), ex.a_data); + bprm->file->f_op->read(bprm->file, (char __user *)N_DATADDR(ex), + ex.a_data, &pos); + goto beyond_if; +@@ -257,7 +257,7 @@ + + if (N_MAGIC(ex) == OMAGIC) { + loff_t pos = fd_offset; +- do_brk(N_TXTADDR(ex) & PAGE_MASK, ++ do_brk_locked(N_TXTADDR(ex) & PAGE_MASK, + ex.a_text+ex.a_data + PAGE_SIZE - 1); + bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex), + ex.a_text+ex.a_data, &pos); +@@ -272,7 +272,7 @@ + + if (!bprm->file->f_op->mmap) { + loff_t pos = fd_offset; +- do_brk(0, ex.a_text+ex.a_data); ++ do_brk_locked(0, ex.a_text+ex.a_data); + bprm->file->f_op->read(bprm->file, + (char __user *)N_TXTADDR(ex), + ex.a_text+ex.a_data, &pos); +@@ -389,7 +389,7 @@ + len = PAGE_ALIGN(ex.a_text + ex.a_data); + bss = ex.a_text + ex.a_data + ex.a_bss; + if (bss > len) { +- error = do_brk(start_addr + len, bss - len); ++ error = do_brk_locked(start_addr + len, bss - len); + retval = error; + if (error != start_addr + len) + goto out; +diff -Nur linux-2.6.10/arch/x86_64/ia32/ia32_aout.c linux-2.6.10.plasmaroo/arch/x86_64/ia32/ia32_aout.c +--- linux-2.6.10/arch/x86_64/ia32/ia32_aout.c 2005-01-03 16:17:04.000000000 -0200 ++++ linux-2.6.10.plasmaroo/arch/x86_64/ia32/ia32_aout.c 2005-01-03 16:46:53.846823360 -0200 +@@ -115,7 +115,7 @@ + end = PAGE_ALIGN(end); + if (end <= start) + return; +- do_brk(start, end - start); ++ do_brk_locked(start, end - start); + } + + #if CORE_DUMP +@@ -325,7 +325,7 @@ + pos = 32; + map_size = ex.a_text+ex.a_data; + +- error = do_brk(text_addr & PAGE_MASK, map_size); ++ error = do_brk_locked(text_addr & PAGE_MASK, map_size); + if (error != (text_addr & PAGE_MASK)) { + send_sig(SIGKILL, current, 0); + return error; +@@ -361,7 +361,7 @@ + + if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) { + loff_t pos = fd_offset; +- do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); ++ do_brk_locked(N_TXTADDR(ex), ex.a_text+ex.a_data); + bprm->file->f_op->read(bprm->file,(char *)N_TXTADDR(ex), + ex.a_text+ex.a_data, &pos); + flush_icache_range((unsigned long) N_TXTADDR(ex), +@@ -470,7 +470,7 @@ + } + #endif + +- do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); ++ do_brk_locked(start_addr, ex.a_text + ex.a_data + ex.a_bss); + + file->f_op->read(file, (char *)start_addr, + ex.a_text + ex.a_data, &pos); +@@ -494,7 +494,7 @@ + len = PAGE_ALIGN(ex.a_text + ex.a_data); + bss = ex.a_text + ex.a_data + ex.a_bss; + if (bss > len) { +- error = do_brk(start_addr + len, bss - len); ++ error = do_brk_locked(start_addr + len, bss - len); + retval = error; + if (error != start_addr + len) + goto out; +diff -ur linux-2.6.10/fs/binfmt_aout.c linux-2.6.10.plasmaroo/fs/binfmt_aout.c +--- linux-2.6.10/fs/binfmt_aout.c 2004-12-24 21:35:50.000000000 +0000 ++++ linux-2.6.10.plasmaroo/fs/binfmt_aout.c 2005-01-07 15:36:00.000000000 +0000 +@@ -50,7 +50,7 @@ + start = PAGE_ALIGN(start); + end = PAGE_ALIGN(end); + if (end > start) { +- unsigned long addr = do_brk(start, end - start); ++ unsigned long addr = do_brk_locked(start, end - start); + if (BAD_ADDR(addr)) + return addr; + } +@@ -323,10 +323,10 @@ + loff_t pos = fd_offset; + /* Fuck me plenty... */ + /* <AOL></AOL> */ +- error = do_brk(N_TXTADDR(ex), ex.a_text); ++ error = do_brk_locked(N_TXTADDR(ex), ex.a_text); + bprm->file->f_op->read(bprm->file, (char *) N_TXTADDR(ex), + ex.a_text, &pos); +- error = do_brk(N_DATADDR(ex), ex.a_data); ++ error = do_brk_locked(N_DATADDR(ex), ex.a_data); + bprm->file->f_op->read(bprm->file, (char *) N_DATADDR(ex), + ex.a_data, &pos); + goto beyond_if; +@@ -347,7 +347,7 @@ + map_size = ex.a_text+ex.a_data; + #endif + +- error = do_brk(text_addr & PAGE_MASK, map_size); ++ error = do_brk_locked(text_addr & PAGE_MASK, map_size); + if (error != (text_addr & PAGE_MASK)) { + send_sig(SIGKILL, current, 0); + return error; +@@ -382,7 +382,7 @@ + + if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) { + loff_t pos = fd_offset; +- do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); ++ do_brk_locked(N_TXTADDR(ex), ex.a_text+ex.a_data); + bprm->file->f_op->read(bprm->file, + (char __user *)N_TXTADDR(ex), + ex.a_text+ex.a_data, &pos); +@@ -488,7 +488,7 @@ + error_time = jiffies; + } + +- do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); ++ do_brk_locked(start_addr, ex.a_text + ex.a_data + ex.a_bss); + + file->f_op->read(file, (char __user *)start_addr, + ex.a_text + ex.a_data, &pos); +@@ -512,7 +512,7 @@ + len = PAGE_ALIGN(ex.a_text + ex.a_data); + bss = ex.a_text + ex.a_data + ex.a_bss; + if (bss > len) { +- error = do_brk(start_addr + len, bss - len); ++ error = do_brk_locked(start_addr + len, bss - len); + retval = error; + if (error != start_addr + len) + goto out; +diff -ur linux-2.6.10/fs/binfmt_elf.c linux-2.6.10.plasmaroo/fs/binfmt_elf.c +--- linux-2.6.10/fs/binfmt_elf.c 2004-12-24 21:34:33.000000000 +0000 ++++ linux-2.6.10.plasmaroo/fs/binfmt_elf.c 2005-01-07 15:36:00.000000000 +0000 +@@ -88,7 +88,7 @@ + start = ELF_PAGEALIGN(start); + end = ELF_PAGEALIGN(end); + if (end > start) { +- unsigned long addr = do_brk(start, end - start); ++ unsigned long addr = do_brk_locked(start, end - start); + if (BAD_ADDR(addr)) + return addr; + } +@@ -408,7 +408,7 @@ + + /* Map the last of the bss segment */ + if (last_bss > elf_bss) { +- error = do_brk(elf_bss, last_bss - elf_bss); ++ error = do_brk_locked(elf_bss, last_bss - elf_bss); + if (BAD_ADDR(error)) + goto out_close; + } +@@ -448,7 +448,7 @@ + goto out; + } + +- do_brk(0, text_data); ++ do_brk_locked(0, text_data); + if (!interpreter->f_op || !interpreter->f_op->read) + goto out; + if (interpreter->f_op->read(interpreter, addr, text_data, &offset) < 0) +@@ -456,7 +456,7 @@ + flush_icache_range((unsigned long)addr, + (unsigned long)addr + text_data); + +- do_brk(ELF_PAGESTART(text_data + ELF_MIN_ALIGN - 1), ++ do_brk_locked(ELF_PAGESTART(text_data + ELF_MIN_ALIGN - 1), + interp_ex->a_bss); + elf_entry = interp_ex->a_entry; + +@@ -1025,7 +1025,7 @@ + len = ELF_PAGESTART(elf_phdata->p_filesz + elf_phdata->p_vaddr + ELF_MIN_ALIGN - 1); + bss = elf_phdata->p_memsz + elf_phdata->p_vaddr; + if (bss > len) +- do_brk(len, bss - len); ++ do_brk_locked(len, bss - len); + error = 0; + + out_free_ph: +diff -ur linux-2.6.10/include/linux/mm.h linux-2.6.10.plasmaroo/include/linux/mm.h +--- linux-2.6.10/include/linux/mm.h 2004-12-24 21:33:50.000000000 +0000 ++++ linux-2.6.10.plasmaroo/include/linux/mm.h 2005-01-07 15:36:00.000000000 +0000 +@@ -704,6 +704,7 @@ + extern int do_munmap(struct mm_struct *, unsigned long, size_t); + + extern unsigned long do_brk(unsigned long, unsigned long); ++extern unsigned long do_brk_locked(unsigned long, unsigned long); + + /* filemap.c */ + extern unsigned long page_unuse(struct page *); +diff -ur linux-2.6.10/mm/mmap.c linux-2.6.10.plasmaroo/mm/mmap.c +--- linux-2.6.10/mm/mmap.c 2004-12-24 21:35:00.000000000 +0000 ++++ linux-2.6.10.plasmaroo/mm/mmap.c 2005-01-07 15:36:04.000000000 +0000 +@@ -1826,6 +1826,20 @@ + + EXPORT_SYMBOL(do_brk); + ++/* locking version of do_brk. */ ++unsigned long do_brk_locked(unsigned long addr, unsigned long len) ++{ ++ unsigned long ret; ++ ++ down_write(¤t->mm->mmap_sem); ++ ret = do_brk(addr, len); ++ up_write(¤t->mm->mmap_sem); ++ ++ return ret; ++} ++ ++EXPORT_SYMBOL(do_brk_locked); ++ + /* Release all mmaps. */ + void exit_mmap(struct mm_struct *mm) + { +@@ -1952,3 +1966,4 @@ + } + return new_vma; + } ++ +diff -ur linux-2.6.10/mm/nommu.c linux-2.6.10.plasmaroo/mm/nommu.c +--- linux-2.6.10/mm/nommu.c 2004-12-24 21:35:25.000000000 +0000 ++++ linux-2.6.10.plasmaroo/mm/nommu.c 2005-01-07 15:30:24.000000000 +0000 +@@ -557,6 +557,11 @@ + return -ENOMEM; + } + ++unsigned long do_brk_locked(unsigned long addr, unsigned long len) ++{ ++ return -ENOMEM; ++} ++ + struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr) + { + return NULL; diff --git a/sys-kernel/hppa-sources/files/CAN-2004-685.patch b/sys-kernel/hppa-sources/files/CAN-2004-685.patch deleted file mode 100644 index d1be834cc8a5..000000000000 --- a/sys-kernel/hppa-sources/files/CAN-2004-685.patch +++ /dev/null @@ -1,83 +0,0 @@ -# This is a BitKeeper generated diff -Nru style patch. -# -# ChangeSet -# 2004/07/26 19:14:16-03:00 mjc@redhat.com -# [PATCH] USB: more sparse fixes -# -# Back in October 2003 Arnaldo commited some fixes prior to 2.6 for some leaking info to userspace in the -# usb drivers: -# http://linux.bkbits.net:8080/linux-2.6/cset@3f986b35LyBKc-OxB8G6k22oOjgYTQ -# -# The corresponding changes have not been commited to 2.4, or included in -# the previous sparse fixes. -# -# drivers/usb/audio.c -# 2004/07/15 08:46:52-03:00 mjc@redhat.com +4 -0 -# USB: more sparse fixes -# -# drivers/usb/brlvger.c -# 2004/07/15 08:47:27-03:00 mjc@redhat.com +1 -0 -# USB: more sparse fixes -# -# drivers/usb/serial/io_edgeport.c -# 2004/07/15 08:48:06-03:00 mjc@redhat.com +1 -0 -# USB: more sparse fixes -# -# drivers/usb/vicam.c -# 2004/07/15 08:47:13-03:00 mjc@redhat.com +1 -0 -# USB: more sparse fixes -# -diff -Nru a/drivers/usb/audio.c b/drivers/usb/audio.c ---- a/drivers/usb/audio.c 2004-08-08 07:41:30 -07:00 -+++ b/drivers/usb/audio.c 2004-08-08 07:41:30 -07:00 -@@ -2141,6 +2141,8 @@ - - if (cmd == SOUND_MIXER_INFO) { - mixer_info info; -+ -+ memset(&info, 0, sizeof(info)); - strncpy(info.id, "USB_AUDIO", sizeof(info.id)); - strncpy(info.name, "USB Audio Class Driver", sizeof(info.name)); - info.modify_counter = ms->modcnt; -@@ -2150,6 +2152,8 @@ - } - if (cmd == SOUND_OLD_MIXER_INFO) { - _old_mixer_info info; -+ -+ memset(&info, 0, sizeof(info)); - strncpy(info.id, "USB_AUDIO", sizeof(info.id)); - strncpy(info.name, "USB Audio Class Driver", sizeof(info.name)); - if (copy_to_user((void *)arg, &info, sizeof(info))) -diff -Nru a/drivers/usb/brlvger.c b/drivers/usb/brlvger.c ---- a/drivers/usb/brlvger.c 2004-08-08 07:41:30 -07:00 -+++ b/drivers/usb/brlvger.c 2004-08-08 07:41:30 -07:00 -@@ -743,6 +743,7 @@ - case BRLVGER_GET_INFO: { - struct brlvger_info vi; - -+ memset(&vi, 0, sizeof(vi)); - strncpy(vi.driver_version, DRIVER_VERSION, - sizeof(vi.driver_version)); - vi.driver_version[sizeof(vi.driver_version)-1] = 0; -diff -Nru a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c ---- a/drivers/usb/serial/io_edgeport.c 2004-08-08 07:41:30 -07:00 -+++ b/drivers/usb/serial/io_edgeport.c 2004-08-08 07:41:30 -07:00 -@@ -1913,6 +1913,7 @@ - - case TIOCGICOUNT: - cnow = edge_port->icount; -+ memset(&icount, 0, sizeof(icount)); - icount.cts = cnow.cts; - icount.dsr = cnow.dsr; - icount.rng = cnow.rng; -diff -Nru a/drivers/usb/vicam.c b/drivers/usb/vicam.c ---- a/drivers/usb/vicam.c 2004-08-08 07:41:30 -07:00 -+++ b/drivers/usb/vicam.c 2004-08-08 07:41:30 -07:00 -@@ -481,6 +481,7 @@ - struct video_capability b; - - DBG("VIDIOCGCAP\n"); -+ memset(&b, 0, sizeof(b)); - strcpy(b.name, "ViCam-based Camera"); - b.type = VID_TYPE_CAPTURE; - b.channels = 1; diff --git a/sys-kernel/hppa-sources/files/LKA-20050107.patch b/sys-kernel/hppa-sources/files/LKA-20050107.patch new file mode 100644 index 000000000000..bc4ba1a9a207 --- /dev/null +++ b/sys-kernel/hppa-sources/files/LKA-20050107.patch @@ -0,0 +1,163 @@ +diff -urNp linux-2.6.10/drivers/char/moxa.c linux-2.6.10-new/drivers/char/moxa.c +--- linux-2.6.10/drivers/char/moxa.c 2005-01-07 10:51:23 -0500 ++++ linux-2.6.10-new/drivers/char/moxa.c 2005-01-07 10:51:33 -0500 +@@ -1668,6 +1668,8 @@ int MoxaDriverIoctl(unsigned int cmd, un + return -EFAULT; + if(dltmp.cardno < 0 || dltmp.cardno >= MAX_BOARDS) + return -EINVAL; ++ if(dltmp.len < 0 || dltmp.len > sizeof(moxaBuff)) ++ return -EINVAL; + + switch(cmd) + { +@@ -2822,8 +2824,6 @@ static int moxaload320b(int cardno, unsi + void __iomem *baseAddr; + int i; + +- if(len > sizeof(moxaBuff)) +- return -EINVAL; + if(copy_from_user(moxaBuff, tmp, len)) + return -EFAULT; + baseAddr = moxaBaseAddr[cardno]; +diff -urNp linux-2.6.10/drivers/block/scsi_ioctl.c linux-2.6.10-new/drivers/block/scsi_ioctl.c +--- linux-2.6.10/drivers/block/scsi_ioctl.c 2005-01-07 10:51:24 -0500 ++++ linux-2.6.10-new/drivers/block/scsi_ioctl.c 2005-01-07 10:51:33 -0500 +@@ -339,7 +339,8 @@ static int sg_scsi_ioctl(struct file *fi + struct gendisk *bd_disk, Scsi_Ioctl_Command __user *sic) + { + struct request *rq; +- int err, in_len, out_len, bytes, opcode, cmdlen; ++ unsigned int in_len, out_len, bytes, opcode, cmdlen; ++ int err; + char *buffer = NULL, sense[SCSI_SENSE_BUFFERSIZE]; + + /* +diff -urNp linux-2.6.10/include/linux/writeback.h linux-2.6.10-new/include/linux/writeback.h +--- linux-2.6.10/include/linux/writeback.h 2005-01-07 10:51:22 -0500 ++++ linux-2.6.10-new/include/linux/writeback.h 2005-01-07 10:51:33 -0500 +@@ -86,6 +86,7 @@ static inline void wait_on_inode(struct + int wakeup_bdflush(long nr_pages); + void laptop_io_completion(void); + void laptop_sync_completion(void); ++void throttle_vm_writeout(void); + + /* These are exported to sysctl. */ + extern int dirty_background_ratio; +diff -urNp linux-2.6.10/drivers/char/random.c linux-2.6.10-new/drivers/char/random.c +--- linux-2.6.10/drivers/char/random.c 2005-01-07 10:51:23 -0500 ++++ linux-2.6.10-new/drivers/char/random.c 2005-01-07 10:51:33 -0500 +@@ -1912,7 +1912,7 @@ static int poolsize_strategy(ctl_table * + void __user *oldval, size_t __user *oldlenp, + void __user *newval, size_t newlen, void **context) + { +- int len; ++ size_t len; + + sysctl_poolsize = random_state->poolinfo.POOLBYTES; + +diff -urNp linux-2.6.10/mm/mmap.c linux-2.6.10-new/mm/mmap.c +--- linux-2.6.10/mm/mmap.c 2004-12-24 22:35:00.000000000 +0100 ++++ linux-2.6.10-new/mm/mmap.c 2004-12-27 16:37:47.000000000 +0100 +@@ -1360,6 +1360,13 @@ int expand_stack(struct vm_area_struct * + vm_unacct_memory(grow); + return -ENOMEM; + } ++ if ((vma->vm_flags & VM_LOCKED) && !capable(CAP_IPC_LOCK) && ++ ((vma->vm_mm->locked_vm + grow) << PAGE_SHIFT) > ++ current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur) { ++ anon_vma_unlock(vma); ++ vm_unacct_memory(grow); ++ return -ENOMEM; ++ } + vma->vm_end = address; + vma->vm_mm->total_vm += grow; + if (vma->vm_flags & VM_LOCKED) +@@ -1422,6 +1429,13 @@ int expand_stack(struct vm_area_struct * + vm_unacct_memory(grow); + return -ENOMEM; + } ++ if ((vma->vm_flags & VM_LOCKED) && !capable(CAP_IPC_LOCK) && ++ ((vma->vm_mm->locked_vm + grow) << PAGE_SHIFT) > ++ current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur) { ++ anon_vma_unlock(vma); ++ vm_unacct_memory(grow); ++ return -ENOMEM; ++ } + vma->vm_start = address; + vma->vm_pgoff -= grow; + vma->vm_mm->total_vm += grow; +diff -urNp linux-2.6.10/mm/page-writeback.c linux-2.6.10-new/mm/page-writeback.c +--- linux-2.6.10/mm/page-writeback.c 2005-01-07 10:51:24 -0500 ++++ linux-2.6.10-new/mm/page-writeback.c 2005-01-07 10:51:33 -0500 +@@ -276,6 +276,28 @@ void balance_dirty_pages_ratelimited(str + } + EXPORT_SYMBOL(balance_dirty_pages_ratelimited); + ++void throttle_vm_writeout(void) ++{ ++ struct writeback_state wbs; ++ long background_thresh; ++ long dirty_thresh; ++ ++ for ( ; ; ) { ++ get_dirty_limits(&wbs, &background_thresh, &dirty_thresh); ++ ++ /* ++ * Boost the allowable dirty threshold a bit for page ++ * allocators so they don't get DoS'ed by heavy writers ++ */ ++ dirty_thresh += dirty_thresh / 10; /* wheeee... */ ++ ++ if (wbs.nr_unstable + wbs.nr_writeback <= dirty_thresh) ++ break; ++ blk_congestion_wait(WRITE, HZ/10); ++ } ++} ++ ++ + /* + * writeback at least _min_pages, and keep writing until the amount of dirty + * memory is less than the background threshold, or until we're all clean. +diff -urNp linux-2.6.10/mm/vmscan.c linux-2.6.10-new/mm/vmscan.c +--- linux-2.6.10/mm/vmscan.c 2005-01-07 10:51:24 -0500 ++++ linux-2.6.10-new/mm/vmscan.c 2005-01-07 10:51:33 -0500 +@@ -369,14 +369,14 @@ static int shrink_list(struct list_head + + BUG_ON(PageActive(page)); + +- if (PageWriteback(page)) +- goto keep_locked; +- + sc->nr_scanned++; + /* Double the slab pressure for mapped and swapcache pages */ + if (page_mapped(page) || PageSwapCache(page)) + sc->nr_scanned++; + ++ if (PageWriteback(page)) ++ goto keep_locked; ++ + referenced = page_referenced(page, 1, sc->priority <= 0); + /* In active use or really unfreeable? Activate it. */ + if (referenced && page_mapping_inuse(page)) +@@ -825,6 +825,8 @@ shrink_zone(struct zone *zone, struct sc + break; + } + } ++ ++ throttle_vm_writeout(); + } + + /* +diff -urNp linux-2.6.10/net/ipv4/netfilter/ip_conntrack_proto_tcp.c linux-2.6.10-new/net/ipv4/netfilter/ip_conntrack_proto_tcp.c +--- linux-2.6.10/net/ipv4/netfilter/ip_conntrack_proto_tcp.c 2005-01-07 10:51:24 -0500 ++++ linux-2.6.10-new/net/ipv4/netfilter/ip_conntrack_proto_tcp.c 2005-01-07 10:51:33 -0500 +@@ -906,7 +906,8 @@ static int tcp_packet(struct ip_conntrac + if (index == TCP_RST_SET + && ((test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status) + && conntrack->proto.tcp.last_index <= TCP_SYNACK_SET) +- || conntrack->proto.tcp.last_index == TCP_ACK_SET) ++ || (!test_bit(IPS_ASSURED_BIT, &conntrack->status) ++ && conntrack->proto.tcp.last_index == TCP_ACK_SET)) + && after(ntohl(th->ack_seq), + conntrack->proto.tcp.last_seq)) { + /* Ignore RST closing down invalid SYN or ACK diff --git a/sys-kernel/hppa-sources/files/NFS-XDR-security.patch b/sys-kernel/hppa-sources/files/NFS-XDR-security.patch deleted file mode 100644 index 9a336ab7876a..000000000000 --- a/sys-kernel/hppa-sources/files/NFS-XDR-security.patch +++ /dev/null @@ -1,48 +0,0 @@ -# This is a BitKeeper generated diff -Nru style patch. -# -# ChangeSet -# 2004/08/16 14:50:04-03:00 neilb@cse.unsw.edu.au -# [PATCH] Fixed possibly xdr parsing error if write size exceed 2^31 -# -# xdr_argsize_check needs to cope with the possibility that the -# pointer has wrapped and could be below buf->base. -# -# Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au> -# -# ### Diffstat output -# ./fs/nfsd/nfs3xdr.c | 2 +- -# ./include/linux/nfsd/xdr3.h | 2 +- -# 2 files changed, 2 insertions(+), 2 deletions(-) -# -# fs/nfsd/nfs3xdr.c -# 2004/08/14 00:23:06-03:00 neilb@cse.unsw.edu.au +1 -1 -# Fixed possibly xdr parsing error if write size exceed 2^31 -# -# include/linux/nfsd/xdr3.h -# 2004/08/15 20:48:43-03:00 neilb@cse.unsw.edu.au +1 -1 -# Fixed possibly xdr parsing error if write size exceed 2^31 -# -diff -Nru a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c ---- a/fs/nfsd/nfs3xdr.c 2004-09-06 11:20:28 -07:00 -+++ b/fs/nfsd/nfs3xdr.c 2004-09-06 11:20:28 -07:00 -@@ -273,7 +273,7 @@ - { - struct svc_buf *buf = &rqstp->rq_argbuf; - -- return p - buf->base <= buf->buflen; -+ return p >= buf->base && p <= buf->base + buf->buflen ; - } - - static inline int -diff -Nru a/include/linux/nfsd/xdr3.h b/include/linux/nfsd/xdr3.h ---- a/include/linux/nfsd/xdr3.h 2004-09-06 11:20:28 -07:00 -+++ b/include/linux/nfsd/xdr3.h 2004-09-06 11:20:28 -07:00 -@@ -41,7 +41,7 @@ - __u32 count; - int stable; - __u8 * data; -- int len; -+ __u32 len; - }; - - struct nfsd3_createargs { diff --git a/sys-kernel/hppa-sources/files/binfmt_elf-loader-security.patch b/sys-kernel/hppa-sources/files/binfmt_elf-loader-security.patch deleted file mode 100644 index 534e4c064a52..000000000000 --- a/sys-kernel/hppa-sources/files/binfmt_elf-loader-security.patch +++ /dev/null @@ -1,72 +0,0 @@ ---- linux-2.4.27/fs/binfmt_elf.c 2004-11-10 12:25:16 -08:00 -+++ linux-2.4.27-plasmaroo/fs/binfmt_elf.c 2004-11-10 12:25:16 -08:00 -@@ -335,9 +335,12 @@ - goto out; - - retval = kernel_read(interpreter,interp_elf_ex->e_phoff,(char *)elf_phdata,size); -- error = retval; -- if (retval < 0) -+ error = -EIO; -+ if (retval != size) { -+ if (retval < 0) -+ error = retval; - goto out_close; -+ } - - eppnt = elf_phdata; - for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) { -@@ -532,8 +535,11 @@ - goto out; - - retval = kernel_read(bprm->file, elf_ex.e_phoff, (char *) elf_phdata, size); -- if (retval < 0) -+ if (retval != size) { -+ if (retval >= 0) -+ retval = -EIO; - goto out_free_ph; -+ } - - files = current->files; /* Refcounted so ok */ - retval = unshare_files(); -@@ -580,8 +586,14 @@ - retval = kernel_read(bprm->file, elf_ppnt->p_offset, - elf_interpreter, - elf_ppnt->p_filesz); -- if (retval < 0) -+ if (retval != elf_ppnt->p_filesz) { -+ if (retval >= 0) -+ retval = -EIO; - goto out_free_interp; -+ } -+ /* make sure path is NULL terminated */ -+ elf_interpreter[elf_ppnt->p_filesz - 1] = '\0'; -+ - /* If the program interpreter is one of these two, - * then assume an iBCS2 image. Otherwise assume - * a native linux image. -@@ -616,8 +628,11 @@ - if (IS_ERR(interpreter)) - goto out_free_interp; - retval = kernel_read(interpreter, 0, bprm->buf, BINPRM_BUF_SIZE); -- if (retval < 0) -+ if (retval != BINPRM_BUF_SIZE) { -+ if (retval >= 0) -+ retval = -EIO; - goto out_free_dentry; -+ } - - /* Get the exec headers */ - loc->interp_ex = *((struct exec *) bprm->buf); -@@ -776,8 +791,10 @@ - } - - error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags); -- if (BAD_ADDR(error)) -- continue; -+ if (BAD_ADDR(error)) { -+ send_sig(SIGKILL, current, 0); -+ goto out_free_dentry; -+ } - - if (!load_addr_set) { - load_addr_set = 1; diff --git a/sys-kernel/hppa-sources/files/digest-hppa-sources-2.4.26_p6-r1 b/sys-kernel/hppa-sources/files/digest-hppa-sources-2.4.26_p6-r1 deleted file mode 100644 index 1783d6ae9683..000000000000 --- a/sys-kernel/hppa-sources/files/digest-hppa-sources-2.4.26_p6-r1 +++ /dev/null @@ -1,3 +0,0 @@ -MD5 88d7aefa03c92739cb70298a0b486e2c linux-2.4.26.tar.bz2 30772389 -MD5 889e7590ba57391259d832f5ef7fef8c patch-2.4.26-pa6.gz 724962 -MD5 010fe6b49e97365f12ce3f70376d5eb0 parisc-2.4.23-pa4-missing-ioctl-translations.diff 18091 diff --git a/sys-kernel/hppa-sources/files/digest-hppa-sources-2.4.26_p7 b/sys-kernel/hppa-sources/files/digest-hppa-sources-2.4.26_p7 deleted file mode 100644 index 9e79b49b2488..000000000000 --- a/sys-kernel/hppa-sources/files/digest-hppa-sources-2.4.26_p7 +++ /dev/null @@ -1,4 +0,0 @@ -MD5 88d7aefa03c92739cb70298a0b486e2c linux-2.4.26.tar.bz2 30772389 -MD5 993a9ea8c553f198ef62747bb7c9a7c4 patch-2.4.26-pa7.gz 725125 -MD5 010fe6b49e97365f12ce3f70376d5eb0 parisc-2.4.23-pa4-missing-ioctl-translations.diff 18091 -MD5 2758cec1dc37d4069a42fc7544599860 lasi-config-max-tag-queue-dep.patch 1455 diff --git a/sys-kernel/hppa-sources/files/digest-hppa-sources-2.4.26_p7-r1 b/sys-kernel/hppa-sources/files/digest-hppa-sources-2.4.26_p7-r1 deleted file mode 100644 index 1be356f1f4e4..000000000000 --- a/sys-kernel/hppa-sources/files/digest-hppa-sources-2.4.26_p7-r1 +++ /dev/null @@ -1,5 +0,0 @@ -MD5 88d7aefa03c92739cb70298a0b486e2c linux-2.4.26.tar.bz2 30772389 -MD5 993a9ea8c553f198ef62747bb7c9a7c4 patch-2.4.26-pa7.gz 725125 -MD5 010fe6b49e97365f12ce3f70376d5eb0 parisc-2.4.23-pa4-missing-ioctl-translations.diff 18091 -MD5 2758cec1dc37d4069a42fc7544599860 lasi-config-max-tag-queue-dep.patch 1455 -MD5 8f8f2412aacf9a01b5549bf2a9a3bff8 linux-2.4.26-CAN-2004-0415.patch 90145 diff --git a/sys-kernel/hppa-sources/files/digest-hppa-sources-2.4.27_p4 b/sys-kernel/hppa-sources/files/digest-hppa-sources-2.4.27_p4 deleted file mode 100644 index ed0632124e01..000000000000 --- a/sys-kernel/hppa-sources/files/digest-hppa-sources-2.4.27_p4 +++ /dev/null @@ -1,4 +0,0 @@ -MD5 59a2e6fde1d110e2ffa20351ac8b4d9e linux-2.4.27.tar.bz2 30898453 -MD5 e6ee93aafa687932abd2c09fca43d4c3 patch-2.4.27-pa4.gz 727846 -MD5 010fe6b49e97365f12ce3f70376d5eb0 parisc-2.4.23-pa4-missing-ioctl-translations.diff 18091 -MD5 2758cec1dc37d4069a42fc7544599860 lasi-config-max-tag-queue-dep.patch 1455 diff --git a/sys-kernel/hppa-sources/files/digest-hppa-sources-2.4.27_p4-r1 b/sys-kernel/hppa-sources/files/digest-hppa-sources-2.4.27_p4-r1 deleted file mode 100644 index ed0632124e01..000000000000 --- a/sys-kernel/hppa-sources/files/digest-hppa-sources-2.4.27_p4-r1 +++ /dev/null @@ -1,4 +0,0 @@ -MD5 59a2e6fde1d110e2ffa20351ac8b4d9e linux-2.4.27.tar.bz2 30898453 -MD5 e6ee93aafa687932abd2c09fca43d4c3 patch-2.4.27-pa4.gz 727846 -MD5 010fe6b49e97365f12ce3f70376d5eb0 parisc-2.4.23-pa4-missing-ioctl-translations.diff 18091 -MD5 2758cec1dc37d4069a42fc7544599860 lasi-config-max-tag-queue-dep.patch 1455 diff --git a/sys-kernel/hppa-sources/files/digest-hppa-sources-2.4.27_p4-r2 b/sys-kernel/hppa-sources/files/digest-hppa-sources-2.4.27_p4-r2 deleted file mode 100644 index ed0632124e01..000000000000 --- a/sys-kernel/hppa-sources/files/digest-hppa-sources-2.4.27_p4-r2 +++ /dev/null @@ -1,4 +0,0 @@ -MD5 59a2e6fde1d110e2ffa20351ac8b4d9e linux-2.4.27.tar.bz2 30898453 -MD5 e6ee93aafa687932abd2c09fca43d4c3 patch-2.4.27-pa4.gz 727846 -MD5 010fe6b49e97365f12ce3f70376d5eb0 parisc-2.4.23-pa4-missing-ioctl-translations.diff 18091 -MD5 2758cec1dc37d4069a42fc7544599860 lasi-config-max-tag-queue-dep.patch 1455 diff --git a/sys-kernel/hppa-sources/files/digest-hppa-sources-2.6.10_p10 b/sys-kernel/hppa-sources/files/digest-hppa-sources-2.6.10_p10 new file mode 100644 index 000000000000..b1567b9fb7e1 --- /dev/null +++ b/sys-kernel/hppa-sources/files/digest-hppa-sources-2.6.10_p10 @@ -0,0 +1,2 @@ +MD5 cffcd2919d9c8ef793ce1ac07a440eda linux-2.6.10.tar.bz2 36533484 +MD5 ac56c33ed522d0d3f7ed72faaaf19e34 patch-2.6.10-pa10.gz 189423 diff --git a/sys-kernel/hppa-sources/files/security-proc-cmdline.patch b/sys-kernel/hppa-sources/files/security-proc-cmdline.patch deleted file mode 100644 index bb80884c394e..000000000000 --- a/sys-kernel/hppa-sources/files/security-proc-cmdline.patch +++ /dev/null @@ -1,24 +0,0 @@ - -From: Roger Luethi <rl@hellgate.ch> - -If you win the race with a starting process, you can read its environment. - -Signed-off-by: Andrew Morton <akpm@osdl.org> ---- - - 25-akpm/fs/proc/base.c | 2 ++ - 1 files changed, 2 insertions(+) - -diff -puN fs/proc/base.c~proc_pid_cmdline-race-fix fs/proc/base.c ---- 25/fs/proc/base.c~proc_pid_cmdline-race-fix 2004-08-05 11:28:21.915442360 -0700 -+++ 25-akpm/fs/proc/base.c 2004-08-05 11:28:21.919441752 -0700 -@@ -340,6 +340,8 @@ static int proc_pid_cmdline(struct task_ - struct mm_struct *mm = get_task_mm(task); - if (!mm) - goto out; -+ if (!mm->arg_end) -+ goto out; /* Shh! No looking before we're done */ - - len = mm->arg_end - mm->arg_start; - -_ diff --git a/sys-kernel/hppa-sources/hppa-sources-2.6.10_p10.ebuild b/sys-kernel/hppa-sources/hppa-sources-2.6.10_p10.ebuild new file mode 100644 index 000000000000..99f55c1a5902 --- /dev/null +++ b/sys-kernel/hppa-sources/hppa-sources-2.6.10_p10.ebuild @@ -0,0 +1,17 @@ +# Copyright 1999-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-x86/sys-kernel/hppa-sources/hppa-sources-2.6.10_p10.ebuild,v 1.1 2005/01/10 17:44:18 gmsoft Exp $ + +ETYPE="sources" +inherit kernel-2 +K_NOUSENAME=true +K_NOSETEXTRAVERSION=true + +detect_version + +DESCRIPTION="Full sources for the Linux kernel with patch for hppa" +PATCH_LEVEL="${PV/${OKV}_p/}" +SRC_URI="${KERNEL_URI} http://ftp.parisc-linux.org/cvs/linux-2.6/patch-${OKV}-pa${PATCH_LEVEL}.gz" +UNIPATCH_LIST="${DISTDIR}/patch-${OKV}-pa${PATCH_LEVEL}.gz ${FILESDIR}/CAN-2004-1056.patch ${FILESDIR}/CAN-2004-1235.patch ${FILESDIR}/LKA-20050107.patch" +HOMEPAGE="http://www.kernel.org/ http://www.gentoo.org/ http://parisc-linux.org" +KEYWORDS="hppa -*" |