![]() | |||||||||||||
Messages in this thread Patch in this message |
I'd appreciate feedback on these - especially on the Alpha platform so I can fix any further problems they may have caused someone and submit this on to Linus for 2.0.34 o sysctl oops o ptrace oops o signal oops o i_count exploit o autofw help text o LDT memory leak o Warning in cdrom.c o Warning in eth16i.c o Remove experimental tag fro DLCI/SDLA support o SMC ultra32 module fix o eql warning o new_tunnel warning o kerneld/ifconfig exploit o ignore source quench and drive by the dropped frames (current "good practice") [Items marked "warning" indicate compiler warnings that turned out to be code that is 'wrong' from a perfect compiler correctness viewpoint but worked correctly before] [Items marked "oops" fix non fatal Oops events] [Items marked "exploit" fix something that allowed you to either crash the machine as any user or to get root] -------------------------------------------------------------------------------------------------- diff --unified --new-file --recursive --exclude-from exclude linux.van2033/Documentation/Configure.help linux/Documentation/Configure.help --- linux.van2033/Documentation/Configure.help Sun Jan 18 14:15:57 1998 +++ linux/Documentation/Configure.help Sun Jan 18 14:26:43 1998 @@ -976,16 +976,13 @@ IP always defragment. If you want this, say Y. -IP: ipautofw masquerade support -CONFIG_IP_MASQUERADE_IPAUTOFW (Experimental) - ipautofw is a program by Richard Lynch allowing additional - support for masquerading protocols which do not (as yet) - have additional protocol helpers. - Information and source for ipautofw is available from - ftp://ftp.netis.com/pub/members/rlynch/ - The ipautofw code is still under development and so is currently - marked EXPERIMENTAL. - If you want this, say Y. +IP: ipautofw masquerading (EXPERIMENTAL) +CONFIG_IP_MASQUERADE_IPAUTOFW + + Richard Lynch's ipautofw allows masquerading to work with protocols + which do not (as yet) have specific protocol helpers. Its source, and + other information, is available at + ftp://ftp.netis.com/pub/members/rlynch/. IP: ICMP masquerading CONFIG_IP_MASQUERADE_ICMP diff --unified --new-file --recursive --exclude-from exclude linux.van2033/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c --- linux.van2033/arch/i386/kernel/process.c Sun Jan 18 14:15:47 1998 +++ linux/arch/i386/kernel/process.c Sun Jan 18 14:21:45 1998 @@ -421,8 +421,9 @@ int i; if (current->ldt) { - free_page((unsigned long) current->ldt); + void * ldt = current->ldt; current->ldt = NULL; + vfree(ldt); for (i=1 ; i<NR_TASKS ; i++) { if (task[i] == current) { set_ldt_desc(gdt+(i<<1)+ diff --unified --new-file --recursive --exclude-from exclude linux.van2033/arch/i386/kernel/ptrace.c linux/arch/i386/kernel/ptrace.c --- linux.van2033/arch/i386/kernel/ptrace.c Sun Jan 18 14:15:47 1998 +++ linux/arch/i386/kernel/ptrace.c Sun Jan 18 14:20:09 1998 @@ -416,6 +416,60 @@ return tmp; } +void safe_wake_up_process(struct task_struct * p) +{ + struct desc_struct * d; + unsigned long limit; + + void check(int index, int mask, int value) { + unsigned long selector, limit; + + if (!p) return; + + selector = get_stack_long(p, sizeof(long)*index - MAGICNUMBER); + if (selector & 4) { + d = p->ldt; + if (d) limit = get_limit(p->tss.ldt); else limit = 0; + } else { + d = gdt; + limit = 8 * 8; + } + + if ((selector & 0xFFF8) >= limit) { + d = NULL; + force_sig(SIGSEGV, p); p = NULL; + } else { + d += selector >> 3; + if ((d->b & mask) != value || + (d->b >> 13) < (selector & 3)) { + force_sig(SIGSEGV, p); p = NULL; + } + } + } + + check(DS, 0x9800, 0x9000); /* Allow present data segments only */ + check(ES, 0x9800, 0x9000); + check(FS, 0x9800, 0x9000); + check(GS, 0x9800, 0x9000); + check(SS, 0x9A00, 0x9200); /* Stack segment should not be read-only */ + check(CS, 0x9800, 0x9800); /* Allow present code segments only */ + + if (!p) return; + + if (d) { + limit = (d->a & 0xFFFF) | (d->b & 0xF0000); + if (d->b & 0x800000) { + limit <<= 12; limit |= 0xFFF; + } + + if (get_stack_long(p, sizeof(long)*EIP - MAGICNUMBER) > limit) { + force_sig(SIGSEGV, p); return; + } + } + + wake_up_process(p); +} + asmlinkage int sys_ptrace(long request, long pid, long addr, long data) { struct task_struct *child; @@ -609,7 +663,7 @@ else child->flags &= ~PF_TRACESYS; child->exit_code = data; - wake_up_process(child); + safe_wake_up_process(child); /* make sure the single step bit is not set. */ tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) & ~TRAP_FLAG; put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp); @@ -642,8 +696,8 @@ child->flags &= ~PF_TRACESYS; tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) | TRAP_FLAG; put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp); - wake_up_process(child); child->exit_code = data; + safe_wake_up_process(child); /* give it a chance to run. */ return 0; } @@ -654,8 +708,8 @@ if ((unsigned long) data > NSIG) return -EIO; child->flags &= ~(PF_PTRACED|PF_TRACESYS); - wake_up_process(child); child->exit_code = data; + safe_wake_up_process(child); REMOVE_LINKS(child); child->p_pptr = child->p_opptr; SET_LINKS(child); diff --unified --new-file --recursive --exclude-from exclude linux.van2033/arch/i386/kernel/signal.c linux/arch/i386/kernel/signal.c --- linux.van2033/arch/i386/kernel/signal.c Sun Jan 18 14:14:04 1998 +++ linux/arch/i386/kernel/signal.c Sun Jan 18 14:20:09 1998 @@ -15,6 +15,7 @@ #include <linux/ptrace.h> #include <linux/unistd.h> +#include <asm/system.h> #include <asm/segment.h> #define _S(nr) (1<<((nr)-1)) @@ -80,13 +81,40 @@ asmlinkage int sys_sigreturn(unsigned long __unused) { #define COPY(x) regs->x = context.x +#define CHECK_DATA(x, mask, value) \ +__asm__("larw %0,%%ax\n\t" \ + "jnz asm_badframe\n\t" \ + "andl $" mask ",%%eax\n\t" \ + "cmpl $" value ",%%eax\n\t" \ + "jne asm_badframe" \ + : \ + : "g" (context.x) \ + : "ax", "cc"); +#define CHECK_CODE(x, y) \ +__asm__("larw %0,%%ax\n\t" \ + "jnz asm_badframe\n\t" \ + "andl $0x9800,%%eax\n\t" \ + "cmpl $0x9800,%%eax\n\t" /* Allow present code segments only */ \ + "jne asm_badframe\n\t" \ + "lsll %0,%%eax\n\t" \ + "cmp %1,%%eax\n\t" /* Check context.eip against the segment limit */ \ + "jb asm_badframe" \ + : \ + : "g" (context.x), "g" (context.y) \ + : "ax", "cc"); #define COPY_SEG(x) \ +CHECK_DATA(x, "0x9800", "0x9000") /* Allow present data segments only */ \ if ( (context.x & 0xfffc) /* not a NULL selectors */ \ && (context.x & 0x4) != 0x4 /* not a LDT selector */ \ && (context.x & 3) != 3 /* not a RPL3 GDT selector */ \ ) goto badframe; COPY(x); -#define COPY_SEG_STRICT(x) \ +#define COPY_STACK(x) \ +CHECK_DATA(x, "0x9A00", "0x9200") /* Stack segment should not be read-only */ \ if (!(context.x & 0xfffc) || (context.x & 3) != 3) goto badframe; COPY(x); +#define COPY_CODE(x, y) \ +CHECK_CODE(x, y) \ +if (!(context.x & 0xfffc) || (context.x & 3) != 3) goto badframe; \ +COPY(x); COPY(y); struct sigcontext_struct context; struct pt_regs * regs; @@ -99,9 +127,8 @@ COPY_SEG(es); COPY_SEG(fs); COPY_SEG(gs); - COPY_SEG_STRICT(ss); - COPY_SEG_STRICT(cs); - COPY(eip); + COPY_STACK(ss); + COPY_CODE(cs, eip); COPY(ecx); COPY(edx); COPY(ebx); COPY(esp); COPY(ebp); @@ -117,6 +144,11 @@ } return context.eax; badframe: + do_exit(SIGSEGV); +} + +void asm_badframe(void) +{ do_exit(SIGSEGV); } diff --unified --new-file --recursive --exclude-from exclude linux.van2033/drivers/block/md.c linux/drivers/block/md.c --- linux.van2033/drivers/block/md.c Sat Jun 29 22:04:00 1996 +++ linux/drivers/block/md.c Sun Jan 18 14:42:10 1998 @@ -202,7 +202,7 @@ if (inode->i_count>1 || md_dev[minor].busy>1) /* ioctl : one open channel */ { - printk ("STOP_MD md%x failed : i_count=%d, busy=%d\n", minor, inode->i_count, md_dev[minor].busy); + printk ("STOP_MD md%x failed : i_count=%ld, busy=%d\n", minor, inode->i_count, md_dev[minor].busy); return -EBUSY; } diff --unified --new-file --recursive --exclude-from exclude linux.van2033/drivers/cdrom/cdrom.c linux/drivers/cdrom/cdrom.c --- linux.van2033/drivers/cdrom/cdrom.c Sat Aug 17 19:19:26 1996 +++ linux/drivers/cdrom/cdrom.c Sun Jan 18 15:40:29 1998 @@ -97,7 +97,9 @@ /* We need our own cdrom error types! This is a temporary solution. */ +#ifndef ENOMEDIUM #define ENOMEDIUM EAGAIN /* no medium in removable device */ +#endif /* We use the open-option O_NONBLOCK to indicate that the * purpose of opening is only for subsequent ioctl() calls; no device diff --unified --new-file --recursive --exclude-from exclude linux.van2033/drivers/net/Config.in linux/drivers/net/Config.in --- linux.van2033/drivers/net/Config.in Sun Jan 18 14:14:19 1998 +++ linux/drivers/net/Config.in Sun Jan 18 14:21:07 1998 @@ -3,13 +3,11 @@ # tristate 'Dummy net driver support' CONFIG_DUMMY tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER -if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'Frame relay DLCI support (EXPERIMENTAL)' CONFIG_DLCI - if [ "$CONFIG_DLCI" = "y" -o "$CONFIG_DLCI" = "m" ]; then - int ' Max open DLCI' CONFIG_DLCI_COUNT 24 - int ' Max DLCI per device' CONFIG_DLCI_MAX 8 - dep_tristate ' SDLA (Sangoma S502/S508) support' CONFIG_SDLA $CONFIG_DLCI - fi +tristate 'Frame relay DLCI support' CONFIG_DLCI +if [ "$CONFIG_DLCI" = "y" -o "$CONFIG_DLCI" = "m" ]; then + int ' Max open DLCI' CONFIG_DLCI_COUNT 24 + int ' Max DLCI per device' CONFIG_DLCI_MAX 8 + dep_tristate ' SDLA (Sangoma S502/S508) support' CONFIG_SDLA $CONFIG_DLCI fi tristate 'PLIP (parallel port) support' CONFIG_PLIP tristate 'PPP (point-to-point) support' CONFIG_PPP diff --unified --new-file --recursive --exclude-from exclude linux.van2033/drivers/net/Makefile linux/drivers/net/Makefile --- linux.van2033/drivers/net/Makefile Sun Jan 18 14:14:19 1998 +++ linux/drivers/net/Makefile Sun Jan 18 14:18:32 1998 @@ -148,7 +148,7 @@ L_OBJS += smc-ultra32.o CONFIG_8390_BUILTIN = y else - ifeq ($(CONFIG_ULTRA),m) + ifeq ($(CONFIG_ULTRA32),m) CONFIG_8390_MODULE = y M_OBJS += smc-ultra32.o endif diff --unified --new-file --recursive --exclude-from exclude linux.van2033/drivers/net/eql.c linux/drivers/net/eql.c --- linux.van2033/drivers/net/eql.c Sun Jan 18 14:14:21 1998 +++ linux/drivers/net/eql.c Sun Jan 18 15:39:36 1998 @@ -375,7 +375,6 @@ equalizer_t *eql = (equalizer_t *) dev->priv; struct device *slave_dev = 0; slave_t *slave; - struct sk_buff *skb2; if (skb == NULL) return 0; diff --unified --new-file --recursive --exclude-from exclude linux.van2033/drivers/net/eth16i.c linux/drivers/net/eth16i.c --- linux.van2033/drivers/net/eth16i.c Sun Jan 18 14:14:21 1998 +++ linux/drivers/net/eth16i.c Sun Jan 18 15:43:38 1998 @@ -332,7 +332,7 @@ static int eth16i_tx(struct sk_buff *skb, struct device *dev); static void eth16i_rx(struct device *dev); static void eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void eth16i_multicast(struct device *dev, int num_addrs, void *addrs); +static void eth16i_multicast(struct device *dev); static void eth16i_select_regbank(unsigned char regbank, short ioaddr); static void eth16i_initialize(struct device *dev); static struct enet_statistics *eth16i_get_stats(struct device *dev); @@ -1152,7 +1152,7 @@ return; } -static void eth16i_multicast(struct device *dev, int num_addrs, void *addrs) +static void eth16i_multicast(struct device *dev) { short ioaddr = dev->base_addr; diff --unified --new-file --recursive --exclude-from exclude linux.van2033/drivers/net/new_tunnel.c linux/drivers/net/new_tunnel.c --- linux.van2033/drivers/net/new_tunnel.c Sun Jan 18 14:14:23 1998 +++ linux/drivers/net/new_tunnel.c Sun Jan 18 15:38:25 1998 @@ -267,7 +267,7 @@ /* Tack on our header */ new_skb->h.iph = (struct iphdr *) skb_push(new_skb, tunnel_hlen); - new_skb->mac.raw = new_skb->ip_hdr; + new_skb->mac.raw = (void *)new_skb->ip_hdr; /* Free the old packet, we no longer need it */ dev_kfree_skb(skb, FREE_WRITE); diff --unified --new-file --recursive --exclude-from exclude linux.van2033/fs/ext/freelists.c linux/fs/ext/freelists.c --- linux.van2033/fs/ext/freelists.c Sat Nov 30 10:21:19 1996 +++ linux/fs/ext/freelists.c Sun Jan 18 15:41:13 1998 @@ -188,7 +188,7 @@ return; } if (inode->i_count != 1) { - printk("free_inode: inode has count=%d\n",inode->i_count); + printk("free_inode: inode has count=%ld\n",inode->i_count); return; } if (inode->i_nlink) { diff --unified --new-file --recursive --exclude-from exclude linux.van2033/fs/ext2/ialloc.c linux/fs/ext2/ialloc.c --- linux.van2033/fs/ext2/ialloc.c Sun Jan 18 14:14:37 1998 +++ linux/fs/ext2/ialloc.c Sun Jan 18 14:58:24 1998 @@ -196,7 +196,7 @@ return; } if (inode->i_count > 1) { - printk ("ext2_free_inode: inode has count=%d\n", + printk ("ext2_free_inode: inode has count=%ld\n", inode->i_count); return; } diff --unified --new-file --recursive --exclude-from exclude linux.van2033/fs/minix/bitmap.c linux/fs/minix/bitmap.c --- linux.van2033/fs/minix/bitmap.c Sat Nov 30 10:21:20 1996 +++ linux/fs/minix/bitmap.c Sun Jan 18 15:40:51 1998 @@ -187,7 +187,7 @@ return; } if (inode->i_count != 1) { - printk("free_inode: inode has count=%d\n",inode->i_count); + printk("free_inode: inode has count=%ld\n",inode->i_count); return; } if (inode->i_nlink) { diff --unified --new-file --recursive --exclude-from exclude linux.van2033/fs/ncpfs/inode.c linux/fs/ncpfs/inode.c --- linux.van2033/fs/ncpfs/inode.c Sun Jan 18 14:14:39 1998 +++ linux/fs/ncpfs/inode.c Sun Jan 18 15:42:03 1998 @@ -145,7 +145,7 @@ lock_super(sb); if (inode->i_count > 1) { -printk("ncp_put_inode: inode in use device %s, inode %ld, count=%d\n", +printk("ncp_put_inode: inode in use device %s, inode %ld, count=%ld\n", kdevname(inode->i_dev), inode->i_ino, inode->i_count); goto unlock; } diff --unified --new-file --recursive --exclude-from exclude linux.van2033/fs/smbfs/inode.c linux/fs/smbfs/inode.c --- linux.van2033/fs/smbfs/inode.c Sun Jan 18 14:14:39 1998 +++ linux/fs/smbfs/inode.c Sun Jan 18 15:41:51 1998 @@ -99,7 +99,7 @@ __u32 mtime = inode->i_mtime; if (inode->i_count > 1) { - printk("smb_put_inode: in use device %s, inode %ld count=%d\n", + printk("smb_put_inode: in use device %s, inode %ld count=%ld\n", kdevname(inode->i_dev), inode->i_ino, inode->i_count); return; } diff --unified --new-file --recursive --exclude-from exclude linux.van2033/fs/sysv/ialloc.c linux/fs/sysv/ialloc.c --- linux.van2033/fs/sysv/ialloc.c Sat Nov 30 10:21:21 1996 +++ linux/fs/sysv/ialloc.c Sun Jan 18 15:41:35 1998 @@ -63,7 +63,7 @@ return; } if (inode->i_count != 1) { - printk("sysv_free_inode: inode has count=%d\n", inode->i_count); + printk("sysv_free_inode: inode has count=%ld\n", inode->i_count); return; } if (inode->i_nlink) { diff --unified --new-file --recursive --exclude-from exclude linux.van2033/fs/ufs/ufs_inode.c linux/fs/ufs/ufs_inode.c --- linux.van2033/fs/ufs/ufs_inode.c Sat Nov 30 10:21:22 1996 +++ linux/fs/ufs/ufs_inode.c Sun Jan 18 15:42:20 1998 @@ -23,7 +23,7 @@ void ufs_print_inode(struct inode * inode) { - printk("ino %lu mode 0%6.6o lk %d uid %d gid %d sz %lu blks %lu cnt %u\n", + printk("ino %lu mode 0%6.6o lk %d uid %d gid %d sz %lu blks %lu cnt %lu\n", inode->i_ino, inode->i_mode, inode->i_nlink, inode->i_uid, inode->i_gid, inode->i_size, inode->i_blocks, inode->i_count); printk(" db <0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x>\n", inode->u.ufs_i.ui_db[0], inode->u.ufs_i.ui_db[1], diff --unified --new-file --recursive --exclude-from exclude linux.van2033/include/linux/fs.h linux/include/linux/fs.h --- linux.van2033/include/linux/fs.h Sun Jan 18 14:15:52 1998 +++ linux/include/linux/fs.h Sun Jan 18 14:40:25 1998 @@ -304,7 +304,7 @@ struct inode *i_hash_next, *i_hash_prev; struct inode *i_bound_to, *i_bound_by; struct inode *i_mount; - unsigned short i_count; + unsigned long i_count; /* needs to be > (address_space * tasks)>>pagebits */ unsigned short i_flags; unsigned char i_lock; unsigned char i_dirt; diff --unified --new-file --recursive --exclude-from exclude linux.van2033/kernel/sysctl.c linux/kernel/sysctl.c --- linux.van2033/kernel/sysctl.c Sun Jan 18 14:14:45 1998 +++ linux/kernel/sysctl.c Sun Jan 18 14:20:09 1998 @@ -180,7 +180,7 @@ struct ctl_table_header *tmp; void *context; - if (nlen == 0 || nlen >= CTL_MAXNAME) + if (nlen <= 0 || nlen >= CTL_MAXNAME) return -ENOTDIR; error = verify_area(VERIFY_READ,name,nlen*sizeof(int)); diff --unified --new-file --recursive --exclude-from exclude linux.van2033/net/core/dev.c linux/net/core/dev.c --- linux.van2033/net/core/dev.c Sun Jan 18 14:14:47 1998 +++ linux/net/core/dev.c Sun Jan 18 14:23:47 1998 @@ -225,7 +225,7 @@ extern __inline__ void dev_load(const char *name) { - if(!dev_get(name)) { + if(!dev_get(name) && suser()) { #ifdef CONFIG_NET_ALIAS const char *sptr; diff --unified --new-file --recursive --exclude-from exclude linux.van2033/net/ipv4/Config.in linux/net/ipv4/Config.in --- linux.van2033/net/ipv4/Config.in Sun Jan 18 14:14:47 1998 +++ linux/net/ipv4/Config.in Sun Jan 18 14:26:43 1998 @@ -15,7 +15,7 @@ if [ "$CONFIG_IP_MASQUERADE" != "n" ]; then comment 'Protocol-specific masquerading support will be built as modules.' if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool 'IP: ipautofw masq support' CONFIG_IP_MASQUERADE_IPAUTOFW + bool 'IP: ipautofw masquerading (EXPERIMENTAL)' CONFIG_IP_MASQUERADE_IPAUTOFW fi bool 'IP: ICMP masquerading' CONFIG_IP_MASQUERADE_ICMP fi diff --unified --new-file --recursive --exclude-from exclude linux.van2033/net/ipv4/tcp.c linux/net/ipv4/tcp.c --- linux.van2033/net/ipv4/tcp.c Sun Jan 18 14:14:49 1998 +++ linux/net/ipv4/tcp.c Sun Jan 18 15:05:48 1998 @@ -740,16 +740,8 @@ if (type == ICMP_SOURCE_QUENCH) { - /* - * FIXME: - * Follow BSD for now and just reduce cong_window to 1 again. - * It is possible that we just want to reduce the - * window by 1/2, or that we want to reduce ssthresh by 1/2 - * here as well. - */ - sk->cong_window = 1; - sk->cong_count = 0; - sk->high_seq = sk->sent_seq; + /* Current practice says these frames are bad, plus the drops + will account right anyway. If we act on this we stall doubly */ return; } | ||||||||||||
| Last update: 2005-03-22 12:41 [from the cache] ©2003-2008 | |||||||||||||