diff --git a/Makefile b/Makefile index e44ff6b..d3312be 100644 --- a/Makefile +++ b/Makefile @@ -93,13 +93,14 @@ CPPFLAGS := -D__KERNEL__ -I$(HPATH) CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \ -fno-strict-aliasing -fno-common -CFLAGS += -fno-builtin-sprintf +CFLAGS += -fno-builtin-strpbrk -fno-builtin-sprintf ifndef CONFIG_FRAME_POINTER CFLAGS += -fomit-frame-pointer endif AFLAGS := -D__ASSEMBLY__ $(CPPFLAGS) check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi) +if_gcc4 = $(shell if echo __GNUC__ | $(CC) -E -xc - | grep -q '^4$$' > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi) # disable pointer signedness warnings in gcc 4.0 CFLAGS += $(call check_gcc,-Wno-pointer-sign,) diff --git a/arch/i386/Makefile b/arch/i386/Makefile index 8f93efd..8ba6bd0 100644 --- a/arch/i386/Makefile +++ b/arch/i386/Makefile @@ -92,9 +92,9 @@ ifdef CONFIG_MVIAC3_2 CFLAGS += $(call check_gcc,-march=c3-2,-march=i686) endif -# Disable unit-at-a-time mode, it makes gcc use a lot more stack -# due to the lack of sharing of stacklots. -CFLAGS += $(call check_gcc,-fno-unit-at-a-time,) +# Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use +# a lot more stack due to the lack of sharing of stacklots. +CFLAGS += $(call if_gcc4,,$(call check_gcc,-fno-unit-at-a-time,)) HEAD := arch/i386/kernel/head.o arch/i386/kernel/init_task.o diff --git a/drivers/char/wdt83627.c b/drivers/char/wdt83627.c index 217002a..a69b903 100644 --- a/drivers/char/wdt83627.c +++ b/drivers/char/wdt83627.c @@ -80,36 +80,6 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" _ /* Non standard proc bits, added by request, wanted some feedback */ -static int wdt_readproc(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - int len; - unsigned char remaining; - unsigned char fired; - spin_lock(&io_lock); - w83627hf_select_wd_register(); - outb_p(0xF6, WDT_EFIR);/* get current timer val */ - remaining=inb_p(WDT_EFDR); - outb_p(0xF7, WDT_EFIR); - fired=inb_p(WDT_EFDR); - /* clear that bit (bit 4) */ - outb_p(fired&(~0x10),WDT_EFDR); - w83627hf_unselect_wd_register(); - spin_unlock(&io_lock); - fired=(fired&0x10)!=0; - len=snprintf(page,PAGE_SIZE, - "W83627HF WDT\n" - "active=%d\n" - "iobase=%04X\n" - "nowayout=%d\n" - "timeout=%d\n" - "remaining=%d\n" - "fired=%d\n", - wdt_is_open,wdt_io,nowayout,timeout,remaining,fired); - *eof=1; - return len; -} - static void w83627hf_select_wd_register(void) { @@ -147,6 +117,36 @@ w83627hf_init(void) w83627hf_unselect_wd_register(); } +static int wdt_readproc(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + int len; + unsigned char remaining; + unsigned char fired; + spin_lock(&io_lock); + w83627hf_select_wd_register(); + outb_p(0xF6, WDT_EFIR);/* get current timer val */ + remaining=inb_p(WDT_EFDR); + outb_p(0xF7, WDT_EFIR); + fired=inb_p(WDT_EFDR); + /* clear that bit (bit 4) */ + outb_p(fired&(~0x10),WDT_EFDR); + w83627hf_unselect_wd_register(); + spin_unlock(&io_lock); + fired=(fired&0x10)!=0; + len=snprintf(page,PAGE_SIZE, + "W83627HF WDT\n" + "active=%d\n" + "iobase=%04X\n" + "nowayout=%d\n" + "timeout=%d\n" + "remaining=%d\n" + "fired=%d\n", + wdt_is_open,wdt_io,nowayout,timeout,remaining,fired); + *eof=1; + return len; +} + static void wdt_ctrl(int timeout) { @@ -347,7 +347,7 @@ static struct notifier_block wdt_notifier = { static int __init wdt_init(void) { - int ret; + int ret = -EBUSY; spin_lock_init(&io_lock); diff --git a/drivers/md/lvm.c b/drivers/md/lvm.c index e84b560..f5e200d 100644 --- a/drivers/md/lvm.c +++ b/drivers/md/lvm.c @@ -394,7 +394,7 @@ static char pv_name[NAME_LEN]; /* static char rootvg[NAME_LEN] = { 0, }; */ static int lock = 0; static int _lock_open_count = 0; -static uint vg_count = 0; +uint vg_count = 0; static long lvm_chr_open_count = 0; static DECLARE_WAIT_QUEUE_HEAD(lvm_wait); diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 081e506..cb93941 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -1829,6 +1829,11 @@ static int __devinit b44_init_one(struct pci_dev *pdev, pci_save_state(bp->pdev, bp->pci_cfg_state); + /* Chip reset provides power to the b44 MAC & PCI cores, which + * is necessary for MAC register access. + */ + b44_chip_reset(bp); + printk(KERN_INFO "%s: Broadcom 4400 10/100BaseT Ethernet ", dev->name); for (i = 0; i < 6; i++) printk("%2.2x%c", dev->dev_addr[i], diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c index 5cdd2f6..eef869d 100644 --- a/drivers/scsi/fdomain.c +++ b/drivers/scsi/fdomain.c @@ -561,7 +561,8 @@ static void print_banner( struct Scsi_Host *shpnt ) printk( "\n" ); } -static int __init fdomain_setup( char *str ) +/* no __init, may be called from fdomain_stubs.c */ +int fdomain_setup( char *str ) { int ints[4]; diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c index 04fbe03..2998e3b 100644 --- a/drivers/scsi/pcmcia/fdomain_stub.c +++ b/drivers/scsi/pcmcia/fdomain_stub.c @@ -85,7 +85,7 @@ typedef struct scsi_info_t { dev_node_t node[8]; } scsi_info_t; -extern void fdomain_setup(char *str, int *ints); +extern int fdomain_setup(char *str); static void fdomain_release(u_long arg); static int fdomain_event(event_t event, int priority, @@ -253,7 +253,7 @@ static void fdomain_config(dev_link_t *link) ints[1] = link->io.BasePort1; ints[2] = link->irq.AssignedIRQ; sprintf(str, "%d,%d", link->io.BasePort1, link->irq.AssignedIRQ); - fdomain_setup(str, ints); + fdomain_setup(str); scsi_register_module(MODULE_SCSI_HA, &driver_template); diff --git a/include/linux/mm.h b/include/linux/mm.h index c9ad6d7..a9bafcb 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -117,6 +117,7 @@ struct vm_area_struct { /* read ahead limits */ extern int vm_min_readahead; extern int vm_max_readahead; +extern unsigned long mmap_min_addr; /* * mapping from the currently active vm_flags protection bits (the @@ -652,6 +653,11 @@ static inline int expand_stack(struct vm_area_struct * vma, unsigned long addres * page_table_lock lock to serialize against concurrent expand_stacks. */ address &= PAGE_MASK; + + /* ensure a non-privileged process is not trying to mmap lower pages */ + if (address < mmap_min_addr && !capable(CAP_SYS_RAWIO)) + return -EPERM; + spin_lock(&vma->vm_mm->page_table_lock); /* already expanded while we were spinning? */ diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 23c7ae4..34a1f13 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -159,6 +159,7 @@ enum VM_LAPTOP_MODE=21, /* kernel in laptop flush mode */ VM_BLOCK_DUMP=22, /* dump fs activity to log */ VM_ANON_LRU=23, /* immediatly insert anon pages in the vm page lru */ + VM_MMAP_MIN_ADDR=24, /* prevent mapping of low addresses by mmap() */ }; diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 3d54347..d36c362 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -317,6 +317,8 @@ static ctl_table vm_table[] = { &laptop_mode, sizeof(int), 0644, NULL, &proc_dointvec}, {VM_BLOCK_DUMP, "block_dump", &block_dump, sizeof(int), 0644, NULL, &proc_dointvec}, + {VM_MMAP_MIN_ADDR, "mmap_min_addr", + &mmap_min_addr, sizeof(unsigned long), 0644, NULL, &proc_doulongvec_minmax}, {0} }; diff --git a/mm/mmap.c b/mm/mmap.c index dc296f3..d35ff3e 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -46,6 +46,8 @@ pgprot_t protection_map[16] = { }; int sysctl_overcommit_memory; +unsigned long mmap_min_addr; /* defaults to 0 = no protection */ + int max_map_count = DEFAULT_MAX_MAP_COUNT; /* Check that a process has enough memory to allocate a @@ -654,13 +656,25 @@ unsigned long get_unmapped_area(struct file *file, unsigned long addr, unsigned return -ENOMEM; if (addr & ~PAGE_MASK) return -EINVAL; + + /* Ensure a non-privileged process is not trying to map + * lower pages. + */ + if (addr < mmap_min_addr && !capable(CAP_SYS_RAWIO)) + return -EPERM; + return addr; } if (file && file->f_op && file->f_op->get_unmapped_area) - return file->f_op->get_unmapped_area(file, addr, len, pgoff, flags); + addr = file->f_op->get_unmapped_area(file, addr, len, pgoff, flags); + else + addr = arch_get_unmapped_area(file, addr, len, pgoff, flags); + + if (addr < mmap_min_addr && !capable(CAP_SYS_RAWIO)) + return -ENOMEM; - return arch_get_unmapped_area(file, addr, len, pgoff, flags); + return addr; } /* Look up the first VMA which satisfies addr < vm_end, NULL if none. */ diff --git a/mm/mremap.c b/mm/mremap.c index 416dd4b..3bda909 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -273,6 +273,12 @@ unsigned long do_mremap(unsigned long addr, if ((addr <= new_addr) && (addr+old_len) > new_addr) goto out; + /* Ensure a non-privileged process is not trying to map + * lower pages. + */ + if (new_addr < mmap_min_addr && !capable(CAP_SYS_RAWIO)) + return -EPERM; + ret = do_munmap(current->mm, new_addr, new_len); if (ret && new_len) goto out;