From 23c2afa8bf546c5018870f75bb78c716b3be04f6 Mon Sep 17 00:00:00 2001 From: Marc Fiuczynski Date: Mon, 8 Aug 2005 21:29:33 +0000 Subject: [PATCH] Fedora Core 2.6.12-1.1398_FC4 kernel --- .config | 3 +- .config.old | 2 + MAINTAINERS | 15 ++-- arch/ppc/kernel/time.c | 13 ++-- arch/um/kernel/process.c | 48 +++++++----- configs/kernel-2.6.12-i586.config | 3 +- configs/kernel-2.6.12-i686-smp.config | 3 +- configs/kernel-2.6.12-i686-xen0.config | 3 +- configs/kernel-2.6.12-i686-xenU.config | 2 +- configs/kernel-2.6.12-i686.config | 3 +- drivers/char/tty_ioctl.c | 4 +- drivers/ide/ide-cd.c | 6 +- drivers/ide/ide-io.c | 57 ++++++++++++++ drivers/ide/pci/piix.c | 11 ++- drivers/media/video/cx88/cx88-video.c | 2 +- drivers/net/hamradio/Kconfig | 2 +- drivers/net/shaper.c | 40 ++++------ drivers/usb/input/Kconfig | 19 +++++ drivers/usb/input/Makefile | 1 + drivers/usb/storage/transport.c | 7 +- fs/char_dev.c | 2 +- fs/nfsd/nfs4state.c | 3 + fs/nfsd/nfsctl.c | 103 ++++++++++++++++++++++++- fs/nfsd/nfssvc.c | 96 ++++++++++++++--------- include/linux/audit.h | 9 ++- include/linux/autoconf.h | 3 +- include/linux/if_shaper.h | 2 +- include/linux/nfsd/syscall.h | 19 +++++ kernel/audit.c | 23 +++--- kernel/auditsc.c | 75 ++++++++++++------ net/bridge/br_netfilter.c | 2 +- net/ipv4/ip_output.c | 8 +- 32 files changed, 436 insertions(+), 153 deletions(-) diff --git a/.config b/.config index 7c457850d..437c3b7c9 100644 --- a/.config +++ b/.config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.12.2 -# Wed Jul 13 17:05:01 2005 +# Thu Aug 4 14:53:44 2005 # CONFIG_X86=y CONFIG_MMU=y @@ -2383,6 +2383,7 @@ CONFIG_USB_MTOUCH=m CONFIG_USB_EGALAX=m CONFIG_USB_XPAD=m CONFIG_USB_ATI_REMOTE=m +# CONFIG_USB_APPLETOUCH is not set # # USB Imaging devices diff --git a/.config.old b/.config.old index d2f3de345..0c9be14eb 100644 --- a/.config.old +++ b/.config.old @@ -2494,6 +2494,8 @@ CONFIG_BLK_DEV_IT821X=y CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_USB_APPLETOUCH is not set + CONFIG_UID16=y CONFIG_X86_PC=y # CONFIG_X86_ELAN is not set diff --git a/MAINTAINERS b/MAINTAINERS index 0dd293aeb..a464ed6f9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -358,13 +358,6 @@ L: linux-atm-general@lists.sourceforge.net W: http://linux-atm.sourceforge.net S: Maintained -AUDIT SUBSYSTEM -P: David Woodhouse -M: dwmw2@infradead.org -L: linux-audit@redhat.com -W: http://people.redhat.com/sgrubb/audit/ -S: Maintained - ATMEL WIRELESS DRIVER P: Simon Kelley M: simon@thekelleys.org.uk @@ -372,6 +365,14 @@ W: http://www.thekelleys.org.uk/atmel W: http://atmelwlandriver.sourceforge.net/ S: Maintained +AUDIT SUBSYSTEM +L: linux-audit@redhat.com (subscribers-only) +P: David Woodhouse +M: dwmw2@infradead.org +L: linux-audit@redhat.com +W: http://people.redhat.com/sgrubb/audit/ +S: Maintained + AX.25 NETWORK LAYER P: Ralf Baechle M: ralf@linux-mips.org diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c index 735866559..bf4ddca5e 100644 --- a/arch/ppc/kernel/time.c +++ b/arch/ppc/kernel/time.c @@ -89,6 +89,9 @@ unsigned long tb_to_ns_scale; extern unsigned long wall_jiffies; +/* used for timezone offset */ +static long timezone_offset; + DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); @@ -170,7 +173,7 @@ void timer_interrupt(struct pt_regs * regs) xtime.tv_sec - last_rtc_update >= 659 && abs((xtime.tv_nsec / 1000) - (1000000-1000000/HZ)) < 500000/HZ && jiffies - wall_jiffies == 1) { - if (ppc_md.set_rtc_time(xtime.tv_sec+1 + time_offset) == 0) + if (ppc_md.set_rtc_time(xtime.tv_sec+1 + timezone_offset) == 0) last_rtc_update = xtime.tv_sec+1; else /* Try again one minute later */ @@ -286,7 +289,7 @@ void __init time_init(void) unsigned old_stamp, stamp, elapsed; if (ppc_md.time_init != NULL) - time_offset = ppc_md.time_init(); + timezone_offset = ppc_md.time_init(); if (__USE_RTC()) { /* 601 processor: dec counts down by 128 every 128ns */ @@ -331,10 +334,10 @@ void __init time_init(void) set_dec(tb_ticks_per_jiffy); /* If platform provided a timezone (pmac), we correct the time */ - if (time_offset) { - sys_tz.tz_minuteswest = -time_offset / 60; + if (timezone_offset) { + sys_tz.tz_minuteswest = -timezone_offset / 60; sys_tz.tz_dsttime = 0; - xtime.tv_sec -= time_offset; + xtime.tv_sec -= timezone_offset; } set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 1b5ef3e96..793c77c6e 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -130,7 +130,7 @@ int start_fork_tramp(void *thread_arg, unsigned long temp_stack, return(arg.pid); } -static int ptrace_child(void) +static int ptrace_child(void *arg) { int ret; int pid = os_getpid(), ppid = getppid(); @@ -159,16 +159,20 @@ static int ptrace_child(void) _exit(ret); } -static int start_ptraced_child(void) +static int start_ptraced_child(void **stack_out) { + void *stack; + unsigned long sp; int pid, n, status; - pid = fork(); - if(pid == 0) - ptrace_child(); - + stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if(stack == MAP_FAILED) + panic("check_ptrace : mmap failed, errno = %d", errno); + sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *); + pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL); if(pid < 0) - panic("check_ptrace : fork failed, errno = %d", errno); + panic("check_ptrace : clone failed, errno = %d", errno); CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); if(n < 0) panic("check_ptrace : wait failed, errno = %d", errno); @@ -176,6 +180,7 @@ static int start_ptraced_child(void) panic("check_ptrace : expected SIGSTOP, got status = %d", status); + *stack_out = stack; return(pid); } @@ -183,12 +188,12 @@ static int start_ptraced_child(void) * just avoid using sysemu, not panic, but only if SYSEMU features are broken. * So only for SYSEMU features we test mustpanic, while normal host features * must work anyway!*/ -static int stop_ptraced_child(int pid, int exitcode, int mustexit) +static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic) { int status, n, ret = 0; if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) - panic("stop_ptraced_child : ptrace failed, errno = %d", errno); + panic("check_ptrace : ptrace failed, errno = %d", errno); CATCH_EINTR(n = waitpid(pid, &status, 0)); if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { int exit_with = WEXITSTATUS(status); @@ -199,13 +204,15 @@ static int stop_ptraced_child(int pid, int exitcode, int mustexit) printk("check_ptrace : child exited with exitcode %d, while " "expecting %d; status 0x%x", exit_with, exitcode, status); - if (mustexit) + if (mustpanic) panic("\n"); else printk("\n"); ret = -1; } + if(munmap(stack, PAGE_SIZE) < 0) + panic("check_ptrace : munmap failed, errno = %d", errno); return ret; } @@ -227,11 +234,12 @@ __uml_setup("nosysemu", nosysemu_cmd_param, static void __init check_sysemu(void) { + void *stack; int pid, syscall, n, status, count=0; printk("Checking syscall emulation patch for ptrace..."); sysemu_supported = 0; - pid = start_ptraced_child(); + pid = start_ptraced_child(&stack); if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) goto fail; @@ -249,7 +257,7 @@ static void __init check_sysemu(void) panic("check_sysemu : failed to modify system " "call return, errno = %d", errno); - if (stop_ptraced_child(pid, 0, 0) < 0) + if (stop_ptraced_child(pid, stack, 0, 0) < 0) goto fail_stopped; sysemu_supported = 1; @@ -257,7 +265,7 @@ static void __init check_sysemu(void) set_using_sysemu(!force_sysemu_disabled); printk("Checking advanced syscall emulation patch for ptrace..."); - pid = start_ptraced_child(); + pid = start_ptraced_child(&stack); while(1){ count++; if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0) @@ -282,7 +290,7 @@ static void __init check_sysemu(void) break; } } - if (stop_ptraced_child(pid, 0, 0) < 0) + if (stop_ptraced_child(pid, stack, 0, 0) < 0) goto fail_stopped; sysemu_supported = 2; @@ -293,17 +301,18 @@ static void __init check_sysemu(void) return; fail: - stop_ptraced_child(pid, 1, 0); + stop_ptraced_child(pid, stack, 1, 0); fail_stopped: printk("missing\n"); } void __init check_ptrace(void) { + void *stack; int pid, syscall, n, status; printk("Checking that ptrace can change system call numbers..."); - pid = start_ptraced_child(); + pid = start_ptraced_child(&stack); if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno); @@ -330,7 +339,7 @@ void __init check_ptrace(void) break; } } - stop_ptraced_child(pid, 0, 1); + stop_ptraced_child(pid, stack, 0, 1); printk("OK\n"); check_sysemu(); } @@ -362,10 +371,11 @@ void forward_pending_sigio(int target) static inline int check_skas3_ptrace_support(void) { struct ptrace_faultinfo fi; + void *stack; int pid, n, ret = 1; printf("Checking for the skas3 patch in the host..."); - pid = start_ptraced_child(); + pid = start_ptraced_child(&stack); n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); if (n < 0) { @@ -380,7 +390,7 @@ static inline int check_skas3_ptrace_support(void) } init_registers(pid); - stop_ptraced_child(pid, 1, 1); + stop_ptraced_child(pid, stack, 1, 1); return(ret); } diff --git a/configs/kernel-2.6.12-i586.config b/configs/kernel-2.6.12-i586.config index 9118574a1..fdcb0a4c4 100644 --- a/configs/kernel-2.6.12-i586.config +++ b/configs/kernel-2.6.12-i586.config @@ -2,7 +2,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.12.2 -# Wed Jul 13 17:04:57 2005 +# Thu Aug 4 14:53:43 2005 # CONFIG_X86=y CONFIG_MMU=y @@ -2383,6 +2383,7 @@ CONFIG_USB_MTOUCH=m CONFIG_USB_EGALAX=m CONFIG_USB_XPAD=m CONFIG_USB_ATI_REMOTE=m +# CONFIG_USB_APPLETOUCH is not set # # USB Imaging devices diff --git a/configs/kernel-2.6.12-i686-smp.config b/configs/kernel-2.6.12-i686-smp.config index 86bb2b011..b1e69edc2 100644 --- a/configs/kernel-2.6.12-i686-smp.config +++ b/configs/kernel-2.6.12-i686-smp.config @@ -2,7 +2,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.12.2 -# Wed Jul 13 17:04:58 2005 +# Thu Aug 4 14:53:43 2005 # CONFIG_X86=y CONFIG_MMU=y @@ -2379,6 +2379,7 @@ CONFIG_USB_MTOUCH=m CONFIG_USB_EGALAX=m CONFIG_USB_XPAD=m CONFIG_USB_ATI_REMOTE=m +# CONFIG_USB_APPLETOUCH is not set # # USB Imaging devices diff --git a/configs/kernel-2.6.12-i686-xen0.config b/configs/kernel-2.6.12-i686-xen0.config index 700a5b657..9e2bf4395 100644 --- a/configs/kernel-2.6.12-i686-xen0.config +++ b/configs/kernel-2.6.12-i686-xen0.config @@ -2,7 +2,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.12.2 -# Wed Jul 13 17:04:59 2005 +# Thu Aug 4 14:53:44 2005 # CONFIG_XEN=y CONFIG_ARCH_XEN=y @@ -2258,6 +2258,7 @@ CONFIG_USB_MTOUCH=m CONFIG_USB_EGALAX=m CONFIG_USB_XPAD=m CONFIG_USB_ATI_REMOTE=m +# CONFIG_USB_APPLETOUCH is not set # # USB Imaging devices diff --git a/configs/kernel-2.6.12-i686-xenU.config b/configs/kernel-2.6.12-i686-xenU.config index 716dbfbfb..c2278459b 100644 --- a/configs/kernel-2.6.12-i686-xenU.config +++ b/configs/kernel-2.6.12-i686-xenU.config @@ -2,7 +2,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.12.2 -# Wed Jul 13 17:05:00 2005 +# Thu Aug 4 14:53:44 2005 # CONFIG_XEN=y CONFIG_ARCH_XEN=y diff --git a/configs/kernel-2.6.12-i686.config b/configs/kernel-2.6.12-i686.config index 6d8f3ba49..8b87207cb 100644 --- a/configs/kernel-2.6.12-i686.config +++ b/configs/kernel-2.6.12-i686.config @@ -2,7 +2,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.12.2 -# Wed Jul 13 17:05:01 2005 +# Thu Aug 4 14:53:44 2005 # CONFIG_X86=y CONFIG_MMU=y @@ -2384,6 +2384,7 @@ CONFIG_USB_MTOUCH=m CONFIG_USB_EGALAX=m CONFIG_USB_XPAD=m CONFIG_USB_ATI_REMOTE=m +# CONFIG_USB_APPLETOUCH is not set # # USB Imaging devices diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index 585979939..f19cf9d77 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c @@ -476,11 +476,11 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file, ld = tty_ldisc_ref(tty); switch (arg) { case TCIFLUSH: - if (ld->flush_buffer) + if (ld && ld->flush_buffer) ld->flush_buffer(tty); break; case TCIOFLUSH: - if (ld->flush_buffer) + if (ld && ld->flush_buffer) ld->flush_buffer(tty); /* fall through */ case TCOFLUSH: diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index e0caefd70..dcb2f2640 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -650,15 +650,15 @@ static void cdrom_end_request (ide_drive_t *drive, int uptodate) /* * now end failed request */ - spin_lock_irqsave(&ide_lock, flags); if(blk_fs_request(failed)) { - if(__ide_end_request(drive, failed, 0, failed->hard_nr_sectors)) + if(ide_end_dequeued_request(drive, failed, 0, failed->hard_nr_sectors)) BUG(); } else { + spin_lock_irqsave(&ide_lock, flags); end_that_request_chunk(failed, 0, failed->data_len); end_that_request_last(failed); + spin_unlock_irqrestore(&ide_lock, flags); } - spin_unlock_irqrestore(&ide_lock, flags); } else cdrom_analyze_sense_data(drive, NULL , sense); diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 68495c1b9..9d0344486 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -222,6 +222,63 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * return ide_stopped; } +/** + * ide_end_dequeued_request - complete an IDE I/O + * @drive: IDE device for the I/O + * @uptodate: + * @nr_sectors: number of sectors completed + * + * Complete an I/O that is no longer on the request queue. This + * typically occurs when we pull the request and issue a REQUEST_SENSE. + * We must still finish the old request but we must not tamper with the + * queue in the meantime. + * + * NOTE: This path does not handle barrier, but barrier is not supported + * on ide-cd anyway. + */ + +int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq, + int uptodate, int nr_sectors) +{ + unsigned long flags; + int ret = 1; + + spin_lock_irqsave(&ide_lock, flags); + + BUG_ON(!(rq->flags & REQ_STARTED)); + + /* + * if failfast is set on a request, override number of sectors and + * complete the whole request right now + */ + if (blk_noretry_request(rq) && end_io_error(uptodate)) + nr_sectors = rq->hard_nr_sectors; + + if (!blk_fs_request(rq) && end_io_error(uptodate) && !rq->errors) + rq->errors = -EIO; + + /* + * decide whether to reenable DMA -- 3 is a random magic for now, + * if we DMA timeout more than 3 times, just stay in PIO + */ + if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) { + drive->state = 0; + HWGROUP(drive)->hwif->ide_dma_on(drive); + } + + if (!end_that_request_first(rq, uptodate, nr_sectors)) { + add_disk_randomness(rq->rq_disk); + if (blk_rq_tagged(rq)) + blk_queue_end_tag(drive->queue, rq); + end_that_request_last(rq); + ret = 0; + } + spin_unlock_irqrestore(&ide_lock, flags); + return ret; +} +EXPORT_SYMBOL_GPL(ide_end_dequeued_request); + + /** * ide_complete_pm_request - end the current Power Management request * @drive: target drive diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c index b3e77df63..21e0176f2 100644 --- a/drivers/ide/pci/piix.c +++ b/drivers/ide/pci/piix.c @@ -203,6 +203,8 @@ static u8 piix_dma_2_pio (u8 xfer_rate) { } } +static spinlock_t tune_lock = SPIN_LOCK_UNLOCKED; + /** * piix_tune_drive - tune a drive attached to a PIIX * @drive: drive to tune @@ -229,7 +231,12 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio) { 2, 3 }, }; pio = ide_get_best_pio_mode(drive, pio, 5, NULL); - spin_lock_irqsave(&ide_lock, flags); + + /* Master v slave is synchronized above us but the slave register is + shared by the two hwifs so the corner case of two slave timeouts in + parallel must be locked */ + + spin_lock_irqsave(&tune_lock, flags); pci_read_config_word(dev, master_port, &master_data); if (is_slave) { master_data = master_data | 0x4000; @@ -249,7 +256,7 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio) pci_write_config_word(dev, master_port, master_data); if (is_slave) pci_write_config_byte(dev, slave_port, slave_data); - spin_unlock_irqrestore(&ide_lock, flags); + spin_unlock_irqrestore(&tune_lock, flags); } /** diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index d1f5c92f0..d650a2fe4 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c @@ -261,7 +261,7 @@ static struct cx88_ctrl cx8800_ctls[] = { .default_value = 0, .type = V4L2_CTRL_TYPE_INTEGER, }, - .off = 0, + .off = 128, .reg = MO_HUE, .mask = 0x00ff, .shift = 0, diff --git a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig index 7cdebe1a0..0cd54306e 100644 --- a/drivers/net/hamradio/Kconfig +++ b/drivers/net/hamradio/Kconfig @@ -17,7 +17,7 @@ config MKISS config 6PACK tristate "Serial port 6PACK driver" - depends on AX25 && BROKEN_ON_SMP + depends on AX25 ---help--- 6pack is a transmission protocol for the data exchange between your PC and your TNC (the Terminal Node Controller acts as a kind of diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c index 20edeb345..16bb1cea2 100644 --- a/drivers/net/shaper.c +++ b/drivers/net/shaper.c @@ -135,10 +135,8 @@ static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct shaper *shaper = dev->priv; struct sk_buff *ptr; - - if (down_trylock(&shaper->sem)) - return -1; + spin_lock(&shaper->lock); ptr=shaper->sendq.prev; /* @@ -232,7 +230,7 @@ static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) shaper->stats.collisions++; } shaper_kick(shaper); - up(&shaper->sem); + spin_unlock(&shaper->lock); return 0; } @@ -271,11 +269,9 @@ static void shaper_timer(unsigned long data) { struct shaper *shaper = (struct shaper *)data; - if (!down_trylock(&shaper->sem)) { - shaper_kick(shaper); - up(&shaper->sem); - } else - mod_timer(&shaper->timer, jiffies); + spin_lock(&shaper->lock); + shaper_kick(shaper); + spin_unlock(&shaper->lock); } /* @@ -331,21 +327,6 @@ static void shaper_kick(struct shaper *shaper) } -/* - * Flush the shaper queues on a closedown - */ - -static void shaper_flush(struct shaper *shaper) -{ - struct sk_buff *skb; - - down(&shaper->sem); - while((skb=skb_dequeue(&shaper->sendq))!=NULL) - dev_kfree_skb(skb); - shaper_kick(shaper); - up(&shaper->sem); -} - /* * Bring the interface up. We just disallow this until a * bind. @@ -375,7 +356,15 @@ static int shaper_open(struct net_device *dev) static int shaper_close(struct net_device *dev) { struct shaper *shaper=dev->priv; - shaper_flush(shaper); + struct sk_buff *skb; + + while ((skb = skb_dequeue(&shaper->sendq)) != NULL) + dev_kfree_skb(skb); + + spin_lock_bh(&shaper->lock); + shaper_kick(shaper); + spin_unlock_bh(&shaper->lock); + del_timer_sync(&shaper->timer); return 0; } @@ -576,6 +565,7 @@ static void shaper_init_priv(struct net_device *dev) init_timer(&sh->timer); sh->timer.function=shaper_timer; sh->timer.data=(unsigned long)sh; + spin_lock_init(&sh->lock); } /* diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig index d28e7eab6..ecf73a516 100644 --- a/drivers/usb/input/Kconfig +++ b/drivers/usb/input/Kconfig @@ -235,3 +235,22 @@ config USB_ATI_REMOTE To compile this driver as a module, choose M here: the module will be called ati_remote. +config USB_APPLETOUCH + tristate "Apple USB Touchpad support" + depends on USB && INPUT + ---help--- + Say Y here if you want to use an Apple USB Touchpad. + + These are the touchpads that can be found on post-February 2005 + Apple Powerbooks (prior models have a Synaptics touchpad connected + to the ADB bus). + + This driver provides a basic mouse driver but can be interfaced + with the synaptics X11 driver to provide acceleration and + scrolling in X11. + + For further information, see + . + + To compile this driver as a module, choose M here: the + module will be called appletouch. diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile index 6bcedd16b..36025f1ae 100644 --- a/drivers/usb/input/Makefile +++ b/drivers/usb/input/Makefile @@ -37,3 +37,4 @@ obj-$(CONFIG_USB_EGALAX) += touchkitusb.o obj-$(CONFIG_USB_POWERMATE) += powermate.o obj-$(CONFIG_USB_WACOM) += wacom.o obj-$(CONFIG_USB_XPAD) += xpad.o +obj-$(CONFIG_USB_APPLETOUCH) += appletouch.o diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index 9743e289c..d20aed29e 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -948,8 +948,9 @@ int usb_stor_Bulk_max_lun(struct us_data *us) int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us) { - struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; - struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf; + /* Offset into iobuf a little in order to defeat pre-set DMA */ + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) (us->iobuf + 4); + struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) (us->iobuf + 4); unsigned int transfer_length = srb->request_bufflen; unsigned int residue; int result; @@ -960,7 +961,7 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us) /* Take care of BULK32 devices; set extra byte to 0 */ if ( unlikely(us->flags & US_FL_BULK32)) { cbwlen = 32; - us->iobuf[31] = 0; + ((unsigned char *)bcb)[31] = 0; } /* set up the command wrapper */ diff --git a/fs/char_dev.c b/fs/char_dev.c index c1e353790..e8fb88b75 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c @@ -139,7 +139,7 @@ __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct) struct char_device_struct *cd = NULL, **cp; int i = major_to_index(major); - up(&chrdevs_lock); + down(&chrdevs_lock); for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next) if ((*cp)->major == major && (*cp)->baseminor == baseminor && diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 75e8b1375..da7f179b1 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -3256,6 +3256,9 @@ __nfs4_state_shutdown(void) void nfs4_state_shutdown(void) { + if (!nfs4_init) + return; + nfs4_lock_state(); nfs4_release_reclaim(); __nfs4_state_shutdown(); diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 161afdcb8..7aee4125b 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -35,6 +36,10 @@ #include +int nfsd_port = 2049; +unsigned int nfsd_portbits = 0; +unsigned int nfsd_versbits = 0; + /* * We have a single directory with 9 nodes in it. */ @@ -51,6 +56,8 @@ enum { NFSD_Fh, NFSD_Threads, NFSD_Leasetime, + NFSD_Ports, + NFSD_Versions, }; /* @@ -66,6 +73,8 @@ static ssize_t write_getfs(struct file *file, char *buf, size_t size); static ssize_t write_filehandle(struct file *file, char *buf, size_t size); static ssize_t write_threads(struct file *file, char *buf, size_t size); static ssize_t write_leasetime(struct file *file, char *buf, size_t size); +static ssize_t write_ports(struct file *file, char *buf, size_t size); +static ssize_t write_versions(struct file *file, char *buf, size_t size); static ssize_t (*write_op[])(struct file *, char *, size_t) = { [NFSD_Svc] = write_svc, @@ -78,6 +87,8 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = { [NFSD_Fh] = write_filehandle, [NFSD_Threads] = write_threads, [NFSD_Leasetime] = write_leasetime, + [NFSD_Ports] = write_ports, + [NFSD_Versions] = write_versions, }; static ssize_t nfsctl_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos) @@ -85,14 +96,12 @@ static ssize_t nfsctl_transaction_write(struct file *file, const char __user *bu ino_t ino = file->f_dentry->d_inode->i_ino; char *data; ssize_t rv; - if (ino >= sizeof(write_op)/sizeof(write_op[0]) || !write_op[ino]) return -EINVAL; data = simple_transaction_get(file, buf, size); if (IS_ERR(data)) return PTR_ERR(data); - rv = write_op[ino](file, data, size); if (rv>0) { simple_transaction_set(file, rv); @@ -256,7 +265,7 @@ static ssize_t write_filehandle(struct file *file, char *buf, size_t size) * qword quoting is used, so filehandle will be \x.... */ char *dname, *path; - int maxsize; + int maxsize = 0; char *mesg = buf; int len; struct auth_domain *dom; @@ -325,6 +334,92 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size) sprintf(buf, "%d\n", nfsd_nrthreads()); return strlen(buf); } +static ssize_t write_ports(struct file *file, char *buf, size_t size) +{ + /* + * Format: + * family proto address port + */ + char *mesg = buf; + char *family, *proto, *addr; + int len, port = 0; + ssize_t tlen = 0; + + if (buf[size-1] != '\n') + return -EINVAL; + buf[size-1] = 0; + + family = mesg; + len = qword_get(&mesg, family, size); + if (len <= 0) return -EINVAL; + + tlen += len; + proto = family+len+1; + len = qword_get(&mesg, proto, size); + if (len <= 0) return -EINVAL; + + tlen += len; + addr = proto+len+1; + len = qword_get(&mesg, addr, size); + if (len <= 0) return -EINVAL; + + len = get_int(&mesg, &port); + if (len) + return len; + + tlen += sizeof(port); + if (port) + nfsd_port = port; + + if (strcmp(proto, "tcp") == 0 || strcmp(proto, "TCP") == 0) + NFSCTL_TCPSET(nfsd_portbits); + if (strcmp(proto, "udp") == 0 || strcmp(proto, "UDP") == 0) + NFSCTL_UDPSET(nfsd_portbits); + + return tlen; +} +static ssize_t write_versions(struct file *file, char *buf, size_t size) +{ + /* + * Format: + * [-/+]vers [-/+]vers ... + */ + char *mesg = buf; + char *vers, sign; + int len, num; + ssize_t tlen = 0; + + if (buf[size-1] != '\n') + return -EINVAL; + buf[size-1] = 0; + + vers = mesg; + len = qword_get(&mesg, vers, size); + if (len <= 0) return -EINVAL; + do { + sign = *vers; + if (sign == '+' || sign == '-') + num = simple_strtol((vers+1), NULL, 0); + else + num = simple_strtol(vers, NULL, 0); + switch(num) { + case 2: + case 3: + case 4: + if (sign != '-') + NFSCTL_VERSET(nfsd_versbits, num); + else + NFSCTL_VERUNSET(nfsd_versbits, num); + break; + default: + return -EINVAL; + } + vers += len + 1; + tlen += len; + } while ((len = qword_get(&mesg, vers, size)) > 0); + + return tlen; +} extern time_t nfs4_leasetime(void); @@ -370,6 +465,8 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent) #ifdef CONFIG_NFSD_V4 [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR}, #endif + [NFSD_Ports] = {"ports", &transaction_ops, S_IWUSR|S_IRUSR}, + [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR}, /* last one */ {""} }; return simple_fill_super(sb, 0x6e667364, nfsd_files); diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 02ded7cfb..453dbeca0 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #define NFSDDBG_FACILITY NFSDDBG_SVC @@ -51,10 +52,7 @@ extern struct svc_program nfsd_program; static void nfsd(struct svc_rqst *rqstp); struct timeval nfssvc_boot; -static struct svc_serv *nfsd_serv; -static atomic_t nfsd_busy; -static unsigned long nfsd_last_call; -static DEFINE_SPINLOCK(nfsd_call_lock); +static struct svc_serv *nfsd_serv; static atomic_t nfsd_busy; static unsigned long nfsd_last_call; static DEFINE_SPINLOCK(nfsd_call_lock); struct nfsd_list { struct list_head list; @@ -62,6 +60,31 @@ struct nfsd_list { }; static struct list_head nfsd_list = LIST_HEAD_INIT(nfsd_list); +extern struct svc_version nfsd_version2, nfsd_version3, nfsd_version4; + +static struct svc_version * nfsd_version[] = { + [2] = &nfsd_version2, +#if defined(CONFIG_NFSD_V3) + [3] = &nfsd_version3, +#endif +#if defined(CONFIG_NFSD_V4) + [4] = &nfsd_version4, +#endif +}; + +#define NFSD_MINVERS 2 +#define NFSD_NRVERS (sizeof(nfsd_version)/sizeof(nfsd_version[0])) +struct svc_program nfsd_program = { + .pg_prog = NFS_PROGRAM, /* program number */ + .pg_nvers = NFSD_NRVERS, /* nr of entries in nfsd_version */ + .pg_vers = nfsd_version, /* version table */ + .pg_name = "nfsd", /* program name */ + .pg_class = "nfsd", /* authentication class */ + .pg_stats = &nfsd_svcstats, /* version table */ + .pg_authenticate = &svc_set_client, /* export authentication */ + +}; + /* * Maximum number of nfsd processes */ @@ -79,17 +102,37 @@ int nfsd_svc(unsigned short port, int nrservs) { int error; - int none_left; + int none_left, found_one, i; struct list_head *victim; lock_kernel(); - dprintk("nfsd: creating service\n"); + dprintk("nfsd: creating service: port %d vers 0x%x proto 0x%x\n", + nfsd_port, nfsd_versbits, nfsd_portbits); error = -EINVAL; if (nrservs <= 0) nrservs = 0; if (nrservs > NFSD_MAXSERVS) nrservs = NFSD_MAXSERVS; + /* + * If set, use the nfsd_ctlbits to define which + * versions that will be advertised + */ + found_one = 0; + if (nfsd_versbits) { + for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) { + if (NFSCTL_VERISSET(nfsd_versbits, i)) { + nfsd_program.pg_vers[i] = nfsd_version[i]; + found_one = 1; + } else + nfsd_program.pg_vers[i] = NULL; + } + } + if (!found_one) { + for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) + nfsd_program.pg_vers[i] = nfsd_version[i]; + } + /* Readahead param cache - will no-op if it already exists */ error = nfsd_racache_init(2*nrservs); if (error<0) @@ -97,20 +140,24 @@ nfsd_svc(unsigned short port, int nrservs) error = nfs4_state_init(); if (error<0) goto out; + if (!nfsd_serv) { atomic_set(&nfsd_busy, 0); error = -ENOMEM; nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE); if (nfsd_serv == NULL) goto out; - error = svc_makesock(nfsd_serv, IPPROTO_UDP, port); - if (error < 0) - goto failure; - + if (!nfsd_portbits || NFSCTL_UDPISSET(nfsd_portbits)) { + error = svc_makesock(nfsd_serv, IPPROTO_UDP, nfsd_port); + if (error < 0) + goto failure; + } #ifdef CONFIG_NFSD_TCP - error = svc_makesock(nfsd_serv, IPPROTO_TCP, port); - if (error < 0) - goto failure; + if (!nfsd_portbits || NFSCTL_TCPISSET(nfsd_portbits)) { + error = svc_makesock(nfsd_serv, IPPROTO_TCP, nfsd_port); + if (error < 0) + goto failure; + } #endif do_gettimeofday(&nfssvc_boot); /* record boot time */ } else @@ -362,26 +409,3 @@ nfsd_dispatch(struct svc_rqst *rqstp, u32 *statp) return 1; } -extern struct svc_version nfsd_version2, nfsd_version3, nfsd_version4; - -static struct svc_version * nfsd_version[] = { - [2] = &nfsd_version2, -#if defined(CONFIG_NFSD_V3) - [3] = &nfsd_version3, -#endif -#if defined(CONFIG_NFSD_V4) - [4] = &nfsd_version4, -#endif -}; - -#define NFSD_NRVERS (sizeof(nfsd_version)/sizeof(nfsd_version[0])) -struct svc_program nfsd_program = { - .pg_prog = NFS_PROGRAM, /* program number */ - .pg_nvers = NFSD_NRVERS, /* nr of entries in nfsd_version */ - .pg_vers = nfsd_version, /* version table */ - .pg_name = "nfsd", /* program name */ - .pg_class = "nfsd", /* authentication class */ - .pg_stats = &nfsd_svcstats, /* version table */ - .pg_authenticate = &svc_set_client, /* export authentication */ - -}; diff --git a/include/linux/audit.h b/include/linux/audit.h index 2f56546eb..d68e85580 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -205,6 +205,7 @@ struct audit_sig_info { struct audit_buffer; struct audit_context; struct inode; +struct netlink_skb_parms; #define AUDITSC_INVALID 0 #define AUDITSC_SUCCESS 1 @@ -236,7 +237,7 @@ extern int audit_socketcall(int nargs, unsigned long *args); extern int audit_sockaddr(int len, void *addr); extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt); extern void audit_signal_info(int sig, struct task_struct *t); -extern int audit_filter_user(int pid, int type); +extern int audit_filter_user(struct netlink_skb_parms *cb, int type); #else #define audit_alloc(t) ({ 0; }) #define audit_free(t) do { ; } while (0) @@ -253,7 +254,7 @@ extern int audit_filter_user(int pid, int type); #define audit_sockaddr(len, addr) ({ 0; }) #define audit_avc_path(dentry, mnt) ({ 0; }) #define audit_signal_info(s,t) do { ; } while (0) -#define audit_filter_user(p,t) ({ 1; }) +#define audit_filter_user(cb,t) ({ 1; }) #endif #ifdef CONFIG_AUDIT @@ -284,8 +285,8 @@ extern void audit_send_reply(int pid, int seq, int type, extern void audit_log_lost(const char *message); extern struct semaphore audit_netlink_sem; #else -#define audit_log(c,t,f,...) do { ; } while (0) -#define audit_log_start(c,t) ({ NULL; }) +#define audit_log(c,g,t,f,...) do { ; } while (0) +#define audit_log_start(c,g,t) ({ NULL; }) #define audit_log_vformat(b,f,a) do { ; } while (0) #define audit_log_format(b,f,...) do { ; } while (0) #define audit_log_end(b) do { ; } while (0) diff --git a/include/linux/autoconf.h b/include/linux/autoconf.h index 1cd667b68..904d8cdf4 100644 --- a/include/linux/autoconf.h +++ b/include/linux/autoconf.h @@ -1,7 +1,7 @@ /* * Automatically generated C config: don't edit * Linux kernel version: 2.6.12.2 - * Wed Jul 13 17:05:01 2005 + * Thu Aug 4 14:53:44 2005 */ #define AUTOCONF_INCLUDED #define CONFIG_X86 1 @@ -2384,6 +2384,7 @@ #define CONFIG_USB_EGALAX_MODULE 1 #define CONFIG_USB_XPAD_MODULE 1 #define CONFIG_USB_ATI_REMOTE_MODULE 1 +#undef CONFIG_USB_APPLETOUCH /* * USB Imaging devices diff --git a/include/linux/if_shaper.h b/include/linux/if_shaper.h index 004e6f09a..68c896a36 100644 --- a/include/linux/if_shaper.h +++ b/include/linux/if_shaper.h @@ -23,7 +23,7 @@ struct shaper __u32 shapeclock; unsigned long recovery; /* Time we can next clock a packet out on an empty queue */ - struct semaphore sem; + spinlock_t lock; struct net_device_stats stats; struct net_device *dev; int (*hard_start_xmit) (struct sk_buff *skb, diff --git a/include/linux/nfsd/syscall.h b/include/linux/nfsd/syscall.h index e65c9db6d..25013b376 100644 --- a/include/linux/nfsd/syscall.h +++ b/include/linux/nfsd/syscall.h @@ -39,6 +39,22 @@ #define NFSCTL_GETFD 7 /* get an fh by path (used by mountd) */ #define NFSCTL_GETFS 8 /* get an fh by path with max FH len */ +/* + * Macros used to set version and protocol + */ +#define NFSCTL_VERSET(_cltbits, _v) ((_cltbits) |= (1 << ((_v) - 1))) +#define NFSCTL_VERUNSET(_cltbits, _v) ((_cltbits) &= ~(1 << ((_v) - 1))) +#define NFSCTL_VERISSET(_cltbits, _v) ((_cltbits) & (1 << ((_v) - 1))) + +#define NFSCTL_UDPSET(_cltbits) ((_cltbits) |= (1 << (17 - 1))) +#define NFSCTL_UDPUNSET(_cltbits) ((_cltbits) &= ~(1 << (17 - 1))) +#define NFSCTL_UDPISSET(_cltbits) ((_cltbits) & (1 << (17 - 1))) + +#define NFSCTL_TCPSET(_cltbits) ((_cltbits) |= (1 << (18 - 1))) +#define NFSCTL_TCPUNSET(_cltbits) ((_cltbits) &= ~(1 << (18 - 1))) +#define NFSCTL_TCPISSET(_cltbits) ((_cltbits) & (1 << (18 - 1))) + + /* SVC */ struct nfsctl_svc { unsigned short svc_port; @@ -120,6 +136,9 @@ extern int exp_delclient(struct nfsctl_client *ncp); extern int exp_export(struct nfsctl_export *nxp); extern int exp_unexport(struct nfsctl_export *nxp); +extern int nfsd_port; +extern unsigned int nfsd_versbits, nfsd_portbits; + #endif /* __KERNEL__ */ #endif /* NFSD_SYSCALL_H */ diff --git a/kernel/audit.c b/kernel/audit.c index 9af947a63..518a833b6 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -79,6 +79,8 @@ static int audit_rate_limit; /* Number of outstanding audit_buffers allowed. */ static int audit_backlog_limit = 64; +static int audit_backlog_wait_time = 60 * HZ; +static int audit_backlog_wait_overflow = 0; /* The identity of the user shutting down the audit system. */ uid_t audit_sig_uid = -1; @@ -286,7 +288,7 @@ int kauditd_thread(void *dummy) audit_pid = 0; } } else { - printk(KERN_ERR "%s\n", skb->data + NLMSG_SPACE(0)); + printk(KERN_NOTICE "%s\n", skb->data + NLMSG_SPACE(0)); kfree_skb(skb); } } else { @@ -434,7 +436,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) if (!audit_enabled && msg_type != AUDIT_USER_AVC) return 0; - err = audit_filter_user(pid, msg_type); + err = audit_filter_user(&NETLINK_CB(skb), msg_type); if (err == 1) { err = 0; ab = audit_log_start(NULL, GFP_KERNEL, msg_type); @@ -562,7 +564,7 @@ static void audit_buffer_free(struct audit_buffer *ab) } static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx, - int gfp_mask, int type) + unsigned int __nocast gfp_mask, int type) { unsigned long flags; struct audit_buffer *ab = NULL; @@ -655,6 +657,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, int gfp_mask, struct timespec t; unsigned int serial; int reserve; + unsigned long timeout_start = jiffies; if (!audit_initialized) return NULL; @@ -667,8 +670,9 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, int gfp_mask, while (audit_backlog_limit && skb_queue_len(&audit_skb_queue) > audit_backlog_limit + reserve) { - if (gfp_mask & __GFP_WAIT) { - int ret = 1; + if (gfp_mask & __GFP_WAIT && audit_backlog_wait_time + && time_before(jiffies, timeout_start + audit_backlog_wait_time)) { + /* Wait for auditd to drain the queue a little */ DECLARE_WAITQUEUE(wait, current); set_current_state(TASK_INTERRUPTIBLE); @@ -676,12 +680,11 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, int gfp_mask, if (audit_backlog_limit && skb_queue_len(&audit_skb_queue) > audit_backlog_limit) - ret = schedule_timeout(HZ * 60); + schedule_timeout(timeout_start + audit_backlog_wait_time - jiffies); __set_current_state(TASK_RUNNING); remove_wait_queue(&audit_backlog_wait, &wait); - if (ret) - continue; + continue; } if (audit_rate_check()) printk(KERN_WARNING @@ -690,6 +693,8 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, int gfp_mask, skb_queue_len(&audit_skb_queue), audit_backlog_limit); audit_log_lost("backlog limit exceeded"); + audit_backlog_wait_time = audit_backlog_wait_overflow; + wake_up(&audit_backlog_wait); return NULL; } @@ -868,7 +873,7 @@ void audit_log_end(struct audit_buffer *ab) ab->skb = NULL; wake_up_interruptible(&kauditd_wait); } else { - printk("%s\n", ab->skb->data + NLMSG_SPACE(0)); + printk(KERN_NOTICE "%s\n", ab->skb->data + NLMSG_SPACE(0)); } } audit_buffer_free(ab); diff --git a/kernel/auditsc.c b/kernel/auditsc.c index f463fd230..242d45e53 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -40,6 +40,8 @@ #include #include #include +#include +#include #include /* 0 = no checking @@ -515,7 +517,7 @@ static enum audit_state audit_filter_syscall(struct task_struct *tsk, int word = AUDIT_WORD(ctx->major); int bit = AUDIT_BIT(ctx->major); - if (audit_pid && ctx->pid == audit_pid) + if (audit_pid && tsk->tgid == audit_pid) return AUDIT_DISABLED; rcu_read_lock(); @@ -530,35 +532,62 @@ static enum audit_state audit_filter_syscall(struct task_struct *tsk, return AUDIT_BUILD_CONTEXT; } -int audit_filter_user(int pid, int type) +static int audit_filter_user_rules(struct netlink_skb_parms *cb, + struct audit_rule *rule, + enum audit_state *state) +{ + int i; + + for (i = 0; i < rule->field_count; i++) { + u32 field = rule->fields[i] & ~AUDIT_NEGATE; + u32 value = rule->values[i]; + int result = 0; + + switch (field) { + case AUDIT_PID: + result = (cb->creds.pid == value); + break; + case AUDIT_UID: + result = (cb->creds.uid == value); + break; + case AUDIT_GID: + result = (cb->creds.gid == value); + break; + case AUDIT_LOGINUID: + result = (cb->loginuid == value); + break; + } + + if (rule->fields[i] & AUDIT_NEGATE) + result = !result; + if (!result) + return 0; + } + switch (rule->action) { + case AUDIT_NEVER: *state = AUDIT_DISABLED; break; + case AUDIT_POSSIBLE: *state = AUDIT_BUILD_CONTEXT; break; + case AUDIT_ALWAYS: *state = AUDIT_RECORD_CONTEXT; break; + } + return 1; +} + +int audit_filter_user(struct netlink_skb_parms *cb, int type) { - struct task_struct *tsk; struct audit_entry *e; enum audit_state state; int ret = 1; - read_lock(&tasklist_lock); - tsk = find_task_by_pid(pid); - if (tsk) - get_task_struct(tsk); - read_unlock(&tasklist_lock); - - if (!tsk) - return -ESRCH; - rcu_read_lock(); list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) { - if (audit_filter_rules(tsk, &e->rule, NULL, &state)) { + if (audit_filter_user_rules(cb, &e->rule, &state)) { if (state == AUDIT_DISABLED) ret = 0; break; } } rcu_read_unlock(); - put_task_struct(tsk); - - return 1; /* Audit by default */ + return ret; /* Audit by default */ } /* This should be called with task_lock() held. */ @@ -750,13 +779,13 @@ static void audit_log_task_info(struct audit_buffer *ab) up_read(&mm->mmap_sem); } -static void audit_log_exit(struct audit_context *context) +static void audit_log_exit(struct audit_context *context, unsigned int gfp_mask) { int i; struct audit_buffer *ab; struct audit_aux_data *aux; - ab = audit_log_start(context, GFP_KERNEL, AUDIT_SYSCALL); + ab = audit_log_start(context, gfp_mask, AUDIT_SYSCALL); if (!ab) return; /* audit_panic has been called */ audit_log_format(ab, "arch=%x syscall=%d", @@ -872,9 +901,11 @@ void audit_free(struct task_struct *tsk) return; /* Check for system calls that do not go through the exit - * function (e.g., exit_group), then free context block. */ + * function (e.g., exit_group), then free context block. + * We use GFP_ATOMIC here because we might be doing this + * in the context of the idle thread */ if (context->in_syscall && context->auditable) - audit_log_exit(context); + audit_log_exit(context, GFP_ATOMIC); audit_free_context(context); } @@ -979,7 +1010,7 @@ void audit_syscall_exit(struct task_struct *tsk, int valid, long return_code) return; if (context->in_syscall && context->auditable) - audit_log_exit(context); + audit_log_exit(context, GFP_KERNEL); context->in_syscall = 0; context->auditable = 0; @@ -1227,7 +1258,7 @@ void audit_signal_info(int sig, struct task_struct *t) extern pid_t audit_sig_pid; extern uid_t audit_sig_uid; - if (unlikely(audit_pid && t->pid == audit_pid)) { + if (unlikely(audit_pid && t->tgid == audit_pid)) { if (sig == SIGTERM || sig == SIGHUP) { struct audit_context *ctx = current->audit_context; audit_sig_pid = current->pid; diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index be03d3ad2..14a8765ac 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -882,7 +882,7 @@ static unsigned int ip_sabotage_out(unsigned int hook, struct sk_buff **pskb, * doesn't use the bridge parent of the indev by using * the BRNF_DONT_TAKE_PARENT mask. */ if (hook == NF_IP_FORWARD && nf_bridge->physindev == NULL) { - nf_bridge->mask &= BRNF_DONT_TAKE_PARENT; + nf_bridge->mask |= BRNF_DONT_TAKE_PARENT; nf_bridge->physindev = (struct net_device *)in; } #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 760dc8238..0fe94ef35 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -196,7 +196,13 @@ static inline int ip_finish_output2(struct sk_buff *skb) nf_debug_ip_finish_output2(skb); #endif /*CONFIG_NETFILTER_DEBUG*/ - nf_reset(skb); +#ifdef CONFIG_BRIDGE_NETFILTER + /* bridge-netfilter defers calling some IP hooks to the bridge layer + * and still needs the conntrack reference. + */ + if (skb->nf_bridge == NULL) +#endif + nf_reset(skb); if (hh) { int hh_alen; -- 2.47.0