From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752303AbcEKLrz (ORCPT ); Wed, 11 May 2016 07:47:55 -0400 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:50689 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751777AbcEKLrs (ORCPT ); Wed, 11 May 2016 07:47:48 -0400 Date: Wed, 11 May 2016 12:47:35 +0100 From: Ben Hutchings To: linux-kernel@vger.kernel.org, Andrew Morton , torvalds@linux-foundation.org, Jiri Slaby , stable@vger.kernel.org Cc: lwn@lwn.net Message-ID: <20160511114735.GC7555@decadent.org.uk> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="Uwl7UQhJk99r8jnw" Content-Disposition: inline X-Mailer: LinuxStableQueue (scripts by bwh) User-Agent: Mutt/1.5.23 (2014-03-12) X-SA-Exim-Connect-IP: X-SA-Exim-Mail-From: ben@decadent.org.uk Subject: Linux 3.2.80 X-SA-Exim-Version: 4.2.1 (built Mon, 26 Dec 2011 16:24:06 +0000) X-SA-Exim-Scanned: Yes (on shadbolt.decadent.org.uk) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org --Uwl7UQhJk99r8jnw Content-Type: multipart/mixed; boundary="llIrKcgUOe3dCx0c" Content-Disposition: inline --llIrKcgUOe3dCx0c Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable I'm announcing the release of the 3.2.80 kernel (belatedly, sorry). All users of the 3.2 kernel series should upgrade. The updated 3.2.y git tree can be found at: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable= =2Egit linux-3.2.y and can be browsed at the normal kernel.org git web browser: https://git.kernel.org/?p=3Dlinux/kernel/git/stable/linux-stable.git The diff from 3.2.79 is attached to this message. Ben. ------------ Documentation/networking/ip-sysctl.txt | 8 +++ MAINTAINERS | 82 ++++++++++++++----------= ---- Makefile | 2 +- arch/parisc/include/asm/uaccess.h | 1 + arch/parisc/kernel/asm-offsets.c | 1 + arch/parisc/kernel/parisc_ksyms.c | 10 ++-- arch/parisc/kernel/traps.c | 3 + arch/parisc/lib/fixup.S | 6 ++ arch/parisc/mm/fault.c | 1 + arch/um/drivers/mconsole_kern.c | 2 +- arch/x86/include/asm/xen/hypervisor.h | 2 + arch/x86/kernel/ioport.c | 7 ++- arch/x86/kernel/process_64.c | 12 ++++ arch/x86/kvm/i8254.c | 12 ++-- arch/x86/kvm/x86.c | 12 ++-- arch/x86/mm/mmap.c | 44 ++++++--------- arch/x86/pci/fixup.c | 7 +++ arch/x86/xen/enlighten.c | 2 +- drivers/bluetooth/ath3k.c | 8 +++ drivers/bluetooth/btusb.c | 4 ++ drivers/connector/connector.c | 11 +--- drivers/edac/amd64_edac.c | 2 +- drivers/gpu/drm/radeon/atombios_encoders.c | 6 +- drivers/hwmon/max1111.c | 6 ++ drivers/input/misc/ati_remote2.c | 36 ++++++++++-- drivers/input/misc/powermate.c | 3 + drivers/input/mouse/synaptics.c | 5 +- drivers/md/dm-snap.c | 9 +++ drivers/md/dm-table.c | 37 +++++++++---- drivers/md/raid1.c | 7 ++- drivers/md/raid10.c | 7 ++- drivers/media/video/bt8xx/bttv-driver.c | 26 +++++++-- drivers/media/video/pwc/pwc-if.c | 6 ++ drivers/media/video/saa7134/saa7134-video.c | 18 ++++-- drivers/misc/ad525x_dpot.c | 2 +- drivers/net/ethernet/jme.c | 26 +++++---- drivers/net/ethernet/micrel/ks8842.c | 10 ++-- drivers/net/ethernet/qlogic/qlge/qlge_main.c | 11 ++++ drivers/net/ethernet/renesas/sh_eth.c | 3 +- drivers/net/irda/irtty-sir.c | 10 ---- drivers/net/macvtap.c | 9 ++- drivers/net/phy/dp83640.c | 17 ++++++ drivers/net/ppp/ppp_generic.c | 35 +++++++----- drivers/net/ppp/pppoe.c | 2 + drivers/net/rionet.c | 4 +- drivers/net/usb/cdc_ncm.c | 6 +- drivers/net/usb/usbnet.c | 7 +++ drivers/net/wan/farsync.c | 2 +- drivers/net/wireless/ath/ath9k/eeprom.c | 7 +-- drivers/pci/probe.c | 14 +++++ drivers/rtc/rtc-vr41xx.c | 13 +++-- drivers/scsi/aacraid/commsup.c | 9 ++- drivers/scsi/be2iscsi/be_main.c | 1 + drivers/scsi/lpfc/lpfc_init.c | 5 +- drivers/scsi/sd.c | 23 +++----- drivers/scsi/sd.h | 7 ++- drivers/scsi/sg.c | 3 +- drivers/staging/usbip/usbip_common.c | 11 ++++ drivers/tty/serial/8250.c | 18 ++---- drivers/tty/serial/sh-sci.c | 37 ------------- drivers/usb/class/cdc-acm.c | 3 + drivers/usb/core/driver.c | 6 +- drivers/usb/core/hub.c | 16 ++++-- drivers/usb/misc/iowarrior.c | 6 ++ drivers/usb/renesas_usbhs/fifo.c | 4 +- drivers/usb/serial/cp210x.c | 1 + drivers/usb/serial/cypress_m8.c | 11 ++-- drivers/usb/serial/digi_acceleport.c | 18 ++++++ drivers/usb/serial/ftdi_sio.c | 4 ++ drivers/usb/serial/ftdi_sio_ids.h | 8 +++ drivers/usb/serial/mct_u232.c | 6 ++ drivers/watchdog/rc32434_wdt.c | 2 +- drivers/xen/events.c | 34 ++++++++++-- fs/bio.c | 12 ++-- fs/exec.c | 30 ++++++++-- fs/ext4/inode.c | 6 +- fs/fhandle.c | 2 +- fs/jbd2/journal.c | 17 ++++-- fs/nfsd/nfs4proc.c | 1 + fs/nfsd/nfs4xdr.c | 13 +++-- fs/ocfs2/dlm/dlmconvert.c | 24 +++++++- fs/ocfs2/dlm/dlmrecovery.c | 1 - fs/open.c | 6 +- fs/splice.c | 3 + fs/xfs/xfs_attr_leaf.c | 19 ++++--- include/linux/device-mapper.h | 2 + include/linux/fs.h | 2 +- include/linux/ipv6.h | 3 + include/linux/netdevice.h | 21 ++++++- include/linux/pci.h | 1 + include/net/inet_ecn.h | 19 ++++++- kernel/sched.c | 14 +++++ kernel/sysctl_binary.c | 2 +- kernel/trace/trace.c | 5 +- kernel/trace/trace_irqsoff.c | 8 ++- net/ax25/ax25_ip.c | 15 +++++ net/bridge/br_stp_if.c | 5 +- net/ipv4/devinet.c | 4 ++ net/ipv4/fib_frontend.c | 4 ++ net/ipv4/ip_gre.c | 2 +- net/ipv4/ip_sockglue.c | 2 + net/ipv4/netfilter/arp_tables.c | 41 +++++++------- net/ipv4/netfilter/ip_tables.c | 46 ++++++++-------- net/ipv4/netfilter/ipt_MASQUERADE.c | 12 +++- net/ipv4/ping.c | 4 +- net/ipv4/raw.c | 4 +- net/ipv4/tcp_yeah.c | 2 +- net/ipv4/udp.c | 4 +- net/ipv6/addrconf.c | 10 ++++ net/ipv6/datagram.c | 3 + net/ipv6/ip6_output.c | 9 ++- net/ipv6/ip6_tunnel.c | 2 +- net/ipv6/ndisc.c | 16 +++--- net/ipv6/netfilter/ip6_tables.c | 46 ++++++++-------- net/ipv6/sit.c | 2 +- net/ipv6/xfrm6_mode_tunnel.c | 2 +- net/iucv/af_iucv.c | 3 + net/l2tp/l2tp_ip.c | 8 ++- net/mac80211/sta_info.c | 17 ++++-- net/netfilter/ipvs/ip_vs_pe_sip.c | 2 +- net/phonet/af_phonet.c | 4 ++ net/sctp/ipv6.c | 2 + net/sctp/protocol.c | 47 +++++++++++++--- net/sctp/sm_statefuns.c | 6 +- net/sctp/socket.c | 3 +- net/socket.c | 38 ++++++------- net/xfrm/xfrm_input.c | 3 + sound/core/timer.c | 4 +- sound/pci/intel8x0.c | 1 + sound/usb/clock.c | 2 + sound/usb/pcm.c | 2 + sound/usb/quirks.c | 26 ++++++--- sound/usb/stream.c | 6 +- 133 files changed, 964 insertions(+), 472 deletions(-) Andy Lutomirski (2): x86/iopl/64: Properly context-switch IOPL on Xen PV x86/iopl: Fix iopl capability check on Xen PV Arnaldo Carvalho de Melo (1): net: Fix use after free in the recvmmsg exit path Arnd Bergmann (4): mac80211: avoid excessive stack usage in sta_info ath9k: fix buffer overrun for ar9287 lpfc: fix misleading indentation farsync: fix off-by-one bug in fst_add_one Aurelien Jacquiot (1): rapidio/rionet: fix deadlock on SMP Ben Hutchings (1): Linux 3.2.80 Benjamin Tissoires (1): Input: synaptics - handle spurious release of trackstick buttons, aga= in Bjorn Helgaas (2): PCI: Disable IO/MEM decoding for devices with non-compliant BARs x86/PCI: Mark Broadwell-EP Home Agent & PCU as having non-compliant B= ARs Bj=C3=B8rn Mork (1): cdc_ncm: toggle altsetting to force reset before setup Boris Ostrovsky (1): xen/events: Mask a moving irq Dan Carpenter (2): EDAC, amd64_edac: Shift wrapping issue in f1x_get_norm_dct_addr() ethernet: micrel: fix some error codes David S. Miller (1): ipv4: Don't do expensive useless work during inetdev destroy. Diego Viola (1): net: jme: fix suspend/resume on JMC260 DingXiang (1): dm snapshot: disallow the COW and origin devices from being identical Dmitry Tunin (4): Bluetooth: btusb: Add new AR3012 ID 13d3:3395 Bluetooth: Add new AR3012 ID 0489:e095 Bluetooth: btusb: Add a new AR3012 ID 04ca:3014 Bluetooth: btusb: Add a new AR3012 ID 13d3:3472 Douglas Gilbert (1): sg: fix dxferp in from_to case Eric Dumazet (3): phonet: properly unshare skbs in phonet_rcv() ipv6: update skb->csum when CE mark is propagated ipv4: fix memory leaks in ip_cmsg_send() callers Eryu Guan (1): ext4: fix NULL pointer dereference in ext4_mark_inode_dirty() Florian Westphal (4): netfilter: x_tables: validate e->target_offset early netfilter: x_tables: make sure e->next_offset covers remaining blob s= ize connector: bump skb->users before callback invocation netfilter: x_tables: fix unconditional helper Geert Uytterhoeven (2): rtc: vr41xx: Wire up alarm_irq_enable serial: sh-sci: Remove cpufreq notifier to fix crash/deadlock Guenter Roeck (2): MAINTAINERS: Update mailing list and web page for hwmon subsystem hwmon: (max1111) Return -ENODEV from max1111_read_channel if not inst= antiated Guillaume Nault (3): ppp: ensure file->private_data can't be overridden ppp: take reference on channels netns pppoe: fix reference counting in PPPoE proxy Guo-Fu Tseng (2): jme: Do not enable NIC WoL functions on S0 jme: Fix device PM wakeup API usage Haishuang Yan (1): ipv4: l2tp: fix a potential issue in l2tp_ip_recv Hangbin Liu (1): net/ipv6: add sysctl option accept_ra_min_hop_limit Hannes Frederic Sowa (1): bridge: Only call /sbin/bridge-stp for the initial network namespace Hannes Reinecke (1): bio: return EINTR if copying to user space got interrupted Hans de Goede (3): pwc: Add USB id for Philips Spc880nc webcam saa7134: Fix bytesperline not being set correctly for planar formats bttv: Width must be a multiple of 16 when capturing planar formats Hector Marco-Gisbert (1): x86/mm/32: Enable full randomization on i386 and X86_32 Helge Deller (3): parisc: Avoid function pointers for kernel exception routines parisc: Fix kernel crash with reversed copy_from_user() parisc: Unbreak handling exceptions from kernel modules Ignat Korchagin (1): USB: usbip: fix potential out-of-bounds write J. Bruce Fields (2): nfsd4: fix bad bounds checking nfsd: fix deadlock secinfo+readdir compound Jakub Sitnicki (1): ipv6: Count in extension headers in skb->network_header Jann Horn (1): fs/coredump: prevent fsuid=3D0 dumps into user-controlled directories Joseph Qi (2): ocfs2/dlm: fix race between convert and recovery ocfs2/dlm: fix BUG in dlm_move_lockres_to_recovery_list Josh Boyer (3): Input: powermate - fix oops with malicious USB descriptors USB: iowarrior: fix oops with malicious USB descriptors USB: serial: ftdi_sio: Add support for ICP DAS I-756xU devices Kees Cook (1): x86: standardize mmap_rnd() usage Manfred Rudigier (1): net: dp83640: Fix tx timestamp overflow handling. Manish Chopra (1): qlge: Fix receive packets drop. Marco Angaroni (1): ipvs: correct initial offset of Call-ID header search in SIP persiste= nce engine Mario Kleiner (1): drm/radeon: Don't drop DP 2.7 Ghz link setup on some cards. Martin K. Petersen (1): sd: Fix excessive capacity printing on devices with blocks bigger tha= n 512 bytes Martyn Welch (1): USB: serial: cp210x: Adding GE Healthcare Device ID Mateusz Guzik (1): xfs: fix two memory leaks in xfs_attr_list.c error paths Maurizio Lombardi (1): be2iscsi: set the boot_kset pointer to NULL in case of failure Michael Hennerich (1): drivers/misc/ad525x_dpot: AD5274 fix RDAC read back errors Michael S. Tsirkin (1): watchdog: rc32434_wdt: fix ioctl error handling Nate Dailey (1): raid1: include bio_end_io_list in nr_queued to prevent freeze_array h= ang Neal Cardwell (1): tcp_yeah: don't set ssthresh below 2 Neil Horman (1): sctp: Fix port hash table size computation OGAWA Hirofumi (1): jbd2: fix FS corruption possibility in jbd2_journal_destroy() on umou= nt path Oliver Neukum (8): usb: retry reset if a device times out usb: hub: fix a typo in hub_port_init() leading to wrong logic USB: usb_driver_claim_interface: add sanity checking USB: cdc-acm: more sanity checking USB: mct_u232: add sanity checking in probe USB: cypress_m8: add endpoint sanity check USB: digi_acceleport: do sanity checking for the number of ports usbnet: cleanup after bind() in probe() Paolo Abeni (1): ipv6/udp: use sticky pktinfo egress ifindex on connect() Peter Hurley (1): net: irda: Fix use-after-free in irtty_open() Rabin Vincent (1): splice: handle zero nr_pages in splice_to_pipe() Radim Kr=C4=8Dm=C3=A1=C5=99 (1): KVM: i8254: change PIT discard tick policy Raghava Aditya Renukunta (1): aacraid: Fix memory leak in aac_fib_map_free Sebastian Frias (1): 8250: use callbacks to access UART_DLL/UART_DLM Sergei Shtylyov (1): sh_eth: fix NULL pointer dereference in sh_eth_ring_format() Shaohua Li (1): raid10: include bio_end_io_list in nr_queued to prevent freeze_array = hang Steven Rostedt (Red Hat) (2): tracing: Have preempt(irqs)off trace preempt disabled functions tracing: Fix crash from reading trace_pipe with sendfile Sudip Mukherjee (1): mac80211: fix memory leak Takashi Iwai (4): ALSA: usb-audio: Fix NULL dereference in create_fixed_stream_quirk() ALSA: usb-audio: Add sanity checks for endpoint accesses ALSA: usb-audio: Minor code cleanup in create_fixed_stream_quirk() ALSA: timer: Use mod_timer() for rearming the system timer Thomas Gleixner (1): sched/cputime: Fix steal time accounting vs. CPU hotplug Ursula Braun (1): af_iucv: Validate socket address length in iucv_sock_bind() Vittorio Gambaletta (VittGam) (1): ALSA: intel8x0: Add clock quirk entry for AD1981B on IBM ThinkPad X41. Vladis Dronov (2): Input: ati_remote2 - fix crashes on detecting device with invalid des= criptor ALSA: usb-audio: Fix double-free in error paths after snd_usb_add_aud= io_stream() call Willem de Bruijn (3): net: validate variable length ll headers ax25: add link layer header validation function macvtap: always pass ethernet header in linear Xin Long (2): sctp: sctp should release assoc when sctp_make_abort_user return NULL= in sctp_close sctp: lack the check for ports in sctp_v6_cmp_addr Yoshihiro Shimoda (2): usb: renesas_usbhs: avoid NULL pointer derefernce in usbhsf_pkt_handl= er() usb: renesas_usbhs: disable TX IRQ before starting TX DMAC transfer Yuki Shibuya (1): KVM: x86: Inject pending interrupt even if pending nmi exist subashab@codeaurora.org (1): xfrm: Fix crash observed during device unregistration and decryption --llIrKcgUOe3dCx0c Content-Type: text/x-diff; charset=UTF-8; name="linux-3.2.80.patch" Content-Disposition: attachment; filename="linux-3.2.80.patch" Content-Transfer-Encoding: quoted-printable diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/network= ing/ip-sysctl.txt index 3b979c6ba84b..0df5824fee3b 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -1070,6 +1070,14 @@ accept_ra_defrtr - BOOLEAN Functional default: enabled if accept_ra is enabled. disabled if accept_ra is disabled. =20 +accept_ra_min_hop_limit - INTEGER + Minimum hop limit Information in Router Advertisement. + + Hop limit Information in Router Advertisement less than this + variable shall be ignored. + + Default: 1 + accept_ra_pinfo - BOOLEAN Learn Prefix Information in Router Advertisement. =20 diff --git a/MAINTAINERS b/MAINTAINERS index 8659eba2703d..e93164d0e5f5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -199,13 +199,13 @@ F: drivers/scsi/aacraid/ =20 ABIT UGURU 1,2 HARDWARE MONITOR DRIVER M: Hans de Goede -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: drivers/hwmon/abituguru.c =20 ABIT UGURU 3 HARDWARE MONITOR DRIVER M: Alistair John Strachan -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: drivers/hwmon/abituguru3.c =20 @@ -322,14 +322,14 @@ S: Maintained =20 ADM1025 HARDWARE MONITOR DRIVER M: Jean Delvare -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/adm1025 F: drivers/hwmon/adm1025.c =20 ADM1029 HARDWARE MONITOR DRIVER M: Corentin Labbe -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: drivers/hwmon/adm1029.c =20 @@ -367,7 +367,7 @@ F: drivers/video/backlight/adp8860_bl.c =20 ADS1015 HARDWARE MONITOR DRIVER M: Dirk Eibach -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/ads1015 F: drivers/hwmon/ads1015.c @@ -380,7 +380,7 @@ F: drivers/macintosh/therm_adt746x.c =20 ADT7475 HARDWARE MONITOR DRIVER M: Jean Delvare -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/adt7475 F: drivers/hwmon/adt7475.c @@ -485,7 +485,7 @@ F: include/linux/altera_jtaguart.h =20 AMD FAM15H PROCESSOR POWER MONITORING DRIVER M: Andreas Herrmann -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/fam15h_power F: drivers/hwmon/fam15h_power.c @@ -572,7 +572,7 @@ F: drivers/input/mouse/bcm5974.c =20 APPLE SMC DRIVER M: Henrik Rydberg -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: drivers/hwmon/applesmc.c =20 @@ -1214,7 +1214,7 @@ F: arch/arm/mach-pxa/include/mach/z2.h =20 ASC7621 HARDWARE MONITOR DRIVER M: George Joseph -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/asc7621 F: drivers/hwmon/asc7621.c @@ -1230,7 +1230,7 @@ F: drivers/platform/x86/eeepc*.c =20 ASUS ASB100 HARDWARE MONITOR DRIVER M: "Mark M. Hoffman" -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: drivers/hwmon/asb100.c =20 @@ -1303,7 +1303,7 @@ F: drivers/net/wireless/ath/carl9170/ =20 ATK0110 HWMON DRIVER M: Luca Tettamanti -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: drivers/hwmon/asus_atk0110.c =20 @@ -1937,7 +1937,7 @@ F: mm/*cgroup* =20 CORETEMP HARDWARE MONITORING DRIVER M: Fenghua Yu -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/coretemp F: drivers/hwmon/coretemp.c @@ -2263,7 +2263,7 @@ T: git git://git.infradead.org/users/vkoul/slave-dma.= git (slave-dma) =20 DME1737 HARDWARE MONITOR DRIVER M: Juerg Haefliger -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/dme1737 F: drivers/hwmon/dme1737.c @@ -2632,7 +2632,7 @@ F: security/integrity/evm/ =20 F71805F HARDWARE MONITORING DRIVER M: Jean Delvare -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/f71805f F: drivers/hwmon/f71805f.c @@ -2683,7 +2683,7 @@ F: fs/* =20 FINTEK F75375S HARDWARE MONITOR AND FAN CONTROLLER DRIVER M: Riku Voipio -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: drivers/hwmon/f75375s.c F: include/linux/f75375s.h @@ -3011,8 +3011,8 @@ F: drivers/tty/hvc/ HARDWARE MONITORING M: Jean Delvare M: Guenter Roeck -L: lm-sensors@lm-sensors.org -W: http://www.lm-sensors.org/ +L: linux-hwmon@vger.kernel.org +W: http://hwmon.wiki.kernel.org/ T: quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-hw= mon/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.= git S: Maintained @@ -3656,7 +3656,7 @@ F: drivers/isdn/hardware/eicon/ =20 IT87 HARDWARE MONITORING DRIVER M: Jean Delvare -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/it87 F: drivers/hwmon/it87.c @@ -3674,7 +3674,7 @@ F: include/linux/ivtv* =20 JC42.4 TEMPERATURE SENSOR DRIVER M: Guenter Roeck -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: drivers/hwmon/jc42.c F: Documentation/hwmon/jc42 @@ -3726,14 +3726,14 @@ F: drivers/tty/serial/jsm/ =20 K10TEMP HARDWARE MONITORING DRIVER M: Clemens Ladisch -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/k10temp F: drivers/hwmon/k10temp.c =20 K8TEMP HARDWARE MONITORING DRIVER M: Rudolf Marek -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/k8temp F: drivers/hwmon/k8temp.c @@ -4070,27 +4070,27 @@ F: net/llc/ =20 LM73 HARDWARE MONITOR DRIVER M: Guillaume Ligneul -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: drivers/hwmon/lm73.c =20 LM78 HARDWARE MONITOR DRIVER M: Jean Delvare -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/lm78 F: drivers/hwmon/lm78.c =20 LM83 HARDWARE MONITOR DRIVER M: Jean Delvare -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/lm83 F: drivers/hwmon/lm83.c =20 LM90 HARDWARE MONITOR DRIVER M: Jean Delvare -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/lm90 F: drivers/hwmon/lm90.c @@ -4137,7 +4137,7 @@ F: drivers/scsi/sym53c8xx_2/ =20 LTC4261 HARDWARE MONITOR DRIVER M: Guenter Roeck -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/ltc4261 F: drivers/hwmon/ltc4261.c @@ -4258,14 +4258,14 @@ F: include/linux/matroxfb.h =20 MAX1668 TEMPERATURE SENSOR DRIVER M: "David George" -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/max1668 F: drivers/hwmon/max1668.c =20 MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER M: "Hans J. Koch" -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/max6650 F: drivers/hwmon/max6650.c @@ -4984,7 +4984,7 @@ F: drivers/parisc/ =20 PC87360 HARDWARE MONITORING DRIVER M: Jim Cromie -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/pc87360 F: drivers/hwmon/pc87360.c @@ -4996,7 +4996,7 @@ F: drivers/char/pc8736x_gpio.c =20 PC87427 HARDWARE MONITORING DRIVER M: Jean Delvare -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/pc87427 F: drivers/hwmon/pc87427.c @@ -5143,8 +5143,8 @@ F: drivers/rtc/rtc-puv3.c =20 PMBUS HARDWARE MONITORING DRIVERS M: Guenter Roeck -L: lm-sensors@lm-sensors.org -W: http://www.lm-sensors.org/ +L: linux-hwmon@vger.kernel.org +W: http://hwmon.wiki.kernel.org/ W: http://www.roeck-us.net/linux/drivers/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.= git S: Maintained @@ -6014,28 +6014,28 @@ F: drivers/net/ethernet/smsc/smc91x.* =20 SMM665 HARDWARE MONITOR DRIVER M: Guenter Roeck -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/smm665 F: drivers/hwmon/smm665.c =20 SMSC EMC2103 HARDWARE MONITOR DRIVER M: Steve Glendinning -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Supported F: Documentation/hwmon/emc2103 F: drivers/hwmon/emc2103.c =20 SMSC SCH5627 HARDWARE MONITOR DRIVER M: Hans de Goede -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Supported F: Documentation/hwmon/sch5627 F: drivers/hwmon/sch5627.c =20 SMSC47B397 HARDWARE MONITOR DRIVER M: "Mark M. Hoffman" -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/smsc47b397 F: drivers/hwmon/smsc47b397.c @@ -7212,14 +7212,14 @@ F: include/linux/regulator/ =20 VT1211 HARDWARE MONITOR DRIVER M: Juerg Haefliger -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/vt1211 F: drivers/hwmon/vt1211.c =20 VT8231 HARDWARE MONITOR DRIVER M: Roger Lucas -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: drivers/hwmon/vt8231.c =20 @@ -7238,21 +7238,21 @@ F: drivers/w1/ =20 W83791D HARDWARE MONITORING DRIVER M: Marc Hulsman -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/w83791d F: drivers/hwmon/w83791d.c =20 W83793 HARDWARE MONITORING DRIVER M: Rudolf Marek -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/w83793 F: drivers/hwmon/w83793.c =20 W83795 HARDWARE MONITORING DRIVER M: Jean Delvare -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: drivers/hwmon/w83795.c =20 diff --git a/Makefile b/Makefile index cfadb8fc7781..5b500f93425b 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION =3D 3 PATCHLEVEL =3D 2 -SUBLEVEL =3D 79 +SUBLEVEL =3D 80 EXTRAVERSION =3D NAME =3D Saber-toothed Squirrel =20 diff --git a/arch/parisc/include/asm/uaccess.h b/arch/parisc/include/asm/ua= ccess.h index ff4cf9dab8d2..337353de237b 100644 --- a/arch/parisc/include/asm/uaccess.h +++ b/arch/parisc/include/asm/uaccess.h @@ -79,6 +79,7 @@ struct exception_table_entry { */ struct exception_data { unsigned long fault_ip; + unsigned long fault_gp; unsigned long fault_space; unsigned long fault_addr; }; diff --git a/arch/parisc/kernel/asm-offsets.c b/arch/parisc/kernel/asm-offs= ets.c index dcd55103a4bb..a0dc1e50e3a3 100644 --- a/arch/parisc/kernel/asm-offsets.c +++ b/arch/parisc/kernel/asm-offsets.c @@ -292,6 +292,7 @@ int main(void) DEFINE(ASM_PT_INITIAL, PT_INITIAL); BLANK(); DEFINE(EXCDATA_IP, offsetof(struct exception_data, fault_ip)); + DEFINE(EXCDATA_GP, offsetof(struct exception_data, fault_gp)); DEFINE(EXCDATA_SPACE, offsetof(struct exception_data, fault_space)); DEFINE(EXCDATA_ADDR, offsetof(struct exception_data, fault_addr)); BLANK(); diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_= ksyms.c index c3f1be951ab4..0824405059d0 100644 --- a/arch/parisc/kernel/parisc_ksyms.c +++ b/arch/parisc/kernel/parisc_ksyms.c @@ -48,11 +48,11 @@ EXPORT_SYMBOL(lstrncpy_from_user); EXPORT_SYMBOL(lclear_user); EXPORT_SYMBOL(lstrnlen_user); =20 -/* Global fixups */ -extern void fixup_get_user_skip_1(void); -extern void fixup_get_user_skip_2(void); -extern void fixup_put_user_skip_1(void); -extern void fixup_put_user_skip_2(void); +/* Global fixups - defined as int to avoid creation of function pointers */ +extern int fixup_get_user_skip_1; +extern int fixup_get_user_skip_2; +extern int fixup_put_user_skip_1; +extern int fixup_put_user_skip_2; EXPORT_SYMBOL(fixup_get_user_skip_1); EXPORT_SYMBOL(fixup_get_user_skip_2); EXPORT_SYMBOL(fixup_put_user_skip_1); diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index cd8b02f69bf5..73102ea0c209 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -817,6 +817,9 @@ void notrace handle_interruption(int code, struct pt_re= gs *regs) =20 if (fault_space =3D=3D 0 && !in_atomic()) { + /* Clean up and return if in exception table. */ + if (fixup_exception(regs)) + return; pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC); parisc_terminate("Kernel Fault", regs, code, fault_address); } diff --git a/arch/parisc/lib/fixup.S b/arch/parisc/lib/fixup.S index f8c45cc2947d..138dd1e5a87a 100644 --- a/arch/parisc/lib/fixup.S +++ b/arch/parisc/lib/fixup.S @@ -26,6 +26,7 @@ =20 #ifdef CONFIG_SMP .macro get_fault_ip t1 t2 + loadgp addil LT%__per_cpu_offset,%r27 LDREG RT%__per_cpu_offset(%r1),\t1 /* t2 =3D smp_processor_id() */ @@ -40,14 +41,19 @@ LDREG RT%exception_data(%r1),\t1 /* t1 =3D &__get_cpu_var(exception_data) */ add,l \t1,\t2,\t1 + /* %r27 =3D t1->fault_gp - restore gp */ + LDREG EXCDATA_GP(\t1), %r27 /* t1 =3D t1->fault_ip */ LDREG EXCDATA_IP(\t1), \t1 .endm #else .macro get_fault_ip t1 t2 + loadgp /* t1 =3D &__get_cpu_var(exception_data) */ addil LT%exception_data,%r27 LDREG RT%exception_data(%r1),\t2 + /* %r27 =3D t2->fault_gp - restore gp */ + LDREG EXCDATA_GP(\t2), %r27 /* t1 =3D t2->fault_ip */ LDREG EXCDATA_IP(\t2), \t1 .endm diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index a9b765a999ef..6471abb29cbb 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c @@ -147,6 +147,7 @@ int fixup_exception(struct pt_regs *regs) struct exception_data *d; d =3D &__get_cpu_var(exception_data); d->fault_ip =3D regs->iaoq[0]; + d->fault_gp =3D regs->gr[27]; d->fault_space =3D regs->isr; d->fault_addr =3D regs->ior; =20 diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_ker= n.c index c70e047eed72..f4a6af25dc72 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c @@ -133,7 +133,7 @@ void mconsole_proc(struct mc_request *req) ptr +=3D strlen("proc"); ptr =3D skip_spaces(ptr); =20 - file =3D file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY); + file =3D file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY, 0); if (IS_ERR(file)) { mconsole_reply(req, "Failed to open file", 1, 0); goto out; diff --git a/arch/x86/include/asm/xen/hypervisor.h b/arch/x86/include/asm/x= en/hypervisor.h index 66d0fff1ee84..fc500f97b39d 100644 --- a/arch/x86/include/asm/xen/hypervisor.h +++ b/arch/x86/include/asm/xen/hypervisor.h @@ -72,4 +72,6 @@ static inline bool xen_x2apic_para_available(void) } #endif =20 +extern void xen_set_iopl_mask(unsigned mask); + #endif /* _ASM_X86_XEN_HYPERVISOR_H */ diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c index 8c968974253d..6a2fa4ac5a76 100644 --- a/arch/x86/kernel/ioport.c +++ b/arch/x86/kernel/ioport.c @@ -95,9 +95,14 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned = long num, int turn_on) */ long sys_iopl(unsigned int level, struct pt_regs *regs) { - unsigned int old =3D (regs->flags >> 12) & 3; struct thread_struct *t =3D ¤t->thread; =20 + /* + * Careful: the IOPL bits in regs->flags are undefined under Xen PV + * and changing them has no effect. + */ + unsigned int old =3D t->iopl >> 12; + if (level > 3) return -EINVAL; /* Trying to gain more privileges? */ diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index ee2e70c9fdbf..557eb3757edb 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -38,6 +38,7 @@ #include #include #include +#include =20 #include #include @@ -52,6 +53,7 @@ #include #include #include +#include =20 asmlinkage extern void ret_from_fork(void); =20 @@ -518,6 +520,16 @@ __switch_to(struct task_struct *prev_p, struct task_st= ruct *next_p) task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV)) __switch_to_xtra(prev_p, next_p, tss); =20 +#ifdef CONFIG_XEN + /* + * On Xen PV, IOPL bits in pt_regs->flags have no effect, and + * current_pt_regs()->flags may not match the current task's + * intended IOPL. We need to switch it manually. + */ + if (unlikely(xen_pv_domain() && prev->iopl !=3D next->iopl)) + xen_set_iopl_mask(next->iopl); +#endif + return prev_p; } =20 diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index aa21aa139694..358edcde653d 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c @@ -246,7 +246,7 @@ static void kvm_pit_ack_irq(struct kvm_irq_ack_notifier= *kian) * PIC is being reset. Handle it gracefully here */ atomic_inc(&ps->pit_timer.pending); - else if (value > 0) + else if (value > 0 && ps->pit_timer.reinject) /* in this case, we had multiple outstanding pit interrupts * that we needed to inject. Reinject */ @@ -300,7 +300,9 @@ static void pit_do_work(struct work_struct *work) * last one has been acked. */ spin_lock(&ps->inject_lock); - if (ps->irq_ack) { + if (!ps->pit_timer.reinject) + inject =3D 1; + else if (ps->irq_ack) { ps->irq_ack =3D 0; inject =3D 1; } @@ -329,10 +331,10 @@ static enum hrtimer_restart pit_timer_fn(struct hrtim= er *data) struct kvm_timer *ktimer =3D container_of(data, struct kvm_timer, timer); struct kvm_pit *pt =3D ktimer->kvm->arch.vpit; =20 - if (ktimer->reinject || !atomic_read(&ktimer->pending)) { + if (ktimer->reinject) atomic_inc(&ktimer->pending); - queue_work(pt->wq, &pt->expired); - } + + queue_work(pt->wq, &pt->expired); =20 if (ktimer->t_ops->is_periodic(ktimer)) { hrtimer_add_expires_ns(&ktimer->timer, ktimer->period); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 09dab5bc4995..da1a1261aac1 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -5634,12 +5634,10 @@ static void inject_pending_event(struct kvm_vcpu *v= cpu) } =20 /* try to inject new event if pending */ - if (vcpu->arch.nmi_pending) { - if (kvm_x86_ops->nmi_allowed(vcpu)) { - --vcpu->arch.nmi_pending; - vcpu->arch.nmi_injected =3D true; - kvm_x86_ops->set_nmi(vcpu); - } + if (vcpu->arch.nmi_pending && kvm_x86_ops->nmi_allowed(vcpu)) { + --vcpu->arch.nmi_pending; + vcpu->arch.nmi_injected =3D true; + kvm_x86_ops->set_nmi(vcpu); } else if (kvm_cpu_has_interrupt(vcpu)) { if (kvm_x86_ops->interrupt_allowed(vcpu)) { kvm_queue_interrupt(vcpu, kvm_cpu_get_interrupt(vcpu), @@ -5742,7 +5740,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) /* enable NMI/IRQ window open exits if needed */ if (vcpu->arch.nmi_pending) kvm_x86_ops->enable_nmi_window(vcpu); - else if (kvm_cpu_has_interrupt(vcpu) || req_int_win) + if (kvm_cpu_has_interrupt(vcpu) || req_int_win) kvm_x86_ops->enable_irq_window(vcpu); =20 if (kvm_lapic_enabled(vcpu)) { diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c index 75f9e5d80d02..7da1b9a234a6 100644 --- a/arch/x86/mm/mmap.c +++ b/arch/x86/mm/mmap.c @@ -67,22 +67,21 @@ static int mmap_is_legacy(void) =20 static unsigned long mmap_rnd(void) { - unsigned long rnd =3D 0; + unsigned long rnd; =20 /* - * 8 bits of randomness in 32bit mmaps, 20 address space bits - * 28 bits of randomness in 64bit mmaps, 40 address space bits - */ - if (current->flags & PF_RANDOMIZE) { - if (mmap_is_ia32()) - rnd =3D get_random_int() % (1<<8); - else - rnd =3D get_random_int() % (1<<28); - } + * 8 bits of randomness in 32bit mmaps, 20 address space bits + * 28 bits of randomness in 64bit mmaps, 40 address space bits + */ + if (mmap_is_ia32()) + rnd =3D (unsigned long)get_random_int() % (1<<8); + else + rnd =3D (unsigned long)get_random_int() % (1<<28); + return rnd << PAGE_SHIFT; } =20 -static unsigned long mmap_base(void) +static unsigned long mmap_base(unsigned long rnd) { unsigned long gap =3D rlimit(RLIMIT_STACK); =20 @@ -91,19 +90,7 @@ static unsigned long mmap_base(void) else if (gap > MAX_GAP) gap =3D MAX_GAP; =20 - return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd()); -} - -/* - * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_= 64 - * does, but not when emulating X86_32 - */ -static unsigned long mmap_legacy_base(void) -{ - if (mmap_is_ia32()) - return TASK_UNMAPPED_BASE; - else - return TASK_UNMAPPED_BASE + mmap_rnd(); + return PAGE_ALIGN(TASK_SIZE - gap - rnd); } =20 /* @@ -112,14 +99,19 @@ static unsigned long mmap_legacy_base(void) */ void arch_pick_mmap_layout(struct mm_struct *mm) { - mm->mmap_legacy_base =3D mmap_legacy_base(); - mm->mmap_base =3D mmap_base(); + unsigned long random_factor =3D 0UL; + + if (current->flags & PF_RANDOMIZE) + random_factor =3D mmap_rnd(); + + mm->mmap_legacy_base =3D TASK_UNMAPPED_BASE + random_factor; =20 if (mmap_is_legacy()) { mm->mmap_base =3D mm->mmap_legacy_base; mm->get_unmapped_area =3D arch_get_unmapped_area; mm->unmap_area =3D arch_unmap_area; } else { + mm->mmap_base =3D mmap_base(random_factor); mm->get_unmapped_area =3D arch_get_unmapped_area_topdown; mm->unmap_area =3D arch_unmap_area_topdown; } diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index 0951b81ea90e..7d0cfe38dc60 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c @@ -538,3 +538,10 @@ static void __devinit twinhead_reserve_killing_zone(st= ruct pci_dev *dev) } } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x27B9, twinhead_reserve_kil= ling_zone); + +static void pci_bdwep_bar(struct pci_dev *dev) +{ + dev->non_compliant_bars =3D 1; +} +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fa0, pci_bdwep_bar); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fc0, pci_bdwep_bar); diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 81afe1bb3a8a..b255312def9c 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -768,7 +768,7 @@ static void xen_load_sp0(struct tss_struct *tss, xen_mc_issue(PARAVIRT_LAZY_CPU); } =20 -static void xen_set_iopl_mask(unsigned mask) +void xen_set_iopl_mask(unsigned mask) { struct physdev_set_iopl set_iopl; =20 diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 9fb9287050d7..0b87fb6cc365 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -80,6 +80,7 @@ static struct usb_device_id ath3k_table[] =3D { { USB_DEVICE(0x0489, 0xe05f) }, { USB_DEVICE(0x0489, 0xe076) }, { USB_DEVICE(0x0489, 0xe078) }, + { USB_DEVICE(0x0489, 0xe095) }, { USB_DEVICE(0x04c5, 0x1330) }, { USB_DEVICE(0x04CA, 0x3004) }, { USB_DEVICE(0x04CA, 0x3005) }, @@ -89,6 +90,7 @@ static struct usb_device_id ath3k_table[] =3D { { USB_DEVICE(0x04CA, 0x300b) }, { USB_DEVICE(0x04CA, 0x300f) }, { USB_DEVICE(0x04CA, 0x3010) }, + { USB_DEVICE(0x04CA, 0x3014) }, { USB_DEVICE(0x0930, 0x0219) }, { USB_DEVICE(0x0930, 0x021c) }, { USB_DEVICE(0x0930, 0x0220) }, @@ -109,10 +111,12 @@ static struct usb_device_id ath3k_table[] =3D { { USB_DEVICE(0x13d3, 0x3362) }, { USB_DEVICE(0x13d3, 0x3375) }, { USB_DEVICE(0x13d3, 0x3393) }, + { USB_DEVICE(0x13d3, 0x3395) }, { USB_DEVICE(0x13d3, 0x3402) }, { USB_DEVICE(0x13d3, 0x3408) }, { USB_DEVICE(0x13d3, 0x3423) }, { USB_DEVICE(0x13d3, 0x3432) }, + { USB_DEVICE(0x13d3, 0x3472) }, { USB_DEVICE(0x13d3, 0x3474) }, =20 /* Atheros AR5BBU12 with sflash firmware */ @@ -140,6 +144,7 @@ static struct usb_device_id ath3k_blist_tbl[] =3D { { USB_DEVICE(0x0489, 0xe05f), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe076), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe078), .driver_info =3D BTUSB_ATH3012 }, + { USB_DEVICE(0x0489, 0xe095), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x04c5, 0x1330), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3004), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3005), .driver_info =3D BTUSB_ATH3012 }, @@ -149,6 +154,7 @@ static struct usb_device_id ath3k_blist_tbl[] =3D { { USB_DEVICE(0x04ca, 0x300b), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x300f), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3010), .driver_info =3D BTUSB_ATH3012 }, + { USB_DEVICE(0x04ca, 0x3014), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0219), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x021c), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0220), .driver_info =3D BTUSB_ATH3012 }, @@ -169,10 +175,12 @@ static struct usb_device_id ath3k_blist_tbl[] =3D { { USB_DEVICE(0x13d3, 0x3362), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3375), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3393), .driver_info =3D BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3395), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3402), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3408), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3423), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3432), .driver_info =3D BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3472), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3474), .driver_info =3D BTUSB_ATH3012 }, =20 /* Atheros AR5BBU22 with sflash firmware */ diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index d83c855af7e2..1cba113f27ce 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -165,6 +165,7 @@ static struct usb_device_id blacklist_table[] =3D { { USB_DEVICE(0x0489, 0xe05f), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe076), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe078), .driver_info =3D BTUSB_ATH3012 }, + { USB_DEVICE(0x0489, 0xe095), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x04c5, 0x1330), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3004), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3005), .driver_info =3D BTUSB_ATH3012 }, @@ -174,6 +175,7 @@ static struct usb_device_id blacklist_table[] =3D { { USB_DEVICE(0x04ca, 0x300b), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x300f), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3010), .driver_info =3D BTUSB_ATH3012 }, + { USB_DEVICE(0x04ca, 0x3014), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0219), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x021c), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0220), .driver_info =3D BTUSB_ATH3012 }, @@ -194,10 +196,12 @@ static struct usb_device_id blacklist_table[] =3D { { USB_DEVICE(0x13d3, 0x3362), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3375), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3393), .driver_info =3D BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3395), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3402), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3408), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3423), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3432), .driver_info =3D BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3472), .driver_info =3D BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3474), .driver_info =3D BTUSB_ATH3012 }, =20 /* Atheros AR5BBU12 with sflash firmware */ diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c index ea6efe86468e..89829127f83e 100644 --- a/drivers/connector/connector.c +++ b/drivers/connector/connector.c @@ -154,26 +154,21 @@ static int cn_call_callback(struct sk_buff *skb) * * It checks skb, netlink header and msg sizes, and calls callback helper. */ -static void cn_rx_skb(struct sk_buff *__skb) +static void cn_rx_skb(struct sk_buff *skb) { struct nlmsghdr *nlh; - struct sk_buff *skb; int len, err; =20 - skb =3D skb_get(__skb); - if (skb->len >=3D NLMSG_SPACE(0)) { nlh =3D nlmsg_hdr(skb); len =3D nlmsg_len(nlh); =20 if (len < (int)sizeof(struct cn_msg) || skb->len < nlh->nlmsg_len || - len > CONNECTOR_MAX_MSG_SIZE) { - kfree_skb(skb); + len > CONNECTOR_MAX_MSG_SIZE) return; - } =20 - err =3D cn_call_callback(skb); + err =3D cn_call_callback(skb_get(skb)); if (err < 0) kfree_skb(skb); } diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index a9d5482cf6f6..0bcf2e1c0e36 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -1318,7 +1318,7 @@ static u64 f1x_get_norm_dct_addr(struct amd64_pvt *pv= t, unsigned range, u64 chan_off; u64 dram_base =3D get_dram_base(pvt, range); u64 hole_off =3D f10_dhar_offset(pvt); - u64 dct_sel_base_off =3D (pvt->dct_sel_hi & 0xFFFFFC00) << 16; + u64 dct_sel_base_off =3D (u64)(pvt->dct_sel_hi & 0xFFFFFC00) << 16; =20 if (hi_rng) { /* diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/r= adeon/atombios_encoders.c index 286f1fa640bc..a1a7d071eb17 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c @@ -607,8 +607,6 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder,= int action, int panel_mo else args.v1.ucLaneNum =3D 4; =20 - if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode) && (dp_clock =3D=3D 27000= 0)) - args.v1.ucConfig |=3D ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; switch (radeon_encoder->encoder_id) { case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: args.v1.ucConfig =3D ATOM_ENCODER_CONFIG_V2_TRANSMITTER1; @@ -625,6 +623,10 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder= , int action, int panel_mo args.v1.ucConfig |=3D ATOM_ENCODER_CONFIG_LINKB; else args.v1.ucConfig |=3D ATOM_ENCODER_CONFIG_LINKA; + + if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode) && (dp_clock =3D=3D 27000= 0)) + args.v1.ucConfig |=3D ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; + break; case 2: case 3: diff --git a/drivers/hwmon/max1111.c b/drivers/hwmon/max1111.c index c97b78ef9116..96121fbb404f 100644 --- a/drivers/hwmon/max1111.c +++ b/drivers/hwmon/max1111.c @@ -80,6 +80,9 @@ static struct max1111_data *the_max1111; =20 int max1111_read_channel(int channel) { + if (!the_max1111 || !the_max1111->spi) + return -ENODEV; + return max1111_read(&the_max1111->spi->dev, channel); } EXPORT_SYMBOL(max1111_read_channel); @@ -208,6 +211,9 @@ static int __devexit max1111_remove(struct spi_device *= spi) { struct max1111_data *data =3D spi_get_drvdata(spi); =20 +#ifdef CONFIG_SHARPSL_PM + the_max1111 =3D NULL; +#endif hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group); mutex_destroy(&data->drvdata_lock); diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remo= te2.c index 8d345e87075e..1c742970dc7f 100644 --- a/drivers/input/misc/ati_remote2.c +++ b/drivers/input/misc/ati_remote2.c @@ -814,26 +814,49 @@ static int ati_remote2_probe(struct usb_interface *in= terface, const struct usb_d =20 ar2->udev =3D udev; =20 + /* Sanity check, first interface must have an endpoint */ + if (alt->desc.bNumEndpoints < 1 || !alt->endpoint) { + dev_err(&interface->dev, + "%s(): interface 0 must have an endpoint\n", __func__); + r =3D -ENODEV; + goto fail1; + } ar2->intf[0] =3D interface; ar2->ep[0] =3D &alt->endpoint[0].desc; =20 + /* Sanity check, the device must have two interfaces */ ar2->intf[1] =3D usb_ifnum_to_if(udev, 1); + if ((udev->actconfig->desc.bNumInterfaces < 2) || !ar2->intf[1]) { + dev_err(&interface->dev, "%s(): need 2 interfaces, found %d\n", + __func__, udev->actconfig->desc.bNumInterfaces); + r =3D -ENODEV; + goto fail1; + } + r =3D usb_driver_claim_interface(&ati_remote2_driver, ar2->intf[1], ar2); if (r) goto fail1; + + /* Sanity check, second interface must have an endpoint */ alt =3D ar2->intf[1]->cur_altsetting; + if (alt->desc.bNumEndpoints < 1 || !alt->endpoint) { + dev_err(&interface->dev, + "%s(): interface 1 must have an endpoint\n", __func__); + r =3D -ENODEV; + goto fail2; + } ar2->ep[1] =3D &alt->endpoint[0].desc; =20 r =3D ati_remote2_urb_init(ar2); if (r) - goto fail2; + goto fail3; =20 ar2->channel_mask =3D channel_mask; ar2->mode_mask =3D mode_mask; =20 r =3D ati_remote2_setup(ar2, ar2->channel_mask); if (r) - goto fail2; + goto fail3; =20 usb_make_path(udev, ar2->phys, sizeof(ar2->phys)); strlcat(ar2->phys, "/input0", sizeof(ar2->phys)); @@ -842,11 +865,11 @@ static int ati_remote2_probe(struct usb_interface *in= terface, const struct usb_d =20 r =3D sysfs_create_group(&udev->dev.kobj, &ati_remote2_attr_group); if (r) - goto fail2; + goto fail3; =20 r =3D ati_remote2_input_init(ar2); if (r) - goto fail3; + goto fail4; =20 usb_set_intfdata(interface, ar2); =20 @@ -854,10 +877,11 @@ static int ati_remote2_probe(struct usb_interface *in= terface, const struct usb_d =20 return 0; =20 - fail3: + fail4: sysfs_remove_group(&udev->dev.kobj, &ati_remote2_attr_group); - fail2: + fail3: ati_remote2_urb_cleanup(ar2); + fail2: usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]); fail1: kfree(ar2); diff --git a/drivers/input/misc/powermate.c b/drivers/input/misc/powermate.c index f45947190e4f..be34cd6a5030 100644 --- a/drivers/input/misc/powermate.c +++ b/drivers/input/misc/powermate.c @@ -304,6 +304,9 @@ static int powermate_probe(struct usb_interface *intf, = const struct usb_device_i int error =3D -ENOMEM; =20 interface =3D intf->cur_altsetting; + if (interface->desc.bNumEndpoints < 1) + return -EINVAL; + endpoint =3D &interface->endpoint[0].desc; if (!usb_endpoint_is_int_in(endpoint)) return -EIO; diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptic= s.c index 91e94add0816..b72d65258061 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -674,8 +674,9 @@ static void synaptics_report_ext_buttons(struct psmouse= *psmouse, if (!SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) return; =20 - /* Bug in FW 8.1, buttons are reported only when ExtBit is 1 */ - if (SYN_ID_FULL(priv->identity) =3D=3D 0x801 && + /* Bug in FW 8.1 & 8.2, buttons are reported only when ExtBit is 1 */ + if ((SYN_ID_FULL(priv->identity) =3D=3D 0x801 || + SYN_ID_FULL(priv->identity) =3D=3D 0x802) && !((psmouse->packet[0] ^ psmouse->packet[3]) & 0x02)) return; =20 diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 09c2b4f2d512..6674ebf959fe 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -1055,6 +1055,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigne= d int argc, char **argv) int i; int r =3D -EINVAL; char *origin_path, *cow_path; + dev_t origin_dev, cow_dev; unsigned args_used, num_flush_requests =3D 1; fmode_t origin_mode =3D FMODE_READ; =20 @@ -1085,11 +1086,19 @@ static int snapshot_ctr(struct dm_target *ti, unsig= ned int argc, char **argv) ti->error =3D "Cannot get origin device"; goto bad_origin; } + origin_dev =3D s->origin->bdev->bd_dev; =20 cow_path =3D argv[0]; argv++; argc--; =20 + cow_dev =3D dm_get_dev_t(cow_path); + if (cow_dev && cow_dev =3D=3D origin_dev) { + ti->error =3D "COW device cannot be the same as origin device"; + r =3D -EINVAL; + goto bad_cow; + } + r =3D dm_get_device(ti, cow_path, dm_table_get_mode(ti->table), &s->cow); if (r) { ti->error =3D "Cannot get COW device"; diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 5c52582b0179..1e379312fa66 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -458,35 +458,50 @@ static int upgrade_mode(struct dm_dev_internal *dd, f= mode_t new_mode, } =20 /* - * Add a device to the list, or just increment the usage count if - * it's already present. + * Convert the path to a device */ -int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode, - struct dm_dev **result) +dev_t dm_get_dev_t(const char *path) { - int r; dev_t uninitialized_var(dev); - struct dm_dev_internal *dd; unsigned int major, minor; - struct dm_table *t =3D ti->table; - - BUG_ON(!t); =20 if (sscanf(path, "%u:%u", &major, &minor) =3D=3D 2) { /* Extract the major/minor numbers */ dev =3D MKDEV(major, minor); if (MAJOR(dev) !=3D major || MINOR(dev) !=3D minor) - return -EOVERFLOW; + return 0; } else { /* convert the path to a device */ struct block_device *bdev =3D lookup_bdev(path); =20 if (IS_ERR(bdev)) - return PTR_ERR(bdev); + return 0; dev =3D bdev->bd_dev; bdput(bdev); } =20 + return dev; +} +EXPORT_SYMBOL_GPL(dm_get_dev_t); + +/* + * Add a device to the list, or just increment the usage count if + * it's already present. + */ +int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode, + struct dm_dev **result) +{ + int r; + dev_t dev; + struct dm_dev_internal *dd; + struct dm_table *t =3D ti->table; + + BUG_ON(!t); + + dev =3D dm_get_dev_t(path); + if (!dev) + return -ENODEV; + dd =3D find_device(&t->devices, dev); if (!dd) { dd =3D kmalloc(sizeof(*dd), GFP_KERNEL); diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 5c8dd404b39d..7b75a1942159 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1976,6 +1976,7 @@ static void handle_write_finished(struct r1conf *conf= , struct r1bio *r1_bio) if (fail) { spin_lock_irq(&conf->device_lock); list_add(&r1_bio->retry_list, &conf->bio_end_io_list); + conf->nr_queued++; spin_unlock_irq(&conf->device_lock); md_wakeup_thread(conf->mddev->thread); } else { @@ -2090,8 +2091,10 @@ static void raid1d(struct mddev *mddev) LIST_HEAD(tmp); spin_lock_irqsave(&conf->device_lock, flags); if (!test_bit(MD_CHANGE_PENDING, &mddev->flags)) { - list_add(&tmp, &conf->bio_end_io_list); - list_del_init(&conf->bio_end_io_list); + while (!list_empty(&conf->bio_end_io_list)) { + list_move(conf->bio_end_io_list.prev, &tmp); + conf->nr_queued--; + } } spin_unlock_irqrestore(&conf->device_lock, flags); while (!list_empty(&tmp)) { diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 922b70b2fed3..8fb44da255ae 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -2241,6 +2241,7 @@ static void handle_write_completed(struct r10conf *co= nf, struct r10bio *r10_bio) if (fail) { spin_lock_irq(&conf->device_lock); list_add(&r10_bio->retry_list, &conf->bio_end_io_list); + conf->nr_queued++; spin_unlock_irq(&conf->device_lock); md_wakeup_thread(conf->mddev->thread); } else { @@ -2267,8 +2268,10 @@ static void raid10d(struct mddev *mddev) LIST_HEAD(tmp); spin_lock_irqsave(&conf->device_lock, flags); if (!test_bit(MD_CHANGE_PENDING, &mddev->flags)) { - list_add(&tmp, &conf->bio_end_io_list); - list_del_init(&conf->bio_end_io_list); + while (!list_empty(&conf->bio_end_io_list)) { + list_move(conf->bio_end_io_list.prev, &tmp); + conf->nr_queued--; + } } spin_unlock_irqrestore(&conf->device_lock, flags); while (!list_empty(&tmp)) { diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/= bt8xx/bttv-driver.c index 3dd06607aec2..a9ec08b29ced 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -2480,6 +2480,19 @@ static int bttv_g_fmt_vid_overlay(struct file *file,= void *priv, return 0; } =20 +static void bttv_get_width_mask_vid_cap(const struct bttv_format *fmt, + unsigned int *width_mask, + unsigned int *width_bias) +{ + if (fmt->flags & FORMAT_FLAGS_PLANAR) { + *width_mask =3D ~15; /* width must be a multiple of 16 pixels */ + *width_bias =3D 8; /* nearest */ + } else { + *width_mask =3D ~3; /* width must be a multiple of 4 pixels */ + *width_bias =3D 2; /* nearest */ + } +} + static int bttv_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { @@ -2488,6 +2501,7 @@ static int bttv_try_fmt_vid_cap(struct file *file, vo= id *priv, struct bttv *btv =3D fh->btv; enum v4l2_field field; __s32 width, height; + unsigned int width_mask, width_bias; int rc; =20 fmt =3D format_by_fourcc(f->fmt.pix.pixelformat); @@ -2525,9 +2539,9 @@ static int bttv_try_fmt_vid_cap(struct file *file, vo= id *priv, width =3D f->fmt.pix.width; height =3D f->fmt.pix.height; =20 + bttv_get_width_mask_vid_cap(fmt, &width_mask, &width_bias); rc =3D limit_scaled_size_lock(fh, &width, &height, field, - /* width_mask: 4 pixels */ ~3, - /* width_bias: nearest */ 2, + width_mask, width_bias, /* adjust_size */ 1, /* adjust_crop */ 0); if (0 !=3D rc) @@ -2558,6 +2572,7 @@ static int bttv_s_fmt_vid_cap(struct file *file, void= *priv, struct bttv_fh *fh =3D priv; struct bttv *btv =3D fh->btv; __s32 width, height; + unsigned int width_mask, width_bias; enum v4l2_field field; =20 retval =3D bttv_switch_type(fh, f->type); @@ -2572,9 +2587,10 @@ static int bttv_s_fmt_vid_cap(struct file *file, voi= d *priv, height =3D f->fmt.pix.height; field =3D f->fmt.pix.field; =20 + fmt =3D format_by_fourcc(f->fmt.pix.pixelformat); + bttv_get_width_mask_vid_cap(fmt, &width_mask, &width_bias); retval =3D limit_scaled_size_lock(fh, &width, &height, f->fmt.pix.field, - /* width_mask: 4 pixels */ ~3, - /* width_bias: nearest */ 2, + width_mask, width_bias, /* adjust_size */ 1, /* adjust_crop */ 1); if (0 !=3D retval) @@ -2582,8 +2598,6 @@ static int bttv_s_fmt_vid_cap(struct file *file, void= *priv, =20 f->fmt.pix.field =3D field; =20 - fmt =3D format_by_fourcc(f->fmt.pix.pixelformat); - /* update our state informations */ fh->fmt =3D fmt; fh->cap.field =3D f->fmt.pix.field; diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc= -if.c index 01ff643e682d..ce1e0e8b7532 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c @@ -91,6 +91,7 @@ static const struct usb_device_id pwc_device_table [] =3D= { { USB_DEVICE(0x0471, 0x0312) }, { USB_DEVICE(0x0471, 0x0313) }, /* the 'new' 720K */ { USB_DEVICE(0x0471, 0x0329) }, /* Philips SPC 900NC PC Camera */ + { USB_DEVICE(0x0471, 0x032C) }, /* Philips SPC 880NC PC Camera */ { USB_DEVICE(0x069A, 0x0001) }, /* Askey */ { USB_DEVICE(0x046D, 0x08B0) }, /* Logitech QuickCam Pro 3000 */ { USB_DEVICE(0x046D, 0x08B1) }, /* Logitech QuickCam Notebook Pro */ @@ -965,6 +966,11 @@ static int usb_pwc_probe(struct usb_interface *intf, c= onst struct usb_device_id name =3D "Philips SPC 900NC webcam"; type_id =3D 740; break; + case 0x032C: + PWC_INFO("Philips SPC 880NC USB webcam detected.\n"); + name =3D "Philips SPC 880NC webcam"; + type_id =3D 740; + break; default: return -ENODEV; break; diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/vi= deo/saa7134/saa7134-video.c index 9cf7914f6f90..dd830a5c9d08 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c @@ -1577,10 +1577,13 @@ static int saa7134_g_fmt_vid_cap(struct file *file,= void *priv, f->fmt.pix.height =3D fh->height; f->fmt.pix.field =3D fh->cap.field; f->fmt.pix.pixelformat =3D fh->fmt->fourcc; - f->fmt.pix.bytesperline =3D - (f->fmt.pix.width * fh->fmt->depth) >> 3; + if (fh->fmt->planar) + f->fmt.pix.bytesperline =3D f->fmt.pix.width; + else + f->fmt.pix.bytesperline =3D + (f->fmt.pix.width * fh->fmt->depth) / 8; f->fmt.pix.sizeimage =3D - f->fmt.pix.height * f->fmt.pix.bytesperline; + (f->fmt.pix.height * f->fmt.pix.width * fh->fmt->depth) / 8; return 0; } =20 @@ -1641,10 +1644,13 @@ static int saa7134_try_fmt_vid_cap(struct file *fil= e, void *priv, if (f->fmt.pix.height > maxh) f->fmt.pix.height =3D maxh; f->fmt.pix.width &=3D ~0x03; - f->fmt.pix.bytesperline =3D - (f->fmt.pix.width * fmt->depth) >> 3; + if (fmt->planar) + f->fmt.pix.bytesperline =3D f->fmt.pix.width; + else + f->fmt.pix.bytesperline =3D + (f->fmt.pix.width * fmt->depth) / 8; f->fmt.pix.sizeimage =3D - f->fmt.pix.height * f->fmt.pix.bytesperline; + (f->fmt.pix.height * f->fmt.pix.width * fmt->depth) / 8; =20 return 0; } diff --git a/drivers/misc/ad525x_dpot.c b/drivers/misc/ad525x_dpot.c index 7cb911028d09..dfa1c2069dc3 100644 --- a/drivers/misc/ad525x_dpot.c +++ b/drivers/misc/ad525x_dpot.c @@ -218,7 +218,7 @@ static s32 dpot_read_i2c(struct dpot_data *dpot, u8 reg) */ value =3D swab16(value); =20 - if (dpot->uid =3D=3D DPOT_UID(AD5271_ID)) + if (dpot->uid =3D=3D DPOT_UID(AD5274_ID)) value =3D value >> 2; return value; default: diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c index ab784e09187b..7583fe1f9cb8 100644 --- a/drivers/net/ethernet/jme.c +++ b/drivers/net/ethernet/jme.c @@ -269,11 +269,17 @@ jme_reset_mac_processor(struct jme_adapter *jme) } =20 static inline void -jme_clear_pm(struct jme_adapter *jme) +jme_clear_pm_enable_wol(struct jme_adapter *jme) { jwrite32(jme, JME_PMCS, PMCS_STMASK | jme->reg_pmcs); } =20 +static inline void +jme_clear_pm_disable_wol(struct jme_adapter *jme) +{ + jwrite32(jme, JME_PMCS, PMCS_STMASK); +} + static int jme_reload_eeprom(struct jme_adapter *jme) { @@ -1856,7 +1862,7 @@ jme_open(struct net_device *netdev) struct jme_adapter *jme =3D netdev_priv(netdev); int rc; =20 - jme_clear_pm(jme); + jme_clear_pm_disable_wol(jme); JME_NAPI_ENABLE(jme); =20 tasklet_enable(&jme->linkch_task); @@ -1924,11 +1930,11 @@ jme_wait_link(struct jme_adapter *jme) static void jme_powersave_phy(struct jme_adapter *jme) { - if (jme->reg_pmcs) { + if (jme->reg_pmcs && device_may_wakeup(&jme->pdev->dev)) { jme_set_100m_half(jme); if (jme->reg_pmcs & (PMCS_LFEN | PMCS_LREN)) jme_wait_link(jme); - jme_clear_pm(jme); + jme_clear_pm_enable_wol(jme); } else { jme_phy_off(jme); } @@ -2616,9 +2622,6 @@ jme_set_wol(struct net_device *netdev, if (wol->wolopts & WAKE_MAGIC) jme->reg_pmcs |=3D PMCS_MFEN; =20 - jwrite32(jme, JME_PMCS, jme->reg_pmcs); - device_set_wakeup_enable(&jme->pdev->dev, !!(jme->reg_pmcs)); - return 0; } =20 @@ -3142,9 +3145,9 @@ jme_init_one(struct pci_dev *pdev, jme->mii_if.mdio_read =3D jme_mdio_read; jme->mii_if.mdio_write =3D jme_mdio_write; =20 - jme_clear_pm(jme); + jme_clear_pm_disable_wol(jme); pci_set_power_state(jme->pdev, PCI_D0); - device_set_wakeup_enable(&pdev->dev, true); + device_init_wakeup(&pdev->dev, true); =20 jme_set_phyfifo_5level(jme); jme->pcirev =3D pdev->revision; @@ -3277,7 +3280,7 @@ jme_resume(struct device *dev) if (!netif_running(netdev)) return 0; =20 - jme_clear_pm(jme); + jme_clear_pm_disable_wol(jme); jme_phy_on(jme); if (test_bit(JME_FLAG_SSET, &jme->flags)) jme_set_settings(netdev, &jme->old_ecmd); @@ -3285,13 +3288,14 @@ jme_resume(struct device *dev) jme_reset_phy_processor(jme); jme_phy_calibration(jme); jme_phy_setEA(jme); - jme_start_irq(jme); netif_device_attach(netdev); =20 atomic_inc(&jme->link_changing); =20 jme_reset_link(jme); =20 + jme_start_irq(jme); + return 0; } =20 diff --git a/drivers/net/ethernet/micrel/ks8842.c b/drivers/net/ethernet/mi= crel/ks8842.c index 4a6ae057e3b1..22ab0989c693 100644 --- a/drivers/net/ethernet/micrel/ks8842.c +++ b/drivers/net/ethernet/micrel/ks8842.c @@ -562,8 +562,8 @@ static int __ks8842_start_new_rx_dma(struct net_device = *netdev) sg_init_table(sg, 1); sg_dma_address(sg) =3D dma_map_single(adapter->dev, ctl->skb->data, DMA_BUFFER_SIZE, DMA_FROM_DEVICE); - err =3D dma_mapping_error(adapter->dev, sg_dma_address(sg)); - if (unlikely(err)) { + if (dma_mapping_error(adapter->dev, sg_dma_address(sg))) { + err =3D -ENOMEM; sg_dma_address(sg) =3D 0; goto out; } @@ -574,8 +574,10 @@ static int __ks8842_start_new_rx_dma(struct net_device= *netdev) sg, 1, DMA_FROM_DEVICE, DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_SRC_UNMAP); =20 - if (!ctl->adesc) + if (!ctl->adesc) { + err =3D -ENOMEM; goto out; + } =20 ctl->adesc->callback_param =3D netdev; ctl->adesc->callback =3D ks8842_dma_rx_cb; @@ -586,7 +588,7 @@ static int __ks8842_start_new_rx_dma(struct net_device = *netdev) goto out; } =20 - return err; + return 0; out: if (sg_dma_address(sg)) dma_unmap_single(adapter->dev, sg_dma_address(sg), diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/eth= ernet/qlogic/qlge/qlge_main.c index c92afcd912e2..6ca1481d75e7 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c @@ -1622,7 +1622,18 @@ static void ql_process_mac_rx_skb(struct ql_adapter = *qdev, return; } skb_reserve(new_skb, NET_IP_ALIGN); + + pci_dma_sync_single_for_cpu(qdev->pdev, + dma_unmap_addr(sbq_desc, mapaddr), + dma_unmap_len(sbq_desc, maplen), + PCI_DMA_FROMDEVICE); + memcpy(skb_put(new_skb, length), skb->data, length); + + pci_dma_sync_single_for_device(qdev->pdev, + dma_unmap_addr(sbq_desc, mapaddr), + dma_unmap_len(sbq_desc, maplen), + PCI_DMA_FROMDEVICE); skb =3D new_skb; =20 /* Frame error, so drop the packet. */ diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/r= enesas/sh_eth.c index 9842fd92c483..85170f105568 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -681,7 +681,8 @@ static void sh_eth_ring_format(struct net_device *ndev) mdp->dirty_rx =3D (u32) (i - RX_RING_SIZE); =20 /* Mark the last entry as wrapping the ring. */ - rxdesc->status |=3D cpu_to_edmac(mdp, RD_RDEL); + if (rxdesc) + rxdesc->status |=3D cpu_to_edmac(mdp, RD_RDEL); =20 memset(mdp->tx_ring, 0, tx_ringsize); =20 diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c index 3352b2443e58..9b40cd20edc6 100644 --- a/drivers/net/irda/irtty-sir.c +++ b/drivers/net/irda/irtty-sir.c @@ -430,16 +430,6 @@ static int irtty_open(struct tty_struct *tty) =20 /* Module stuff handled via irda_ldisc.owner - Jean II */ =20 - /* First make sure we're not already connected. */ - if (tty->disc_data !=3D NULL) { - priv =3D tty->disc_data; - if (priv && priv->magic =3D=3D IRTTY_MAGIC) { - ret =3D -EEXIST; - goto out; - } - tty->disc_data =3D NULL; /* ### */ - } - /* stop the underlying driver */ irtty_stop_receiver(tty, TRUE); if (tty->ops->stop) diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 7300447eb4c7..2fcdedefce42 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -720,6 +720,8 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q= , struct msghdr *m, copylen =3D vnet_hdr.hdr_len ? vnet_hdr.hdr_len : GOODCOPY_LEN; if (copylen > good_linear) copylen =3D good_linear; + else if (copylen < ETH_HLEN) + copylen =3D ETH_HLEN; linear =3D copylen; if (iov_pages(iv, vnet_hdr_len + copylen, count) <=3D MAX_SKB_FRAGS) @@ -728,10 +730,11 @@ static ssize_t macvtap_get_user(struct macvtap_queue = *q, struct msghdr *m, =20 if (!zerocopy) { copylen =3D len; - if (vnet_hdr.hdr_len > good_linear) + linear =3D vnet_hdr.hdr_len; + if (linear > good_linear) linear =3D good_linear; - else - linear =3D vnet_hdr.hdr_len; + else if (linear < ETH_HLEN) + linear =3D ETH_HLEN; } =20 skb =3D macvtap_alloc_skb(&q->sk, MACVTAP_RESERVE, copylen, diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c index bb335ab9981c..2a0178db7ece 100644 --- a/drivers/net/phy/dp83640.c +++ b/drivers/net/phy/dp83640.c @@ -680,6 +680,11 @@ static void decode_rxts(struct dp83640_private *dp8364= 0, { struct rxts *rxts; unsigned long flags; + u8 overflow; + + overflow =3D (phy_rxts->ns_hi >> 14) & 0x3; + if (overflow) + pr_debug("rx timestamp queue overflow, count %d\n", overflow); =20 spin_lock_irqsave(&dp83640->rx_lock, flags); =20 @@ -703,6 +708,7 @@ static void decode_txts(struct dp83640_private *dp83640, struct skb_shared_hwtstamps shhwtstamps; struct sk_buff *skb; u64 ns; + u8 overflow; =20 /* We must already have the skb that triggered this. */ =20 @@ -712,6 +718,17 @@ static void decode_txts(struct dp83640_private *dp8364= 0, pr_debug("dp83640: have timestamp but tx_queue empty\n"); return; } + + overflow =3D (phy_txts->ns_hi >> 14) & 0x3; + if (overflow) { + pr_debug("tx timestamp queue overflow, count %d\n", overflow); + while (skb) { + skb_complete_tx_timestamp(skb, NULL); + skb =3D skb_dequeue(&dp83640->tx_queue); + } + return; + } + ns =3D phy2txts(phy_txts); memset(&shhwtstamps, 0, sizeof(shhwtstamps)); shhwtstamps.hwtstamp =3D ns_to_ktime(ns); diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index 82d44215bb33..9907ac78aed0 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -555,7 +555,7 @@ static int get_filter(void __user *arg, struct sock_fil= ter **p) =20 static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long a= rg) { - struct ppp_file *pf =3D file->private_data; + struct ppp_file *pf; struct ppp *ppp; int err =3D -EFAULT, val, val2, i; struct ppp_idle idle; @@ -565,9 +565,14 @@ static long ppp_ioctl(struct file *file, unsigned int = cmd, unsigned long arg) void __user *argp =3D (void __user *)arg; int __user *p =3D argp; =20 - if (!pf) - return ppp_unattached_ioctl(current->nsproxy->net_ns, - pf, file, cmd, arg); + mutex_lock(&ppp_mutex); + + pf =3D file->private_data; + if (!pf) { + err =3D ppp_unattached_ioctl(current->nsproxy->net_ns, + pf, file, cmd, arg); + goto out; + } =20 if (cmd =3D=3D PPPIOCDETACH) { /* @@ -582,7 +587,6 @@ static long ppp_ioctl(struct file *file, unsigned int c= md, unsigned long arg) * this fd and reopening /dev/ppp. */ err =3D -EINVAL; - mutex_lock(&ppp_mutex); if (pf->kind =3D=3D INTERFACE) { ppp =3D PF_TO_PPP(pf); if (file =3D=3D ppp->owner) @@ -594,15 +598,13 @@ static long ppp_ioctl(struct file *file, unsigned int= cmd, unsigned long arg) } else pr_warn("PPPIOCDETACH file->f_count=3D%ld\n", atomic_long_read(&file->f_count)); - mutex_unlock(&ppp_mutex); - return err; + goto out; } =20 if (pf->kind =3D=3D CHANNEL) { struct channel *pch; struct ppp_channel *chan; =20 - mutex_lock(&ppp_mutex); pch =3D PF_TO_CHANNEL(pf); =20 switch (cmd) { @@ -624,17 +626,16 @@ static long ppp_ioctl(struct file *file, unsigned int= cmd, unsigned long arg) err =3D chan->ops->ioctl(chan, cmd, arg); up_read(&pch->chan_sem); } - mutex_unlock(&ppp_mutex); - return err; + goto out; } =20 if (pf->kind !=3D INTERFACE) { /* can't happen */ pr_err("PPP: not interface or channel??\n"); - return -EINVAL; + err =3D -EINVAL; + goto out; } =20 - mutex_lock(&ppp_mutex); ppp =3D PF_TO_PPP(pf); switch (cmd) { case PPPIOCSMRU: @@ -781,7 +782,10 @@ static long ppp_ioctl(struct file *file, unsigned int = cmd, unsigned long arg) default: err =3D -ENOTTY; } + +out: mutex_unlock(&ppp_mutex); + return err; } =20 @@ -794,7 +798,6 @@ static int ppp_unattached_ioctl(struct net *net, struct= ppp_file *pf, struct ppp_net *pn; int __user *p =3D (int __user *)arg; =20 - mutex_lock(&ppp_mutex); switch (cmd) { case PPPIOCNEWUNIT: /* Create a new ppp unit */ @@ -845,7 +848,7 @@ static int ppp_unattached_ioctl(struct net *net, struct= ppp_file *pf, default: err =3D -ENOTTY; } - mutex_unlock(&ppp_mutex); + return err; } =20 @@ -2175,7 +2178,7 @@ int ppp_register_net_channel(struct net *net, struct = ppp_channel *chan) =20 pch->ppp =3D NULL; pch->chan =3D chan; - pch->chan_net =3D net; + pch->chan_net =3D get_net(net); chan->ppp =3D pch; init_ppp_file(&pch->file, CHANNEL); pch->file.hdrlen =3D chan->hdrlen; @@ -2272,6 +2275,8 @@ ppp_unregister_channel(struct ppp_channel *chan) spin_lock_bh(&pn->all_channels_lock); list_del(&pch->list); spin_unlock_bh(&pn->all_channels_lock); + put_net(pch->chan_net); + pch->chan_net =3D NULL; =20 pch->file.dead =3D 1; wake_up_interruptible(&pch->file.rwait); diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c index 0f4a04d35e9f..239e6e71781c 100644 --- a/drivers/net/ppp/pppoe.c +++ b/drivers/net/ppp/pppoe.c @@ -398,6 +398,8 @@ static int pppoe_rcv_core(struct sock *sk, struct sk_bu= ff *skb) =20 if (!__pppoe_xmit(sk_pppox(relay_po), skb)) goto abort_put; + + sock_put(sk_pppox(relay_po)); } else { if (sock_queue_rcv_skb(sk, skb)) goto abort_kfree; diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c index c0f097b19403..66cd4ce02312 100644 --- a/drivers/net/rionet.c +++ b/drivers/net/rionet.c @@ -269,7 +269,7 @@ static void rionet_outb_msg_event(struct rio_mport *mpo= rt, void *dev_id, int mbo struct net_device *ndev =3D dev_id; struct rionet_private *rnet =3D netdev_priv(ndev); =20 - spin_lock(&rnet->lock); + spin_lock(&rnet->tx_lock); =20 if (netif_msg_intr(rnet)) printk(KERN_INFO @@ -288,7 +288,7 @@ static void rionet_outb_msg_event(struct rio_mport *mpo= rt, void *dev_id, int mbo if (rnet->tx_cnt < RIONET_TX_RING_SIZE) netif_wake_queue(ndev); =20 - spin_unlock(&rnet->lock); + spin_unlock(&rnet->tx_lock); } =20 static int rionet_open(struct net_device *ndev) diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index f06fb78383a1..56160cbd5512 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -550,7 +550,11 @@ advance: =20 iface_no =3D ctx->data->cur_altsetting->desc.bInterfaceNumber; =20 - /* reset data interface */ + /* Reset data interface. Some devices will not reset properly + * unless they are configured first. Toggle the altsetting to + * force a reset + */ + usb_set_interface(dev->udev, iface_no, 1); temp =3D usb_set_interface(dev->udev, iface_no, 0); if (temp) goto error2; diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 3d217421c016..8a6398bdd21a 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1486,6 +1486,13 @@ out3: if (info->unbind) info->unbind (dev, udev); out1: + /* subdrivers must undo all they did in bind() if they + * fail it, but we may fail later and a deferred kevent + * may trigger an error resubmitting itself and, worse, + * schedule a timer. So we kill it all just in case. + */ + cancel_work_sync(&dev->kevent); + del_timer_sync(&dev->delay); free_netdev(net); out: usb_put_dev(xdev); diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c index 7a4c49145034..7d3fd932add7 100644 --- a/drivers/net/wan/farsync.c +++ b/drivers/net/wan/farsync.c @@ -2546,7 +2546,7 @@ fst_add_one(struct pci_dev *pdev, const struct pci_de= vice_id *ent) dev->mem_start =3D card->phys_mem + BUF_OFFSET ( txBuffer[i][0][0]); dev->mem_end =3D card->phys_mem - + BUF_OFFSET ( txBuffer[i][NUM_TX_BUFFER]= [0]); + + BUF_OFFSET ( txBuffer[i][NUM_TX_BUFFER = - 1][LEN_RX_BUFFER - 1]); dev->base_addr =3D card->pci_conf; dev->irq =3D card->irq; =20 diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless= /ath/ath9k/eeprom.c index e46f751ab508..b62f08cf5b8c 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.c +++ b/drivers/net/wireless/ath/ath9k/eeprom.c @@ -364,10 +364,9 @@ void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw= *ah, =20 if (match) { if (AR_SREV_9287(ah)) { - /* FIXME: array overrun? */ for (i =3D 0; i < numXpdGains; i++) { minPwrT4[i] =3D data_9287[idxL].pwrPdg[i][0]; - maxPwrT4[i] =3D data_9287[idxL].pwrPdg[i][4]; + maxPwrT4[i] =3D data_9287[idxL].pwrPdg[i][intercepts - 1]; ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], data_9287[idxL].pwrPdg[i], data_9287[idxL].vpdPdg[i], @@ -377,7 +376,7 @@ void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw = *ah, } else if (eeprom_4k) { for (i =3D 0; i < numXpdGains; i++) { minPwrT4[i] =3D data_4k[idxL].pwrPdg[i][0]; - maxPwrT4[i] =3D data_4k[idxL].pwrPdg[i][4]; + maxPwrT4[i] =3D data_4k[idxL].pwrPdg[i][intercepts - 1]; ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], data_4k[idxL].pwrPdg[i], data_4k[idxL].vpdPdg[i], @@ -387,7 +386,7 @@ void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw = *ah, } else { for (i =3D 0; i < numXpdGains; i++) { minPwrT4[i] =3D data_def[idxL].pwrPdg[i][0]; - maxPwrT4[i] =3D data_def[idxL].pwrPdg[i][4]; + maxPwrT4[i] =3D data_def[idxL].pwrPdg[i][intercepts - 1]; ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], data_def[idxL].pwrPdg[i], data_def[idxL].vpdPdg[i], diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index bc92c4771e57..fbf3be17239d 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -136,6 +136,9 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_t= ype type, u32 l, sz, mask; u16 orig_cmd; =20 + if (dev->non_compliant_bars) + return 0; + mask =3D type ? PCI_ROM_ADDRESS_MASK : ~0; =20 if (!dev->mmio_always_on) { @@ -902,6 +905,7 @@ void set_pcie_hotplug_bridge(struct pci_dev *pdev) int pci_setup_device(struct pci_dev *dev) { u32 class; + u16 cmd; u8 hdr_type; struct pci_slot *slot; int pos =3D 0; @@ -949,6 +953,16 @@ int pci_setup_device(struct pci_dev *dev) /* device class may be changed after fixup */ class =3D dev->class >> 8; =20 + if (dev->non_compliant_bars) { + pci_read_config_word(dev, PCI_COMMAND, &cmd); + if (cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { + dev_info(&dev->dev, "device has non-compliant BARs; disabling IO/MEM de= coding\n"); + cmd &=3D ~PCI_COMMAND_IO; + cmd &=3D ~PCI_COMMAND_MEMORY; + pci_write_config_word(dev, PCI_COMMAND, cmd); + } + } + switch (dev->hdr_type) { /* header type */ case PCI_HEADER_TYPE_NORMAL: /* standard header */ if (class =3D=3D PCI_CLASS_BRIDGE_PCI) diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c index c5698cda366a..27da0778b580 100644 --- a/drivers/rtc/rtc-vr41xx.c +++ b/drivers/rtc/rtc-vr41xx.c @@ -272,12 +272,13 @@ static irqreturn_t rtclong1_interrupt(int irq, void *= dev_id) } =20 static const struct rtc_class_ops vr41xx_rtc_ops =3D { - .release =3D vr41xx_rtc_release, - .ioctl =3D vr41xx_rtc_ioctl, - .read_time =3D vr41xx_rtc_read_time, - .set_time =3D vr41xx_rtc_set_time, - .read_alarm =3D vr41xx_rtc_read_alarm, - .set_alarm =3D vr41xx_rtc_set_alarm, + .release =3D vr41xx_rtc_release, + .ioctl =3D vr41xx_rtc_ioctl, + .read_time =3D vr41xx_rtc_read_time, + .set_time =3D vr41xx_rtc_set_time, + .read_alarm =3D vr41xx_rtc_read_alarm, + .set_alarm =3D vr41xx_rtc_set_alarm, + .alarm_irq_enable =3D vr41xx_rtc_alarm_irq_enable, }; =20 static int __devinit rtc_probe(struct platform_device *pdev) diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index e5f2d7d9002e..43e58c2cc35c 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -83,9 +83,12 @@ static int fib_map_alloc(struct aac_dev *dev) =20 void aac_fib_map_free(struct aac_dev *dev) { - pci_free_consistent(dev->pdev, - dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB), - dev->hw_fib_va, dev->hw_fib_pa); + if (dev->hw_fib_va && dev->max_fib_size) { + pci_free_consistent(dev->pdev, + (dev->max_fib_size * + (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB)), + dev->hw_fib_va, dev->hw_fib_pa); + } dev->hw_fib_va =3D NULL; dev->hw_fib_pa =3D 0; } diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_mai= n.c index b9ee9f370782..51e6fc0d6d9e 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -3607,6 +3607,7 @@ put_shost: scsi_host_put(phba->shost); free_kset: iscsi_boot_destroy_kset(phba->boot_kset); + phba->boot_kset =3D NULL; return -ENOMEM; } =20 diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 55bc4fc7376f..12ee398a4d7c 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -2526,7 +2526,7 @@ lpfc_online(struct lpfc_hba *phba) } =20 vports =3D lpfc_create_vport_work_array(phba); - if (vports !=3D NULL) + if (vports !=3D NULL) { for (i =3D 0; i <=3D phba->max_vports && vports[i] !=3D NULL; i++) { struct Scsi_Host *shost; shost =3D lpfc_shost_from_vport(vports[i]); @@ -2538,7 +2538,8 @@ lpfc_online(struct lpfc_hba *phba) vports[i]->fc_flag |=3D FC_VPORT_NEEDS_INIT_VPI; spin_unlock_irq(shost->host_lock); } - lpfc_destroy_vport_work_array(phba, vports); + } + lpfc_destroy_vport_work_array(phba, vports); =20 lpfc_unblock_mgmt_io(phba); return 0; diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 9a4f52d8e1db..614f2cd24b7f 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1051,18 +1051,19 @@ static int sd_getgeo(struct block_device *bdev, str= uct hd_geometry *geo) struct scsi_disk *sdkp =3D scsi_disk(bdev->bd_disk); struct scsi_device *sdp =3D sdkp->device; struct Scsi_Host *host =3D sdp->host; + sector_t capacity =3D logical_to_sectors(sdp, sdkp->capacity); int diskinfo[4]; =20 /* default to most commonly used values */ - diskinfo[0] =3D 0x40; /* 1 << 6 */ - diskinfo[1] =3D 0x20; /* 1 << 5 */ - diskinfo[2] =3D sdkp->capacity >> 11; -=09 + diskinfo[0] =3D 0x40; /* 1 << 6 */ + diskinfo[1] =3D 0x20; /* 1 << 5 */ + diskinfo[2] =3D capacity >> 11; + /* override with calculated, extended default, or driver values */ if (host->hostt->bios_param) - host->hostt->bios_param(sdp, bdev, sdkp->capacity, diskinfo); + host->hostt->bios_param(sdp, bdev, capacity, diskinfo); else - scsicam_bios_param(bdev, sdkp->capacity, diskinfo); + scsicam_bios_param(bdev, capacity, diskinfo); =20 geo->heads =3D diskinfo[0]; geo->sectors =3D diskinfo[1]; @@ -1931,14 +1932,6 @@ got_data: } } =20 - /* Rescale capacity to 512-byte units */ - if (sector_size =3D=3D 4096) - sdkp->capacity <<=3D 3; - else if (sector_size =3D=3D 2048) - sdkp->capacity <<=3D 2; - else if (sector_size =3D=3D 1024) - sdkp->capacity <<=3D 1; - blk_queue_physical_block_size(sdp->request_queue, sdkp->physical_block_size); sdkp->device->sector_size =3D sector_size; @@ -2416,7 +2409,7 @@ static int sd_revalidate_disk(struct gendisk *disk) =20 blk_queue_flush(sdkp->disk->queue, flush); =20 - set_capacity(disk, sdkp->capacity); + set_capacity(disk, logical_to_sectors(sdp, sdkp->capacity)); kfree(buffer); =20 out: diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index e3e3cd2dfda0..5bff88fe92a8 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -52,7 +52,7 @@ struct scsi_disk { struct device dev; struct gendisk *disk; atomic_t openers; - sector_t capacity; /* size in 512-byte sectors */ + sector_t capacity; /* size in logical blocks */ u32 max_ws_blocks; u32 max_unmap_blocks; u32 unmap_granularity; @@ -89,6 +89,11 @@ static inline struct scsi_disk *scsi_disk(struct gendisk= *disk) (sdsk)->disk->disk_name, ##a) : \ sdev_printk(prefix, (sdsk)->device, fmt, ##a) =20 +static inline sector_t logical_to_sectors(struct scsi_device *sdev, sector= _t blocks) +{ + return blocks << (ilog2(sdev->sector_size) - 9); +} + /* * A DIF-capable target device can be formatted with different * protection schemes. Currently 0 through 3 are defined: diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index b4cac3943f35..fddce4eefcd2 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -609,7 +609,8 @@ sg_write(struct file *filp, const char __user *buf, siz= e_t count, loff_t * ppos) else hp->dxfer_direction =3D (mxsize > 0) ? SG_DXFER_FROM_DEV : SG_DXFER_NONE; hp->dxfer_len =3D mxsize; - if (hp->dxfer_direction =3D=3D SG_DXFER_TO_DEV) + if ((hp->dxfer_direction =3D=3D SG_DXFER_TO_DEV) || + (hp->dxfer_direction =3D=3D SG_DXFER_TO_FROM_DEV)) hp->dxferp =3D (char __user *)buf + cmd_size; else hp->dxferp =3D NULL; diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/u= sbip_common.c index 194e974051f3..4fbef0c28343 100644 --- a/drivers/staging/usbip/usbip_common.c +++ b/drivers/staging/usbip/usbip_common.c @@ -820,6 +820,17 @@ int usbip_recv_xbuff(struct usbip_device *ud, struct u= rb *urb) if (!(size > 0)) return 0; =20 + if (size > urb->transfer_buffer_length) { + /* should not happen, probably malicious packet */ + if (ud->side =3D=3D USBIP_STUB) { + usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); + return 0; + } else { + usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); + return -EPIPE; + } + } + ret =3D usbip_xmit(0, ud->tcp_socket, (char *)urb->transfer_buffer, size, 0); if (ret !=3D size) { diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c index 33601f891fd7..07cfec56db00 100644 --- a/drivers/tty/serial/8250.c +++ b/drivers/tty/serial/8250.c @@ -777,22 +777,16 @@ static int size_fifo(struct uart_8250_port *up) */ static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p) { - unsigned char old_dll, old_dlm, old_lcr; - unsigned int id; + unsigned char old_lcr; + unsigned int id, old_dl; =20 old_lcr =3D serial_inp(p, UART_LCR); serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_A); + old_dl =3D serial_dl_read(p); + serial_dl_write(p, 0); + id =3D serial_dl_read(p); + serial_dl_write(p, old_dl); =20 - old_dll =3D serial_inp(p, UART_DLL); - old_dlm =3D serial_inp(p, UART_DLM); - - serial_outp(p, UART_DLL, 0); - serial_outp(p, UART_DLM, 0); - - id =3D serial_inp(p, UART_DLL) | serial_inp(p, UART_DLM) << 8; - - serial_outp(p, UART_DLL, old_dll); - serial_outp(p, UART_DLM, old_dlm); serial_outp(p, UART_LCR, old_lcr); =20 return id; diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 829e51a20eee..07c01348eb35 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include @@ -95,8 +94,6 @@ struct sci_port { unsigned int rx_timeout; #endif =20 - struct notifier_block freq_transition; - #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE unsigned short saved_smr; unsigned short saved_fcr; @@ -958,30 +955,6 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *= ptr) return ret; } =20 -/* - * Here we define a transition notifier so that we can update all of our - * ports' baud rate when the peripheral clock changes. - */ -static int sci_notifier(struct notifier_block *self, - unsigned long phase, void *p) -{ - struct sci_port *sci_port; - unsigned long flags; - - sci_port =3D container_of(self, struct sci_port, freq_transition); - - if ((phase =3D=3D CPUFREQ_POSTCHANGE) || - (phase =3D=3D CPUFREQ_RESUMECHANGE)) { - struct uart_port *port =3D &sci_port->port; - - spin_lock_irqsave(&port->lock, flags); - port->uartclk =3D clk_get_rate(sci_port->iclk); - spin_unlock_irqrestore(&port->lock, flags); - } - - return NOTIFY_OK; -} - static struct sci_irq_desc { const char *desc; irq_handler_t handler; @@ -2171,9 +2144,6 @@ static int sci_remove(struct platform_device *dev) { struct sci_port *port =3D platform_get_drvdata(dev); =20 - cpufreq_unregister_notifier(&port->freq_transition, - CPUFREQ_TRANSITION_NOTIFIER); - uart_remove_one_port(&sci_uart_driver, &port->port); =20 clk_put(port->iclk); @@ -2227,13 +2197,6 @@ static int __devinit sci_probe(struct platform_devic= e *dev) if (ret) goto err_unreg; =20 - sp->freq_transition.notifier_call =3D sci_notifier; - - ret =3D cpufreq_register_notifier(&sp->freq_transition, - CPUFREQ_TRANSITION_NOTIFIER); - if (unlikely(ret < 0)) - goto err_unreg; - #ifdef CONFIG_SH_STANDARD_BIOS sh_bios_gdb_detach(); #endif diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index bbb217495917..3d96de0b278c 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -926,6 +926,9 @@ static int acm_probe(struct usb_interface *intf, if (quirks =3D=3D NO_UNION_NORMAL) { data_interface =3D usb_ifnum_to_if(usb_dev, 1); control_interface =3D usb_ifnum_to_if(usb_dev, 0); + /* we would crash */ + if (!data_interface || !control_interface) + return -ENODEV; goto skip_normal_probe; } =20 diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index c105ba32ff02..c5957142d26b 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -428,9 +428,13 @@ static int usb_unbind_interface(struct device *dev) int usb_driver_claim_interface(struct usb_driver *driver, struct usb_interface *iface, void *priv) { - struct device *dev =3D &iface->dev; + struct device *dev; int retval =3D 0; =20 + if (!iface) + return -ENODEV; + + dev =3D &iface->dev; if (dev->driver) return -EBUSY; =20 diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index dde03309396a..676324aacd92 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -3033,7 +3033,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device= *udev, int port1, =20 struct usb_device *hdev =3D hub->hdev; struct usb_hcd *hcd =3D bus_to_hcd(hdev->bus); - int i, j, retval; + int retries, operations, retval, i; unsigned delay =3D HUB_SHORT_RESET_TIME; enum usb_device_speed oldspeed =3D udev->speed; const char *speed; @@ -3135,7 +3135,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device= *udev, int port1, * first 8 bytes of the device descriptor to get the ep0 maxpacket * value. */ - for (i =3D 0; i < GET_DESCRIPTOR_TRIES; (++i, msleep(100))) { + for (retries =3D 0; retries < GET_DESCRIPTOR_TRIES; (++retries, msleep(10= 0))) { if (USE_NEW_SCHEME(retry_counter) && !(hcd->driver->flags & HCD_USB3)) { struct usb_device_descriptor *buf; int r =3D 0; @@ -3151,7 +3151,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device= *udev, int port1, * 255 is for WUSB devices, we actually need to use * 512 (WUSB1.0[4.8.1]). */ - for (j =3D 0; j < 3; ++j) { + for (operations =3D 0; operations < 3; ++operations) { buf->bMaxPacketSize0 =3D 0; r =3D usb_control_msg(udev, usb_rcvaddr0pipe(), USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, @@ -3171,7 +3171,13 @@ hub_port_init (struct usb_hub *hub, struct usb_devic= e *udev, int port1, r =3D -EPROTO; break; } - if (r =3D=3D 0) + /* + * Some devices time out if they are powered on + * when already connected. They need a second + * reset. But only on the first attempt, + * lest we get into a time out/reset loop + */ + if (r =3D=3D 0 || (r =3D=3D -ETIMEDOUT && retries =3D=3D 0)) break; } udev->descriptor.bMaxPacketSize0 =3D @@ -3203,7 +3209,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device= *udev, int port1, * authorization will assign the final address. */ if (udev->wusb =3D=3D 0) { - for (j =3D 0; j < SET_ADDRESS_TRIES; ++j) { + for (operations =3D 0; operations < SET_ADDRESS_TRIES; ++operations) { retval =3D hub_set_address(udev, devnum); if (retval >=3D 0) break; diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index 81457904d6ba..2fce7197fa7b 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c @@ -792,6 +792,12 @@ static int iowarrior_probe(struct usb_interface *inter= face, iface_desc =3D interface->cur_altsetting; dev->product_id =3D le16_to_cpu(udev->descriptor.idProduct); =20 + if (iface_desc->desc.bNumEndpoints < 1) { + dev_err(&interface->dev, "Invalid number of endpoints\n"); + retval =3D -EINVAL; + goto error; + } + /* set up the endpoint information */ for (i =3D 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint =3D &iface_desc->endpoint[i].desc; diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/f= ifo.c index ffdf5d15085e..6fb551476cca 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c @@ -166,7 +166,8 @@ static int usbhsf_pkt_handler(struct usbhs_pipe *pipe, = int type) goto __usbhs_pkt_handler_end; } =20 - ret =3D func(pkt, &is_done); + if (likely(func)) + ret =3D func(pkt, &is_done); =20 if (is_done) __usbhsf_pkt_del(pkt); @@ -931,6 +932,7 @@ static int usbhsf_dma_try_pop(struct usbhs_pkt *pkt, in= t *is_done) =20 pkt->trans =3D len; =20 + usbhsf_tx_irq_ctrl(pipe, 0); tasklet_init(&fifo->tasklet, usbhsf_dma_prepare_tasklet, (unsigned long)pkt); diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 9b43535cd182..645687c08baf 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -170,6 +170,7 @@ static const struct usb_device_id id_table[] =3D { { USB_DEVICE(0x18EF, 0xE025) }, /* ELV Marble Sound Board 1 */ { USB_DEVICE(0x1901, 0x0190) }, /* GE B850 CP2105 Recorder interface */ { USB_DEVICE(0x1901, 0x0193) }, /* GE B650 CP2104 PMC interface */ + { USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */ { USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */ { USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */ { USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */ diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m= 8.c index 10c30ad34e85..8db2fb1ae85a 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -489,6 +489,11 @@ static int generic_startup(struct usb_serial *serial) =20 dbg("%s - port %d", __func__, port->number); =20 + if (!port->interrupt_out_urb || !port->interrupt_in_urb) { + dev_err(&port->dev, "required endpoint is missing\n"); + return -ENODEV; + } + priv =3D kzalloc(sizeof(struct cypress_private), GFP_KERNEL); if (!priv) return -ENOMEM; @@ -658,12 +663,6 @@ static int cypress_open(struct tty_struct *tty, struct= usb_serial_port *port) cypress_set_termios(tty, port, &priv->tmp_termios); =20 /* setup the port and start reading from the device */ - if (!port->interrupt_in_urb) { - dev_err(&port->dev, "%s - interrupt_in_urb is empty!\n", - __func__); - return -1; - } - usb_fill_int_urb(port->interrupt_in_urb, serial->dev, usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress), port->interrupt_in_urb->transfer_buffer, diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi= _acceleport.c index e92cbefc0f88..e59bd95f05c0 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -1489,12 +1489,30 @@ static int digi_startup_device(struct usb_serial *s= erial) static int digi_startup(struct usb_serial *serial) { =20 + struct device *dev =3D &serial->interface->dev; int i; struct digi_port *priv; struct digi_serial *serial_priv; =20 dbg("digi_startup: TOP"); =20 + /* check whether the device has the expected number of endpoints */ + if (serial->num_port_pointers < serial->type->num_ports + 1) { + dev_err(dev, "OOB endpoints missing\n"); + return -ENODEV; + } + + for (i =3D 0; i < serial->type->num_ports + 1 ; i++) { + if (!serial->port[i]->read_urb) { + dev_err(dev, "bulk-in endpoint missing\n"); + return -ENODEV; + } + if (!serial->port[i]->write_urb) { + dev_err(dev, "bulk-out endpoint missing\n"); + return -ENODEV; + } + } + /* allocate the private data structures for all ports */ /* number of regular ports + 1 for the out-of-band port */ for (i =3D 0; i < serial->type->num_ports + 1; i++) { diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 509275766f5e..f0b752591f2e 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1026,6 +1026,10 @@ static struct usb_device_id id_table_combined [] =3D= { { USB_DEVICE(FTDI_VID, CHETCO_SEASMART_DISPLAY_PID) }, { USB_DEVICE(FTDI_VID, CHETCO_SEASMART_LITE_PID) }, { USB_DEVICE(FTDI_VID, CHETCO_SEASMART_ANALOG_PID) }, + /* ICP DAS I-756xU devices */ + { USB_DEVICE(ICPDAS_VID, ICPDAS_I7560U_PID) }, + { USB_DEVICE(ICPDAS_VID, ICPDAS_I7561U_PID) }, + { USB_DEVICE(ICPDAS_VID, ICPDAS_I7563U_PID) }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_si= o_ids.h index f9d55c4f5091..c2e80ebe34a9 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -866,6 +866,14 @@ #define NOVITUS_BONO_E_PID 0x6010 =20 /* + * ICPDAS I-756*U devices + */ +#define ICPDAS_VID 0x1b5c +#define ICPDAS_I7560U_PID 0x0103 +#define ICPDAS_I7561U_PID 0x0104 +#define ICPDAS_I7563U_PID 0x0105 + +/* * RT Systems programming cables for various ham radios */ #define RTSYSTEMS_VID 0x2100 /* Vendor ID */ diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 96a62dd5aa3f..a7e7ba65a611 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -443,6 +443,12 @@ static int mct_u232_startup(struct usb_serial *serial) struct mct_u232_private *priv; struct usb_serial_port *port, *rport; =20 + /* check first to simplify error handling */ + if (!serial->port[1] || !serial->port[1]->interrupt_in_urb) { + dev_err(&port->dev, "expected endpoint missing\n"); + return -ENODEV; + } + priv =3D kzalloc(sizeof(struct mct_u232_private), GFP_KERNEL); if (!priv) return -ENOMEM; diff --git a/drivers/watchdog/rc32434_wdt.c b/drivers/watchdog/rc32434_wdt.c index d4c29b5311a4..56dcae7be48b 100644 --- a/drivers/watchdog/rc32434_wdt.c +++ b/drivers/watchdog/rc32434_wdt.c @@ -239,7 +239,7 @@ static long rc32434_wdt_ioctl(struct file *file, unsign= ed int cmd, return -EINVAL; /* Fall through */ case WDIOC_GETTIMEOUT: - return copy_to_user(argp, &timeout, sizeof(int)); + return copy_to_user(argp, &timeout, sizeof(int)) ? -EFAULT : 0; default: return -ENOTTY; } diff --git a/drivers/xen/events.c b/drivers/xen/events.c index bcf7711784a5..71319739b95b 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -337,6 +337,12 @@ static inline int test_evtchn(int port) return sync_test_bit(port, &s->evtchn_pending[0]); } =20 +static inline int test_and_set_mask(int port) +{ + struct shared_info *s =3D HYPERVISOR_shared_info; + return sync_test_and_set_bit(port, &s->evtchn_mask[0]); +} + =20 /** * notify_remote_via_irq - send event to remote end of event channel via i= rq @@ -507,9 +513,19 @@ static void eoi_pirq(struct irq_data *data) struct physdev_eoi eoi =3D { .irq =3D pirq_from_irq(data->irq) }; int rc =3D 0; =20 - irq_move_irq(data); + if (!VALID_EVTCHN(evtchn)) + return; =20 - if (VALID_EVTCHN(evtchn)) + if (unlikely(irqd_is_setaffinity_pending(data))) { + int masked =3D test_and_set_mask(evtchn); + + clear_evtchn(evtchn); + + irq_move_masked_irq(data); + + if (!masked) + unmask_evtchn(evtchn); + } else clear_evtchn(evtchn); =20 if (pirq_needs_eoi(data->irq)) { @@ -1427,9 +1443,19 @@ static void ack_dynirq(struct irq_data *data) { int evtchn =3D evtchn_from_irq(data->irq); =20 - irq_move_irq(data); + if (!VALID_EVTCHN(evtchn)) + return; + + if (unlikely(irqd_is_setaffinity_pending(data))) { + int masked =3D test_and_set_mask(evtchn); =20 - if (VALID_EVTCHN(evtchn)) + clear_evtchn(evtchn); + + irq_move_masked_irq(data); + + if (!masked) + unmask_evtchn(evtchn); + } else clear_evtchn(evtchn); } =20 diff --git a/fs/bio.c b/fs/bio.c index b84d85103727..55b51881e751 100644 --- a/fs/bio.c +++ b/fs/bio.c @@ -793,15 +793,19 @@ int bio_uncopy_user(struct bio *bio) if (!bio_flagged(bio, BIO_NULL_MAPPED)) { /* * if we're in a workqueue, the request is orphaned, so - * don't copy into a random user address space, just free. + * don't copy into a random user address space, just free + * and return -EINTR so user space doesn't expect any data. */ if (current->mm) ret =3D __bio_copy_iov(bio, bmd->iovecs, bmd->sgvecs, bmd->nr_sgvecs, bio_data_dir(bio) =3D=3D READ, 0, bmd->is_our_pages); - else if (bmd->is_our_pages) - bio_for_each_segment_all(bvec, bio, i) - __free_page(bvec->bv_page); + else { + ret =3D -EINTR; + if (bmd->is_our_pages) + bio_for_each_segment_all(bvec, bio, i) + __free_page(bvec->bv_page); + } } bio_free_map_data(bmd); bio_put(bio); diff --git a/fs/exec.c b/fs/exec.c index aba5e13a6a68..a0006d85785c 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -55,6 +55,9 @@ #include #include #include +#include +#include +#include =20 #include #include @@ -2246,6 +2249,8 @@ void do_coredump(long signr, int exit_code, struct pt= _regs *regs) } } else { struct inode *inode; + int open_flags =3D O_CREAT | O_RDWR | O_NOFOLLOW | + O_LARGEFILE | O_EXCL; =20 if (cprm.limit < binfmt->min_coredump) goto fail_unlock; @@ -2284,10 +2289,27 @@ void do_coredump(long signr, int exit_code, struct = pt_regs *regs) * what matters is that at least one of the two processes * writes its coredump successfully, not which one. */ - cprm.file =3D filp_open(cn.corename, - O_CREAT | 2 | O_NOFOLLOW | - O_LARGEFILE | O_EXCL, - 0600); + if (need_suid_safe) { + /* + * Using user namespaces, normal user tasks can change + * their current->fs->root to point to arbitrary + * directories. Since the intention of the "only dump + * with a fully qualified path" rule is to control where + * coredumps may be placed using root privileges, + * current->fs->root must not be used. Instead, use the + * root directory of init_task. + */ + struct path root; + + task_lock(&init_task); + get_fs_root(init_task.fs, &root); + task_unlock(&init_task); + cprm.file =3D file_open_root(root.dentry, root.mnt, + cn.corename, open_flags, 0600); + path_put(&root); + } else { + cprm.file =3D filp_open(cn.corename, open_flags, 0600); + } if (IS_ERR(cprm.file)) goto fail_unlock; =20 diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 0de8c6ddf580..010f050a87b3 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4636,6 +4636,8 @@ int ext4_mark_inode_dirty(handle_t *handle, struct in= ode *inode) might_sleep(); trace_ext4_mark_inode_dirty(inode, _RET_IP_); err =3D ext4_reserve_inode_write(handle, inode, &iloc); + if (err) + return err; if (ext4_handle_valid(handle) && EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize && !ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND)) { @@ -4666,9 +4668,7 @@ int ext4_mark_inode_dirty(handle_t *handle, struct in= ode *inode) } } } - if (!err) - err =3D ext4_mark_iloc_dirty(handle, inode, &iloc); - return err; + return ext4_mark_iloc_dirty(handle, inode, &iloc); } =20 /* diff --git a/fs/fhandle.c b/fs/fhandle.c index c9e18f3ecc41..710438a1e021 100644 --- a/fs/fhandle.c +++ b/fs/fhandle.c @@ -229,7 +229,7 @@ long do_handle_open(int mountdirfd, path_put(&path); return fd; } - file =3D file_open_root(path.dentry, path.mnt, "", open_flag); + file =3D file_open_root(path.dentry, path.mnt, "", open_flag, 0); if (IS_ERR(file)) { put_unused_fd(fd); retval =3D PTR_ERR(file); diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index c19b8cecbfe1..039b8ae3bbd1 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -1340,11 +1340,12 @@ out: /** * jbd2_mark_journal_empty() - Mark on disk journal as empty. * @journal: The journal to update. + * @write_op: With which operation should we write the journal sb * * Update a journal's dynamic superblock fields to show that journal is em= pty. * Write updated superblock to disk waiting for IO to complete. */ -static void jbd2_mark_journal_empty(journal_t *journal) +static void jbd2_mark_journal_empty(journal_t *journal, int write_op) { journal_superblock_t *sb =3D journal->j_superblock; =20 @@ -1357,7 +1358,7 @@ static void jbd2_mark_journal_empty(journal_t *journa= l) sb->s_start =3D cpu_to_be32(0); read_unlock(&journal->j_state_lock); =20 - jbd2_write_superblock(journal, WRITE_FUA); + jbd2_write_superblock(journal, write_op); =20 /* Log is no longer empty */ write_lock(&journal->j_state_lock); @@ -1593,7 +1594,13 @@ int jbd2_journal_destroy(journal_t *journal) if (journal->j_sb_buffer) { if (!is_journal_aborted(journal)) { mutex_lock(&journal->j_checkpoint_mutex); - jbd2_mark_journal_empty(journal); + + write_lock(&journal->j_state_lock); + journal->j_tail_sequence =3D + ++journal->j_transaction_sequence; + write_unlock(&journal->j_state_lock); + + jbd2_mark_journal_empty(journal, WRITE_FLUSH_FUA); mutex_unlock(&journal->j_checkpoint_mutex); } else err =3D -EIO; @@ -1859,7 +1866,7 @@ int jbd2_journal_flush(journal_t *journal) * the magic code for a fully-recovered superblock. Any future * commits of data to the journal will restore the current * s_start value. */ - jbd2_mark_journal_empty(journal); + jbd2_mark_journal_empty(journal, WRITE_FUA); mutex_unlock(&journal->j_checkpoint_mutex); write_lock(&journal->j_state_lock); J_ASSERT(!journal->j_running_transaction); @@ -1905,7 +1912,7 @@ int jbd2_journal_wipe(journal_t *journal, int write) if (write) { /* Lock to make assertions happy... */ mutex_lock(&journal->j_checkpoint_mutex); - jbd2_mark_journal_empty(journal); + jbd2_mark_journal_empty(journal, WRITE_FUA); mutex_unlock(&journal->j_checkpoint_mutex); } =20 diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 9a959de2f18e..bd07ecf448be 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -791,6 +791,7 @@ nfsd4_secinfo(struct svc_rqst *rqstp, struct nfsd4_comp= ound_state *cstate, &exp, &dentry); if (err) return err; + fh_unlock(&cstate->current_fh); if (dentry->d_inode =3D=3D NULL) { exp_put(exp); err =3D nfserr_noent; diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 9d2c52b03bd2..31352e2bec29 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -931,8 +931,9 @@ nfsd4_decode_rename(struct nfsd4_compoundargs *argp, st= ruct nfsd4_rename *rename =20 READ_BUF(4); READ32(rename->rn_snamelen); - READ_BUF(rename->rn_snamelen + 4); + READ_BUF(rename->rn_snamelen); SAVEMEM(rename->rn_sname, rename->rn_snamelen); + READ_BUF(4); READ32(rename->rn_tnamelen); READ_BUF(rename->rn_tnamelen); SAVEMEM(rename->rn_tname, rename->rn_tnamelen); @@ -1009,13 +1010,14 @@ nfsd4_decode_setclientid(struct nfsd4_compoundargs = *argp, struct nfsd4_setclient READ_BUF(8); READ32(setclientid->se_callback_prog); READ32(setclientid->se_callback_netid_len); - - READ_BUF(setclientid->se_callback_netid_len + 4); + READ_BUF(setclientid->se_callback_netid_len); SAVEMEM(setclientid->se_callback_netid_val, setclientid->se_callback_neti= d_len); + READ_BUF(4); READ32(setclientid->se_callback_addr_len); =20 - READ_BUF(setclientid->se_callback_addr_len + 4); + READ_BUF(setclientid->se_callback_addr_len); SAVEMEM(setclientid->se_callback_addr_val, setclientid->se_callback_addr_= len); + READ_BUF(4); READ32(setclientid->se_callback_ident); =20 DECODE_TAIL; @@ -1584,8 +1586,9 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) */ READ_BUF(4); READ32(argp->taglen); - READ_BUF(argp->taglen + 8); + READ_BUF(argp->taglen); SAVEMEM(argp->tag, argp->taglen); + READ_BUF(8); READ32(argp->minorversion); READ32(argp->opcnt); =20 diff --git a/fs/ocfs2/dlm/dlmconvert.c b/fs/ocfs2/dlm/dlmconvert.c index 29a886d1e82c..f65bdcf61526 100644 --- a/fs/ocfs2/dlm/dlmconvert.c +++ b/fs/ocfs2/dlm/dlmconvert.c @@ -265,6 +265,7 @@ enum dlm_status dlmconvert_remote(struct dlm_ctxt *dlm, struct dlm_lock *lock, int flags, int type) { enum dlm_status status; + u8 old_owner =3D res->owner; =20 mlog(0, "type=3D%d, convert_type=3D%d, busy=3D%d\n", lock->ml.type, lock->ml.convert_type, res->state & DLM_LOCK_RES_IN_PROGRESS); @@ -290,6 +291,19 @@ enum dlm_status dlmconvert_remote(struct dlm_ctxt *dlm, status =3D DLM_DENIED; goto bail; } + + if (lock->ml.type =3D=3D type && lock->ml.convert_type =3D=3D LKM_IVMODE)= { + mlog(0, "last convert request returned DLM_RECOVERING, but " + "owner has already queued and sent ast to me. res %.*s, " + "(cookie=3D%u:%llu, type=3D%d, conv=3D%d)\n", + res->lockname.len, res->lockname.name, + dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)), + dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)), + lock->ml.type, lock->ml.convert_type); + status =3D DLM_NORMAL; + goto bail; + } + res->state |=3D DLM_LOCK_RES_IN_PROGRESS; /* move lock to local convert queue */ /* do not alter lock refcount. switching lists. */ @@ -319,11 +333,19 @@ enum dlm_status dlmconvert_remote(struct dlm_ctxt *dl= m, spin_lock(&res->spinlock); res->state &=3D ~DLM_LOCK_RES_IN_PROGRESS; lock->convert_pending =3D 0; - /* if it failed, move it back to granted queue */ + /* if it failed, move it back to granted queue. + * if master returns DLM_NORMAL and then down before sending ast, + * it may have already been moved to granted queue, reset to + * DLM_RECOVERING and retry convert */ if (status !=3D DLM_NORMAL) { if (status !=3D DLM_NOTQUEUED) dlm_error(status); dlm_revert_pending_convert(res, lock); + } else if ((res->state & DLM_LOCK_RES_RECOVERING) || + (old_owner !=3D res->owner)) { + mlog(0, "res %.*s is in recovering or has been recovered.\n", + res->lockname.len, res->lockname.name); + status =3D DLM_RECOVERING; } bail: spin_unlock(&res->spinlock); diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index bf3f00809ac2..171db3f91d10 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c @@ -2039,7 +2039,6 @@ void dlm_move_lockres_to_recovery_list(struct dlm_ctx= t *dlm, dlm_lock_get(lock); if (lock->convert_pending) { /* move converting lock back to granted */ - BUG_ON(i !=3D DLM_CONVERTING_LIST); mlog(0, "node died with convert pending " "on %.*s. move back to granted list.\n", res->lockname.len, res->lockname.name); diff --git a/fs/open.c b/fs/open.c index b8485d3cef97..ca155d4f23d3 100644 --- a/fs/open.c +++ b/fs/open.c @@ -958,12 +958,10 @@ struct file *filp_open(const char *filename, int flag= s, int mode) EXPORT_SYMBOL(filp_open); =20 struct file *file_open_root(struct dentry *dentry, struct vfsmount *mnt, - const char *filename, int flags) + const char *filename, int flags, umode_t mode) { struct open_flags op; - int lookup =3D build_open_flags(flags, 0, &op); - if (flags & O_CREAT) - return ERR_PTR(-EINVAL); + int lookup =3D build_open_flags(flags, mode, &op); if (!filename && (flags & O_DIRECTORY)) if (!dentry->d_inode->i_op->lookup) return ERR_PTR(-ENOTDIR); diff --git a/fs/splice.c b/fs/splice.c index 71c80f449f91..459128ba084a 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -188,6 +188,9 @@ ssize_t splice_to_pipe(struct pipe_inode_info *pipe, unsigned int spd_pages =3D spd->nr_pages; int ret, do_wakeup, page_nr; =20 + if (!spd_pages) + return 0; + ret =3D 0; do_wakeup =3D 0; page_nr =3D 0; diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c index c1b55e596551..e050022f7140 100644 --- a/fs/xfs/xfs_attr_leaf.c +++ b/fs/xfs/xfs_attr_leaf.c @@ -721,8 +721,10 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *conte= xt) sbp->namelen, sbp->valuelen, &sbp->name[sbp->namelen]); - if (error) + if (error) { + kmem_free(sbuf); return error; + } if (context->seen_enough) break; cursor->offset++; @@ -2404,14 +2406,13 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_li= st_context_t *context) args.rmtblkno =3D be32_to_cpu(name_rmt->valueblk); args.rmtblkcnt =3D XFS_B_TO_FSB(args.dp->i_mount, valuelen); retval =3D xfs_attr_rmtval_get(&args); - if (retval) - return retval; - retval =3D context->put_listent(context, - entry->flags, - name_rmt->name, - (int)name_rmt->namelen, - valuelen, - args.value); + if (!retval) + retval =3D context->put_listent(context, + entry->flags, + name_rmt->name, + (int)name_rmt->namelen, + valuelen, + args.value); kmem_free(args.value); } else { retval =3D context->put_listent(context, diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 6712ab698cad..213a8700144b 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -116,6 +116,8 @@ struct dm_dev { char name[16]; }; =20 +dev_t dm_get_dev_t(const char *path); + /* * Constructors should call these functions to ensure destination devices * are opened/closed correctly. diff --git a/include/linux/fs.h b/include/linux/fs.h index dd743859f04e..44e856ba8a79 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2073,7 +2073,7 @@ extern long do_sys_open(int dfd, const char __user *f= ilename, int flags, int mode); extern struct file *filp_open(const char *, int, int); extern struct file *file_open_root(struct dentry *, struct vfsmount *, - const char *, int); + const char *, int, umode_t); extern struct file * dentry_open(struct dentry *, struct vfsmount *, int, const struct cred *); extern int filp_close(struct file *, fl_owner_t id); diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 00ef00d0f315..2729d09e9c11 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -153,6 +153,7 @@ struct ipv6_devconf { #endif __s32 max_addresses; __s32 accept_ra_defrtr; + __s32 accept_ra_min_hop_limit; __s32 accept_ra_pinfo; #ifdef CONFIG_IPV6_ROUTER_PREF __s32 accept_ra_rtr_pref; @@ -213,6 +214,8 @@ enum { DEVCONF_DISABLE_IPV6, DEVCONF_ACCEPT_DAD, DEVCONF_FORCE_TLLAO, + DEVCONF_USE_OIF_ADDRS_ONLY =3D 37, + DEVCONF_ACCEPT_RA_MIN_HOP_LIMIT, DEVCONF_MAX }; =20 diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 4b04097c748c..700c94821db1 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -293,6 +293,7 @@ struct header_ops { void (*cache_update)(struct hh_cache *hh, const struct net_device *dev, const unsigned char *haddr); + bool (*validate)(const char *ll_header, unsigned int len); }; =20 /* These flag bits are private to the generic network queueing @@ -1119,7 +1120,7 @@ struct net_device { =20 unsigned int mtu; /* interface MTU value */ unsigned short type; /* interface hardware type */ - unsigned short hard_header_len; /* hardware hdr length */ + unsigned short hard_header_len; /* maximum hardware hdr length */ =20 /* extra head- and tailroom the hardware may need, but not in all cases * can this be guaranteed, especially tailroom. Some cases also use @@ -1728,6 +1729,24 @@ static inline int dev_rebuild_header(struct sk_buff = *skb) return dev->header_ops->rebuild(skb); } =20 +/* ll_header must have at least hard_header_len allocated */ +static inline bool dev_validate_header(const struct net_device *dev, + char *ll_header, int len) +{ + if (likely(len >=3D dev->hard_header_len)) + return true; + + if (capable(CAP_SYS_RAWIO)) { + memset(ll_header + len, 0, dev->hard_header_len - len); + return true; + } + + if (dev->header_ops && dev->header_ops->validate) + return dev->header_ops->validate(ll_header, len); + + return false; +} + typedef int gifconf_func_t(struct net_device * dev, char __user * bufptr, = int len); extern int register_gifconf(unsigned int family, gifconf_func_t * gifconf= ); static inline int unregister_gifconf(unsigned int family) diff --git a/include/linux/pci.h b/include/linux/pci.h index f0c44959beec..dd8bb8077735 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -327,6 +327,7 @@ struct pci_dev { unsigned int is_hotplug_bridge:1; unsigned int __aer_firmware_first_valid:1; unsigned int __aer_firmware_first:1; + unsigned int non_compliant_bars:1; /* broken BARs; ignore them */ pci_dev_flags_t dev_flags; atomic_t enable_cnt; /* pci_enable_device has been called */ =20 diff --git a/include/net/inet_ecn.h b/include/net/inet_ecn.h index 2fa14691869c..18f2d104b6be 100644 --- a/include/net/inet_ecn.h +++ b/include/net/inet_ecn.h @@ -109,11 +109,24 @@ static inline void ipv4_copy_dscp(unsigned int dscp, = struct iphdr *inner) =20 struct ipv6hdr; =20 -static inline int IP6_ECN_set_ce(struct ipv6hdr *iph) +/* Note: + * IP_ECN_set_ce() has to tweak IPV4 checksum when setting CE, + * meaning both changes have no effect on skb->csum if/when CHECKSUM_COMPL= ETE + * In IPv6 case, no checksum compensates the change in IPv6 header, + * so we have to update skb->csum. + */ +static inline int IP6_ECN_set_ce(struct sk_buff *skb, struct ipv6hdr *iph) { + __be32 from, to; + if (INET_ECN_is_not_ect(ipv6_get_dsfield(iph))) return 0; - *(__be32*)iph |=3D htonl(INET_ECN_CE << 20); + + from =3D *(__be32 *)iph; + to =3D from | htonl(INET_ECN_CE << 20); + *(__be32 *)iph =3D to; + if (skb->ip_summed =3D=3D CHECKSUM_COMPLETE) + skb->csum =3D csum_add(csum_sub(skb->csum, from), to); return 1; } =20 @@ -138,7 +151,7 @@ static inline int INET_ECN_set_ce(struct sk_buff *skb) =20 case cpu_to_be16(ETH_P_IPV6): if (skb->network_header + sizeof(struct ipv6hdr) <=3D skb->tail) - return IP6_ECN_set_ce(ipv6_hdr(skb)); + return IP6_ECN_set_ce(skb, ipv6_hdr(skb)); break; } =20 diff --git a/kernel/sched.c b/kernel/sched.c index a7a40b5677f0..33ac1e348542 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2084,6 +2084,19 @@ EXPORT_SYMBOL_GPL(account_system_vtime); =20 #endif /* CONFIG_IRQ_TIME_ACCOUNTING */ =20 +static inline void account_reset_rq(struct rq *rq) +{ +#ifdef CONFIG_IRQ_TIME_ACCOUNTING + rq->prev_irq_time =3D 0; +#endif +#ifdef CONFIG_PARAVIRT + rq->prev_steal_time =3D 0; +#endif +#ifdef CONFIG_PARAVIRT_TIME_ACCOUNTING + rq->prev_steal_time_rq =3D 0; +#endif +} + #ifdef CONFIG_PARAVIRT static inline u64 steal_ticks(u64 steal) { @@ -6851,6 +6864,7 @@ migration_call(struct notifier_block *nfb, unsigned l= ong action, void *hcpu) =20 case CPU_UP_PREPARE: rq->calc_load_update =3D calc_load_update; + account_reset_rq(rq); break; =20 case CPU_ONLINE: diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c index 9f9aa3205973..cd2ea02c5a9d 100644 --- a/kernel/sysctl_binary.c +++ b/kernel/sysctl_binary.c @@ -1346,7 +1346,7 @@ static ssize_t binary_sysctl(const int *name, int nle= n, } =20 mnt =3D current->nsproxy->pid_ns->proc_mnt; - file =3D file_open_root(mnt->mnt_root, mnt, pathname, flags); + file =3D file_open_root(mnt->mnt_root, mnt, pathname, flags, 0); result =3D PTR_ERR(file); if (IS_ERR(file)) goto out_putname; diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 0c348a63be49..f4b93a207026 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -3565,7 +3565,10 @@ static ssize_t tracing_splice_read_pipe(struct file = *filp, =20 spd.nr_pages =3D i; =20 - ret =3D splice_to_pipe(pipe, &spd); + if (i) + ret =3D splice_to_pipe(pipe, &spd); + else + ret =3D 0; out: splice_shrink_spd(&spd); return ret; diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index 1626e1aee71a..76fb95088a7e 100644 --- a/kernel/trace/trace_irqsoff.c +++ b/kernel/trace/trace_irqsoff.c @@ -117,8 +117,12 @@ static int func_prolog_dec(struct trace_array *tr, return 0; =20 local_save_flags(*flags); - /* slight chance to get a false positive on tracing_cpu */ - if (!irqs_disabled_flags(*flags)) + /* + * Slight chance to get a false positive on tracing_cpu, + * although I'm starting to think there isn't a chance. + * Leave this for now just to be paranoid. + */ + if (!irqs_disabled_flags(*flags) && !preempt_count()) return 0; =20 *data =3D tr->data[cpu]; diff --git a/net/ax25/ax25_ip.c b/net/ax25/ax25_ip.c index cf0c47a26530..a0c9956b5b23 100644 --- a/net/ax25/ax25_ip.c +++ b/net/ax25/ax25_ip.c @@ -232,9 +232,24 @@ int ax25_rebuild_header(struct sk_buff *skb) =20 #endif =20 +static bool ax25_validate_header(const char *header, unsigned int len) +{ + ax25_digi digi; + + if (!len) + return false; + + if (header[0]) + return true; + + return ax25_addr_parse(header + 1, len - 1, NULL, NULL, &digi, NULL, + NULL); +} + const struct header_ops ax25_header_ops =3D { .create =3D ax25_hard_header, .rebuild =3D ax25_rebuild_header, + .validate =3D ax25_validate_header, }; =20 EXPORT_SYMBOL(ax25_hard_header); diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c index 0f7dc609f27d..afafe662d452 100644 --- a/net/bridge/br_stp_if.c +++ b/net/bridge/br_stp_if.c @@ -129,7 +129,10 @@ static void br_stp_start(struct net_bridge *br) char *argv[] =3D { BR_STP_PROG, br->dev->name, "start", NULL }; char *envp[] =3D { NULL }; =20 - r =3D call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC); + if (net_eq(dev_net(br->dev), &init_net)) + r =3D call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC); + else + r =3D -ENOENT; if (r =3D=3D 0) { br->stp_enabled =3D BR_USER_STP; br_debug(br, "userspace STP started\n"); diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index e41c40f48cfe..757bee7e8a9b 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -326,6 +326,9 @@ static void __inet_del_ifa(struct in_device *in_dev, st= ruct in_ifaddr **ifap, =20 ASSERT_RTNL(); =20 + if (in_dev->dead) + goto no_promotions; + /* 1. Deleting primary ifaddr forces deletion all secondaries * unless alias promotion is set **/ @@ -372,6 +375,7 @@ static void __inet_del_ifa(struct in_device *in_dev, st= ruct in_ifaddr **ifap, fib_del_ifaddr(ifa, ifa1); } =20 +no_promotions: /* 2. Unlink it */ =20 *ifap =3D ifa1->ifa_next; diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 92fc5f69f5da..76784c7d54da 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -764,6 +764,9 @@ void fib_del_ifaddr(struct in_ifaddr *ifa, struct in_if= addr *iprim) subnet =3D 1; } =20 + if (in_dev->dead) + goto no_promotions; + /* Deletion is more complicated than add. * We should take care of not to delete too much :-) * @@ -839,6 +842,7 @@ void fib_del_ifaddr(struct in_ifaddr *ifa, struct in_if= addr *iprim) } } =20 +no_promotions: if (!(ok & BRD_OK)) fib_magic(RTM_DELROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim); if (subnet && ifa->ifa_prefixlen < 31) { diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 5f28fabffd67..601254e4f28f 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -535,7 +535,7 @@ static inline void ipgre_ecn_decapsulate(const struct i= phdr *iph, struct sk_buff if (skb->protocol =3D=3D htons(ETH_P_IP)) { IP_ECN_set_ce(ip_hdr(skb)); } else if (skb->protocol =3D=3D htons(ETH_P_IPV6)) { - IP6_ECN_set_ce(ipv6_hdr(skb)); + IP6_ECN_set_ce(skb, ipv6_hdr(skb)); } } } diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 043d8822a138..b3648bbef0da 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -206,6 +206,8 @@ int ip_cmsg_send(struct net *net, struct msghdr *msg, s= truct ipcm_cookie *ipc) switch (cmsg->cmsg_type) { case IP_RETOPTS: err =3D cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr)); + + /* Our caller is responsible for freeing ipc->opt */ err =3D ip_options_get(net, &ipc->opt, CMSG_DATA(cmsg), err < 40 ? err : 40); if (err) diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_table= s.c index bcb6e6197595..51abd1480e21 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -350,11 +350,12 @@ unsigned int arpt_do_table(struct sk_buff *skb, } =20 /* All zeroes =3D=3D unconditional rule. */ -static inline bool unconditional(const struct arpt_arp *arp) +static inline bool unconditional(const struct arpt_entry *e) { static const struct arpt_arp uncond; =20 - return memcmp(arp, &uncond, sizeof(uncond)) =3D=3D 0; + return e->target_offset =3D=3D sizeof(struct arpt_entry) && + memcmp(&e->arp, &uncond, sizeof(uncond)) =3D=3D 0; } =20 /* Figures out from what hook each rule can be called: returns 0 if @@ -393,11 +394,10 @@ static int mark_source_chains(const struct xt_table_i= nfo *newinfo, |=3D ((1 << hook) | (1 << NF_ARP_NUMHOOKS)); =20 /* Unconditional return/END. */ - if ((e->target_offset =3D=3D sizeof(struct arpt_entry) && + if ((unconditional(e) && (strcmp(t->target.u.user.name, XT_STANDARD_TARGET) =3D=3D 0) && - t->verdict < 0 && unconditional(&e->arp)) || - visited) { + t->verdict < 0) || visited) { unsigned int oldpos, size; =20 if ((strcmp(t->target.u.user.name, @@ -465,14 +465,12 @@ static int mark_source_chains(const struct xt_table_i= nfo *newinfo, return 1; } =20 -static inline int check_entry(const struct arpt_entry *e, const char *name) +static inline int check_entry(const struct arpt_entry *e) { const struct xt_entry_target *t; =20 - if (!arp_checkentry(&e->arp)) { - duprintf("arp_tables: arp check failed %p %s.\n", e, name); + if (!arp_checkentry(&e->arp)) return -EINVAL; - } =20 if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset) return -EINVAL; @@ -513,10 +511,6 @@ find_check_entry(struct arpt_entry *e, const char *nam= e, unsigned int size) struct xt_target *target; int ret; =20 - ret =3D check_entry(e, name); - if (ret) - return ret; - t =3D arpt_get_target(e); target =3D xt_request_find_target(NFPROTO_ARP, t->u.user.name, t->u.user.revision); @@ -542,7 +536,7 @@ static bool check_underflow(const struct arpt_entry *e) const struct xt_entry_target *t; unsigned int verdict; =20 - if (!unconditional(&e->arp)) + if (!unconditional(e)) return false; t =3D arpt_get_target_c(e); if (strcmp(t->u.user.name, XT_STANDARD_TARGET) !=3D 0) @@ -561,9 +555,11 @@ static inline int check_entry_size_and_hooks(struct ar= pt_entry *e, unsigned int valid_hooks) { unsigned int h; + int err; =20 if ((unsigned long)e % __alignof__(struct arpt_entry) !=3D 0 || - (unsigned char *)e + sizeof(struct arpt_entry) >=3D limit) { + (unsigned char *)e + sizeof(struct arpt_entry) >=3D limit || + (unsigned char *)e + e->next_offset > limit) { duprintf("Bad offset %p\n", e); return -EINVAL; } @@ -575,6 +571,10 @@ static inline int check_entry_size_and_hooks(struct ar= pt_entry *e, return -EINVAL; } =20 + err =3D check_entry(e); + if (err) + return err; + /* Check hooks & underflows */ for (h =3D 0; h < NF_ARP_NUMHOOKS; h++) { if (!(valid_hooks & (1 << h))) @@ -583,9 +583,9 @@ static inline int check_entry_size_and_hooks(struct arp= t_entry *e, newinfo->hook_entry[h] =3D hook_entries[h]; if ((unsigned char *)e - base =3D=3D underflows[h]) { if (!check_underflow(e)) { - pr_err("Underflows must be unconditional and " - "use the STANDARD target with " - "ACCEPT/DROP\n"); + pr_debug("Underflows must be unconditional and " + "use the STANDARD target with " + "ACCEPT/DROP\n"); return -EINVAL; } newinfo->underflow[h] =3D underflows[h]; @@ -1219,7 +1219,8 @@ check_compat_entry_size_and_hooks(struct compat_arpt_= entry *e, =20 duprintf("check_compat_entry_size_and_hooks %p\n", e); if ((unsigned long)e % __alignof__(struct compat_arpt_entry) !=3D 0 || - (unsigned char *)e + sizeof(struct compat_arpt_entry) >=3D limit) { + (unsigned char *)e + sizeof(struct compat_arpt_entry) >=3D limit || + (unsigned char *)e + e->next_offset > limit) { duprintf("Bad offset %p, limit =3D %p\n", e, limit); return -EINVAL; } @@ -1232,7 +1233,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_= entry *e, } =20 /* For purposes of check_entry casting the compat entry is fine */ - ret =3D check_entry((struct arpt_entry *)e, name); + ret =3D check_entry((struct arpt_entry *)e); if (ret) return ret; =20 diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index f98a1cf54c5b..41c01de69104 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -168,11 +168,12 @@ get_entry(const void *base, unsigned int offset) =20 /* All zeroes =3D=3D unconditional rule. */ /* Mildly perf critical (only if packet tracing is on) */ -static inline bool unconditional(const struct ipt_ip *ip) +static inline bool unconditional(const struct ipt_entry *e) { static const struct ipt_ip uncond; =20 - return memcmp(ip, &uncond, sizeof(uncond)) =3D=3D 0; + return e->target_offset =3D=3D sizeof(struct ipt_entry) && + memcmp(&e->ip, &uncond, sizeof(uncond)) =3D=3D 0; #undef FWINV } =20 @@ -230,11 +231,10 @@ get_chainname_rulenum(const struct ipt_entry *s, cons= t struct ipt_entry *e, } else if (s =3D=3D e) { (*rulenum)++; =20 - if (s->target_offset =3D=3D sizeof(struct ipt_entry) && + if (unconditional(s) && strcmp(t->target.u.kernel.target->name, XT_STANDARD_TARGET) =3D=3D 0 && - t->verdict < 0 && - unconditional(&s->ip)) { + t->verdict < 0) { /* Tail of chains: STANDARD target (return/policy) */ *comment =3D *chainname =3D=3D hookname ? comments[NF_IP_TRACE_COMMENT_POLICY] @@ -468,11 +468,10 @@ mark_source_chains(const struct xt_table_info *newinf= o, e->comefrom |=3D ((1 << hook) | (1 << NF_INET_NUMHOOKS)); =20 /* Unconditional return/END. */ - if ((e->target_offset =3D=3D sizeof(struct ipt_entry) && + if ((unconditional(e) && (strcmp(t->target.u.user.name, XT_STANDARD_TARGET) =3D=3D 0) && - t->verdict < 0 && unconditional(&e->ip)) || - visited) { + t->verdict < 0) || visited) { unsigned int oldpos, size; =20 if ((strcmp(t->target.u.user.name, @@ -561,14 +560,12 @@ static void cleanup_match(struct xt_entry_match *m, s= truct net *net) } =20 static int -check_entry(const struct ipt_entry *e, const char *name) +check_entry(const struct ipt_entry *e) { const struct xt_entry_target *t; =20 - if (!ip_checkentry(&e->ip)) { - duprintf("ip check failed %p %s.\n", e, name); + if (!ip_checkentry(&e->ip)) return -EINVAL; - } =20 if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset) @@ -658,10 +655,6 @@ find_check_entry(struct ipt_entry *e, struct net *net,= const char *name, struct xt_mtchk_param mtpar; struct xt_entry_match *ematch; =20 - ret =3D check_entry(e, name); - if (ret) - return ret; - j =3D 0; mtpar.net =3D net; mtpar.table =3D name; @@ -705,7 +698,7 @@ static bool check_underflow(const struct ipt_entry *e) const struct xt_entry_target *t; unsigned int verdict; =20 - if (!unconditional(&e->ip)) + if (!unconditional(e)) return false; t =3D ipt_get_target_c(e); if (strcmp(t->u.user.name, XT_STANDARD_TARGET) !=3D 0) @@ -725,9 +718,11 @@ check_entry_size_and_hooks(struct ipt_entry *e, unsigned int valid_hooks) { unsigned int h; + int err; =20 if ((unsigned long)e % __alignof__(struct ipt_entry) !=3D 0 || - (unsigned char *)e + sizeof(struct ipt_entry) >=3D limit) { + (unsigned char *)e + sizeof(struct ipt_entry) >=3D limit || + (unsigned char *)e + e->next_offset > limit) { duprintf("Bad offset %p\n", e); return -EINVAL; } @@ -739,6 +734,10 @@ check_entry_size_and_hooks(struct ipt_entry *e, return -EINVAL; } =20 + err =3D check_entry(e); + if (err) + return err; + /* Check hooks & underflows */ for (h =3D 0; h < NF_INET_NUMHOOKS; h++) { if (!(valid_hooks & (1 << h))) @@ -747,9 +746,9 @@ check_entry_size_and_hooks(struct ipt_entry *e, newinfo->hook_entry[h] =3D hook_entries[h]; if ((unsigned char *)e - base =3D=3D underflows[h]) { if (!check_underflow(e)) { - pr_err("Underflows must be unconditional and " - "use the STANDARD target with " - "ACCEPT/DROP\n"); + pr_debug("Underflows must be unconditional and " + "use the STANDARD target with " + "ACCEPT/DROP\n"); return -EINVAL; } newinfo->underflow[h] =3D underflows[h]; @@ -1486,7 +1485,8 @@ check_compat_entry_size_and_hooks(struct compat_ipt_e= ntry *e, =20 duprintf("check_compat_entry_size_and_hooks %p\n", e); if ((unsigned long)e % __alignof__(struct compat_ipt_entry) !=3D 0 || - (unsigned char *)e + sizeof(struct compat_ipt_entry) >=3D limit) { + (unsigned char *)e + sizeof(struct compat_ipt_entry) >=3D limit || + (unsigned char *)e + e->next_offset > limit) { duprintf("Bad offset %p, limit =3D %p\n", e, limit); return -EINVAL; } @@ -1499,7 +1499,7 @@ check_compat_entry_size_and_hooks(struct compat_ipt_e= ntry *e, } =20 /* For purposes of check_entry casting the compat entry is fine */ - ret =3D check_entry((struct ipt_entry *)e, name); + ret =3D check_entry((struct ipt_entry *)e); if (ret) return ret; =20 diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_M= ASQUERADE.c index 9931152a78b5..9a30807c8c28 100644 --- a/net/ipv4/netfilter/ipt_MASQUERADE.c +++ b/net/ipv4/netfilter/ipt_MASQUERADE.c @@ -123,8 +123,16 @@ static int masq_inet_event(struct notifier_block *this, unsigned long event, void *ptr) { - struct net_device *dev =3D ((struct in_ifaddr *)ptr)->ifa_dev->dev; - return masq_device_event(this, event, dev); + struct in_device *idev =3D ((struct in_ifaddr *)ptr)->ifa_dev; + /* The masq_dev_notifier will catch the case of the device going + * down. So if the inetdev is dead and being destroyed we have + * no work to do. Otherwise this is an individual address removal + * and we have to perform the flush. + */ + if (idev->dead) + return NOTIFY_DONE; + + return masq_device_event(this, event, idev->dev); } =20 static struct notifier_block masq_dev_notifier =3D { diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index 7aa6225e7fe3..5d28677345e0 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c @@ -530,8 +530,10 @@ static int ping_sendmsg(struct kiocb *iocb, struct soc= k *sk, struct msghdr *msg, =20 if (msg->msg_controllen) { err =3D ip_cmsg_send(sock_net(sk), msg, &ipc); - if (err) + if (unlikely(err)) { + kfree(ipc.opt); return err; + } if (ipc.opt) free =3D 1; } diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 063bcd54d268..e6430963e994 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -520,8 +520,10 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock= *sk, struct msghdr *msg, =20 if (msg->msg_controllen) { err =3D ip_cmsg_send(sock_net(sk), msg, &ipc); - if (err) + if (unlikely(err)) { + kfree(ipc.opt); goto out; + } if (ipc.opt) free =3D 1; } diff --git a/net/ipv4/tcp_yeah.c b/net/ipv4/tcp_yeah.c index 05c3b6f0e8e1..bf8321d6f2ef 100644 --- a/net/ipv4/tcp_yeah.c +++ b/net/ipv4/tcp_yeah.c @@ -222,7 +222,7 @@ static u32 tcp_yeah_ssthresh(struct sock *sk) { yeah->fast_count =3D 0; yeah->reno_count =3D max(yeah->reno_count>>1, 2U); =20 - return tp->snd_cwnd - reduction; + return max_t(int, tp->snd_cwnd - reduction, 2); } =20 static struct tcp_congestion_ops tcp_yeah __read_mostly =3D { diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index f602611ae9c9..f64a1e548beb 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -875,8 +875,10 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, s= truct msghdr *msg, return err; if (msg->msg_controllen) { err =3D ip_cmsg_send(sock_net(sk), msg, &ipc); - if (err) + if (unlikely(err)) { + kfree(ipc.opt); return err; + } if (ipc.opt) free =3D 1; connected =3D 0; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 006867df0178..79eceab4637a 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -185,6 +185,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = =3D { #endif .max_addresses =3D IPV6_MAX_ADDRESSES, .accept_ra_defrtr =3D 1, + .accept_ra_min_hop_limit=3D 1, .accept_ra_pinfo =3D 1, #ifdef CONFIG_IPV6_ROUTER_PREF .accept_ra_rtr_pref =3D 1, @@ -219,6 +220,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mos= tly =3D { #endif .max_addresses =3D IPV6_MAX_ADDRESSES, .accept_ra_defrtr =3D 1, + .accept_ra_min_hop_limit=3D 1, .accept_ra_pinfo =3D 1, #ifdef CONFIG_IPV6_ROUTER_PREF .accept_ra_rtr_pref =3D 1, @@ -3943,6 +3945,7 @@ static inline void ipv6_store_devconf(struct ipv6_dev= conf *cnf, #endif array[DEVCONF_MAX_ADDRESSES] =3D cnf->max_addresses; array[DEVCONF_ACCEPT_RA_DEFRTR] =3D cnf->accept_ra_defrtr; + array[DEVCONF_ACCEPT_RA_MIN_HOP_LIMIT] =3D cnf->accept_ra_min_hop_limit; array[DEVCONF_ACCEPT_RA_PINFO] =3D cnf->accept_ra_pinfo; #ifdef CONFIG_IPV6_ROUTER_PREF array[DEVCONF_ACCEPT_RA_RTR_PREF] =3D cnf->accept_ra_rtr_pref; @@ -4546,6 +4549,13 @@ static struct addrconf_sysctl_table .proc_handler =3D proc_dointvec, }, { + .procname =3D "accept_ra_min_hop_limit", + .data =3D &ipv6_devconf.accept_ra_min_hop_limit, + .maxlen =3D sizeof(int), + .mode =3D 0644, + .proc_handler =3D proc_dointvec, + }, + { .procname =3D "accept_ra_pinfo", .data =3D &ipv6_devconf.accept_ra_pinfo, .maxlen =3D sizeof(int), diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 9e4bacc4f19e..20437cb6dbdd 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -161,6 +161,9 @@ ipv4_connected: fl6.fl6_dport =3D inet->inet_dport; fl6.fl6_sport =3D inet->inet_sport; =20 + if (!fl6.flowi6_oif) + fl6.flowi6_oif =3D np->sticky_pktinfo.ipi6_ifindex; + if (!fl6.flowi6_oif && (addr_type&IPV6_ADDR_MULTICAST)) fl6.flowi6_oif =3D np->mcast_oif; =20 diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 6b3edff2c8f6..f1ca6588307c 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -1109,9 +1109,8 @@ static inline int ip6_ufo_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb), void *from, int length, int hh_len, int fragheaderlen, - int transhdrlen, int mtu,unsigned int flags, - struct rt6_info *rt) - + int exthdrlen, int transhdrlen, int mtu, + unsigned int flags, struct rt6_info *rt) { struct sk_buff *skb; int err; @@ -1136,7 +1135,7 @@ static inline int ip6_ufo_append_data(struct sock *sk, skb_put(skb,fragheaderlen + transhdrlen); =20 /* initialize network header pointer */ - skb_reset_network_header(skb); + skb_set_network_header(skb, exthdrlen); =20 /* initialize protocol header pointer */ skb->transport_header =3D skb->network_header + fragheaderlen; @@ -1342,7 +1341,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void= *from, char *to, (rt->dst.dev->features & NETIF_F_UFO) && (sk->sk_type =3D=3D SOCK_DGRAM)) { err =3D ip6_ufo_append_data(sk, getfrag, from, length, - hh_len, fragheaderlen, + hh_len, fragheaderlen, exthdrlen, transhdrlen, mtu, flags, rt); if (err) goto error; diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index ae32ff78ab31..1828c27ba7aa 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -689,7 +689,7 @@ static void ip6ip6_dscp_ecn_decapsulate(const struct ip= 6_tnl *t, ipv6_copy_dscp(ipv6_get_dsfield(ipv6h), ipv6_hdr(skb)); =20 if (INET_ECN_is_ce(ipv6_get_dsfield(ipv6h))) - IP6_ECN_set_ce(ipv6_hdr(skb)); + IP6_ECN_set_ce(skb, ipv6_hdr(skb)); } =20 /* called with rcu_read_lock() */ diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 39836dafa931..e5b0f9e0deaa 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -1276,18 +1276,16 @@ static void ndisc_router_discovery(struct sk_buff *= skb) if (rt) rt->rt6i_expires =3D jiffies + (HZ * lifetime); =20 - if (ra_msg->icmph.icmp6_hop_limit) { - /* Only set hop_limit on the interface if it is higher than - * the current hop_limit. - */ - if (in6_dev->cnf.hop_limit < ra_msg->icmph.icmp6_hop_limit) { + if (in6_dev->cnf.accept_ra_min_hop_limit < 256 && + ra_msg->icmph.icmp6_hop_limit) { + if (in6_dev->cnf.accept_ra_min_hop_limit <=3D ra_msg->icmph.icmp6_hop_li= mit) { in6_dev->cnf.hop_limit =3D ra_msg->icmph.icmp6_hop_limit; + if (rt) + dst_metric_set(&rt->dst, RTAX_HOPLIMIT, + ra_msg->icmph.icmp6_hop_limit); } else { - ND_PRINTK2(KERN_WARNING "RA: Got route advertisement with lower hop_lim= it than current\n"); + ND_PRINTK2(KERN_WARNING "RA: Got route advertisement with lower hop_lim= it than minimum\n"); } - if (rt) - dst_metric_set(&rt->dst, RTAX_HOPLIMIT, - ra_msg->icmph.icmp6_hop_limit); } =20 skip_defrtr: diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_table= s.c index 2e752b2f5b30..8970886882a7 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -208,11 +208,12 @@ get_entry(const void *base, unsigned int offset) =20 /* All zeroes =3D=3D unconditional rule. */ /* Mildly perf critical (only if packet tracing is on) */ -static inline bool unconditional(const struct ip6t_ip6 *ipv6) +static inline bool unconditional(const struct ip6t_entry *e) { static const struct ip6t_ip6 uncond; =20 - return memcmp(ipv6, &uncond, sizeof(uncond)) =3D=3D 0; + return e->target_offset =3D=3D sizeof(struct ip6t_entry) && + memcmp(&e->ipv6, &uncond, sizeof(uncond)) =3D=3D 0; } =20 static inline const struct xt_entry_target * @@ -269,11 +270,10 @@ get_chainname_rulenum(const struct ip6t_entry *s, con= st struct ip6t_entry *e, } else if (s =3D=3D e) { (*rulenum)++; =20 - if (s->target_offset =3D=3D sizeof(struct ip6t_entry) && + if (unconditional(s) && strcmp(t->target.u.kernel.target->name, XT_STANDARD_TARGET) =3D=3D 0 && - t->verdict < 0 && - unconditional(&s->ipv6)) { + t->verdict < 0) { /* Tail of chains: STANDARD target (return/policy) */ *comment =3D *chainname =3D=3D hookname ? comments[NF_IP6_TRACE_COMMENT_POLICY] @@ -490,11 +490,10 @@ mark_source_chains(const struct xt_table_info *newinf= o, e->comefrom |=3D ((1 << hook) | (1 << NF_INET_NUMHOOKS)); =20 /* Unconditional return/END. */ - if ((e->target_offset =3D=3D sizeof(struct ip6t_entry) && + if ((unconditional(e) && (strcmp(t->target.u.user.name, XT_STANDARD_TARGET) =3D=3D 0) && - t->verdict < 0 && - unconditional(&e->ipv6)) || visited) { + t->verdict < 0) || visited) { unsigned int oldpos, size; =20 if ((strcmp(t->target.u.user.name, @@ -583,14 +582,12 @@ static void cleanup_match(struct xt_entry_match *m, s= truct net *net) } =20 static int -check_entry(const struct ip6t_entry *e, const char *name) +check_entry(const struct ip6t_entry *e) { const struct xt_entry_target *t; =20 - if (!ip6_checkentry(&e->ipv6)) { - duprintf("ip_tables: ip check failed %p %s.\n", e, name); + if (!ip6_checkentry(&e->ipv6)) return -EINVAL; - } =20 if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset) @@ -681,10 +678,6 @@ find_check_entry(struct ip6t_entry *e, struct net *net= , const char *name, struct xt_mtchk_param mtpar; struct xt_entry_match *ematch; =20 - ret =3D check_entry(e, name); - if (ret) - return ret; - j =3D 0; mtpar.net =3D net; mtpar.table =3D name; @@ -728,7 +721,7 @@ static bool check_underflow(const struct ip6t_entry *e) const struct xt_entry_target *t; unsigned int verdict; =20 - if (!unconditional(&e->ipv6)) + if (!unconditional(e)) return false; t =3D ip6t_get_target_c(e); if (strcmp(t->u.user.name, XT_STANDARD_TARGET) !=3D 0) @@ -748,9 +741,11 @@ check_entry_size_and_hooks(struct ip6t_entry *e, unsigned int valid_hooks) { unsigned int h; + int err; =20 if ((unsigned long)e % __alignof__(struct ip6t_entry) !=3D 0 || - (unsigned char *)e + sizeof(struct ip6t_entry) >=3D limit) { + (unsigned char *)e + sizeof(struct ip6t_entry) >=3D limit || + (unsigned char *)e + e->next_offset > limit) { duprintf("Bad offset %p\n", e); return -EINVAL; } @@ -762,6 +757,10 @@ check_entry_size_and_hooks(struct ip6t_entry *e, return -EINVAL; } =20 + err =3D check_entry(e); + if (err) + return err; + /* Check hooks & underflows */ for (h =3D 0; h < NF_INET_NUMHOOKS; h++) { if (!(valid_hooks & (1 << h))) @@ -770,9 +769,9 @@ check_entry_size_and_hooks(struct ip6t_entry *e, newinfo->hook_entry[h] =3D hook_entries[h]; if ((unsigned char *)e - base =3D=3D underflows[h]) { if (!check_underflow(e)) { - pr_err("Underflows must be unconditional and " - "use the STANDARD target with " - "ACCEPT/DROP\n"); + pr_debug("Underflows must be unconditional and " + "use the STANDARD target with " + "ACCEPT/DROP\n"); return -EINVAL; } newinfo->underflow[h] =3D underflows[h]; @@ -1510,7 +1509,8 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_= entry *e, =20 duprintf("check_compat_entry_size_and_hooks %p\n", e); if ((unsigned long)e % __alignof__(struct compat_ip6t_entry) !=3D 0 || - (unsigned char *)e + sizeof(struct compat_ip6t_entry) >=3D limit) { + (unsigned char *)e + sizeof(struct compat_ip6t_entry) >=3D limit || + (unsigned char *)e + e->next_offset > limit) { duprintf("Bad offset %p, limit =3D %p\n", e, limit); return -EINVAL; } @@ -1523,7 +1523,7 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_= entry *e, } =20 /* For purposes of check_entry casting the compat entry is fine */ - ret =3D check_entry((struct ip6t_entry *)e, name); + ret =3D check_entry((struct ip6t_entry *)e); if (ret) return ret; =20 diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 52ce1969d9b2..1dbd1d10ca9d 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -553,7 +553,7 @@ out: static inline void ipip6_ecn_decapsulate(const struct iphdr *iph, struct s= k_buff *skb) { if (INET_ECN_is_ce(iph->tos)) - IP6_ECN_set_ce(ipv6_hdr(skb)); + IP6_ECN_set_ce(skb, ipv6_hdr(skb)); } =20 static int ipip6_rcv(struct sk_buff *skb) diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c index 23ecd68a5e62..e33c9d7a4f85 100644 --- a/net/ipv6/xfrm6_mode_tunnel.c +++ b/net/ipv6/xfrm6_mode_tunnel.c @@ -24,7 +24,7 @@ static inline void ipip6_ecn_decapsulate(struct sk_buff *= skb) struct ipv6hdr *inner_iph =3D ipipv6_hdr(skb); =20 if (INET_ECN_is_ce(ipv6_get_dsfield(outer_iph))) - IP6_ECN_set_ce(inner_iph); + IP6_ECN_set_ce(skb, inner_iph); } =20 /* Add encapsulation header. diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index cf98d625d958..fc36accd487d 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c @@ -708,6 +708,9 @@ static int iucv_sock_bind(struct socket *sock, struct s= ockaddr *addr, if (!addr || addr->sa_family !=3D AF_IUCV) return -EINVAL; =20 + if (addr_len < sizeof(struct sockaddr_iucv)) + return -EINVAL; + lock_sock(sk); if (sk->sk_state !=3D IUCV_OPEN) { err =3D -EBADFD; diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index 334a93d1a8ed..2d9b98ecbd73 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c @@ -129,12 +129,11 @@ static int l2tp_ip_recv(struct sk_buff *skb) int length; int offset; =20 - /* Point to L2TP header */ - optr =3D ptr =3D skb->data; - if (!pskb_may_pull(skb, 4)) goto discard; =20 + /* Point to L2TP header */ + optr =3D ptr =3D skb->data; session_id =3D ntohl(*((__be32 *) ptr)); ptr +=3D 4; =20 @@ -162,6 +161,9 @@ static int l2tp_ip_recv(struct sk_buff *skb) if (!pskb_may_pull(skb, length)) goto discard; =20 + /* Point to L2TP header */ + optr =3D ptr =3D skb->data; + ptr +=3D 4; printk(KERN_DEBUG "%s: ip recv: ", tunnel->name); =20 offset =3D 0; diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 1914f5a6d6e7..feb7e67413c2 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -344,12 +344,16 @@ static int sta_info_finish_insert(struct sta_info *st= a, { struct ieee80211_local *local =3D sta->local; struct ieee80211_sub_if_data *sdata =3D sta->sdata; - struct station_info sinfo; + struct station_info *sinfo; unsigned long flags; int err =3D 0; =20 lockdep_assert_held(&local->sta_mtx); =20 + sinfo =3D kzalloc(sizeof(struct station_info), GFP_KERNEL); + if (!sinfo) + return -ENOMEM; + if (!sta->dummy || dummy_reinsert) { /* notify driver */ if (sdata->vif.type =3D=3D NL80211_IFTYPE_AP_VLAN) @@ -358,8 +362,10 @@ static int sta_info_finish_insert(struct sta_info *sta, u.ap); err =3D drv_sta_add(local, sdata, &sta->sta); if (err) { - if (!async) + if (!async) { + kfree(sinfo); return err; + } printk(KERN_DEBUG "%s: failed to add IBSS STA %pM to " "driver (%d) - keeping it anyway.\n", sdata->name, sta->sta.addr, err); @@ -397,12 +403,11 @@ static int sta_info_finish_insert(struct sta_info *st= a, ieee80211_sta_debugfs_add(sta); rate_control_add_sta_debugfs(sta); =20 - memset(&sinfo, 0, sizeof(sinfo)); - sinfo.filled =3D 0; - sinfo.generation =3D local->sta_generation; - cfg80211_new_sta(sdata->dev, sta->sta.addr, &sinfo, GFP_KERNEL); + sinfo->generation =3D local->sta_generation; + cfg80211_new_sta(sdata->dev, sta->sta.addr, sinfo, GFP_KERNEL); } =20 + kfree(sinfo); return 0; } =20 diff --git a/net/netfilter/ipvs/ip_vs_pe_sip.c b/net/netfilter/ipvs/ip_vs_p= e_sip.c index 87ecf759323b..4fe530e971f6 100644 --- a/net/netfilter/ipvs/ip_vs_pe_sip.c +++ b/net/netfilter/ipvs/ip_vs_pe_sip.c @@ -85,7 +85,7 @@ ip_vs_sip_fill_param(struct ip_vs_conn_param *p, struct s= k_buff *skb) dptr =3D skb->data + dataoff; datalen =3D skb->len - dataoff; =20 - if (get_callid(dptr, dataoff, datalen, &matchoff, &matchlen)) + if (get_callid(dptr, 0, datalen, &matchoff, &matchlen)) return -EINVAL; =20 /* N.B: pe_data is only set on success, diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c index d65f699fbf34..1e29f71ed3c6 100644 --- a/net/phonet/af_phonet.c +++ b/net/phonet/af_phonet.c @@ -377,6 +377,10 @@ static int phonet_rcv(struct sk_buff *skb, struct net_= device *dev, struct sockaddr_pn sa; u16 len; =20 + skb =3D skb_share_check(skb, GFP_ATOMIC); + if (!skb) + return NET_RX_DROP; + /* check we have at least a full Phonet header */ if (!pskb_pull(skb, sizeof(struct phonethdr))) goto out; diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 054c6a285661..428fa6f69bd8 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -515,6 +515,8 @@ static int sctp_v6_cmp_addr(const union sctp_addr *addr= 1, } return 0; } + if (addr1->v6.sin6_port !=3D addr2->v6.sin6_port) + return 0; if (!ipv6_addr_equal(&addr1->v6.sin6_addr, &addr2->v6.sin6_addr)) return 0; /* If this is a linklocal address, compare the scope_id. */ diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index de35e01f03a9..149deaefc0d6 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -67,6 +67,8 @@ #include #include =20 +#define MAX_SCTP_PORT_HASH_ENTRIES (64 * 1024) + /* Global data structures. */ struct sctp_globals sctp_globals __read_mostly; DEFINE_SNMP_STAT(struct sctp_mib, sctp_statistics) __read_mostly; @@ -1206,6 +1208,8 @@ SCTP_STATIC __init int sctp_init(void) unsigned long limit; int max_share; int order; + int num_entries; + int max_entry_order; =20 /* SCTP_DEBUG sanity check. */ if (!sctp_sanity_check()) @@ -1316,14 +1320,24 @@ SCTP_STATIC __init int sctp_init(void) =20 /* Size and allocate the association hash table. * The methodology is similar to that of the tcp hash tables. + * Though not identical. Start by getting a goal size */ if (totalram_pages >=3D (128 * 1024)) goal =3D totalram_pages >> (22 - PAGE_SHIFT); else goal =3D totalram_pages >> (24 - PAGE_SHIFT); =20 - for (order =3D 0; (1UL << order) < goal; order++) - ; + /* Then compute the page order for said goal */ + order =3D get_order(goal); + + /* Now compute the required page order for the maximum sized table we + * want to create + */ + max_entry_order =3D get_order(MAX_SCTP_PORT_HASH_ENTRIES * + sizeof(struct sctp_bind_hashbucket)); + + /* Limit the page order by that maximum hash table size */ + order =3D min(order, max_entry_order); =20 do { sctp_assoc_hashsize =3D (1UL << order) * PAGE_SIZE / @@ -1357,27 +1371,42 @@ SCTP_STATIC __init int sctp_init(void) INIT_HLIST_HEAD(&sctp_ep_hashtable[i].chain); } =20 - /* Allocate and initialize the SCTP port hash table. */ + /* Allocate and initialize the SCTP port hash table. + * Note that order is initalized to start at the max sized + * table we want to support. If we can't get that many pages + * reduce the order and try again + */ do { - sctp_port_hashsize =3D (1UL << order) * PAGE_SIZE / - sizeof(struct sctp_bind_hashbucket); - if ((sctp_port_hashsize > (64 * 1024)) && order > 0) - continue; sctp_port_hashtable =3D (struct sctp_bind_hashbucket *) __get_free_pages(GFP_ATOMIC|__GFP_NOWARN, order); } while (!sctp_port_hashtable && --order > 0); + if (!sctp_port_hashtable) { pr_err("Failed bind hash alloc\n"); status =3D -ENOMEM; goto err_bhash_alloc; } + + /* Now compute the number of entries that will fit in the + * port hash space we allocated + */ + num_entries =3D (1UL << order) * PAGE_SIZE / + sizeof(struct sctp_bind_hashbucket); + + /* And finish by rounding it down to the nearest power of two + * this wastes some memory of course, but its needed because + * the hash function operates based on the assumption that + * that the number of entries is a power of two + */ + sctp_port_hashsize =3D rounddown_pow_of_two(num_entries); + for (i =3D 0; i < sctp_port_hashsize; i++) { spin_lock_init(&sctp_port_hashtable[i].lock); INIT_HLIST_HEAD(&sctp_port_hashtable[i].chain); } =20 - pr_info("Hash tables configured (established %d bind %d)\n", - sctp_assoc_hashsize, sctp_port_hashsize); + pr_info("Hash tables configured (established %d bind %d/%d)\n", + sctp_assoc_hashsize, sctp_port_hashsize, num_entries); =20 /* Disable ADDIP by default. */ sctp_addip_enable =3D 0; diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index eb638dd9aef8..4e0a9b934233 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -4740,7 +4740,8 @@ sctp_disposition_t sctp_sf_do_9_1_prm_abort( =20 retval =3D SCTP_DISPOSITION_CONSUME; =20 - sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); + if (abort) + sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); =20 /* Even if we can't send the ABORT due to low memory delete the * TCB. This is a departure from our typical NOMEM handling. @@ -4872,7 +4873,8 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_abort( SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT)); retval =3D SCTP_DISPOSITION_CONSUME; =20 - sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); + if (abort) + sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); =20 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, SCTP_STATE(SCTP_STATE_CLOSED)); diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 5b0e16cfaff5..9907e31eb26c 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -1524,8 +1524,7 @@ SCTP_STATIC void sctp_close(struct sock *sk, long tim= eout) struct sctp_chunk *chunk; =20 chunk =3D sctp_make_abort_user(asoc, NULL, 0); - if (chunk) - sctp_primitive_ABORT(asoc, chunk); + sctp_primitive_ABORT(asoc, chunk); } else sctp_primitive_SHUTDOWN(asoc, NULL); } diff --git a/net/socket.c b/net/socket.c index 10ea25afd7e6..bdcddce2d85d 100644 --- a/net/socket.c +++ b/net/socket.c @@ -2317,31 +2317,31 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *m= msg, unsigned int vlen, break; } =20 -out_put: - fput_light(sock->file, fput_needed); - if (err =3D=3D 0) - return datagrams; + goto out_put; =20 - if (datagrams !=3D 0) { + if (datagrams =3D=3D 0) { + datagrams =3D err; + goto out_put; + } + + /* + * We may return less entries than requested (vlen) if the + * sock is non block and there aren't enough datagrams... + */ + if (err !=3D -EAGAIN) { /* - * We may return less entries than requested (vlen) if the - * sock is non block and there aren't enough datagrams... + * ... or if recvmsg returns an error after we + * received some datagrams, where we record the + * error to return on the next call or if the + * app asks about it using getsockopt(SO_ERROR). */ - if (err !=3D -EAGAIN) { - /* - * ... or if recvmsg returns an error after we - * received some datagrams, where we record the - * error to return on the next call or if the - * app asks about it using getsockopt(SO_ERROR). - */ - sock->sk->sk_err =3D -err; - } - - return datagrams; + sock->sk->sk_err =3D -err; } +out_put: + fput_light(sock->file, fput_needed); =20 - return err; + return datagrams; } =20 SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg, diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index ab2bb42fe094..2529dab5af47 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c @@ -191,6 +191,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32= spi, int encap_type) XFRM_SKB_CB(skb)->seq.input.hi =3D seq_hi; =20 skb_dst_force(skb); + dev_hold(skb->dev); =20 nexthdr =3D x->type->input(x, skb); =20 @@ -198,6 +199,8 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32= spi, int encap_type) return 0; =20 resume: + dev_put(skb->dev); + spin_lock(&x->lock); if (nexthdr <=3D 0) { if (nexthdr =3D=3D -EBADMSG) { diff --git a/sound/core/timer.c b/sound/core/timer.c index beb41ecb2730..bc83a9653c76 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -1017,8 +1017,8 @@ static int snd_timer_s_start(struct snd_timer * timer) njiff +=3D timer->sticks - priv->correction; priv->correction =3D 0; } - priv->last_expires =3D priv->tlist.expires =3D njiff; - add_timer(&priv->tlist); + priv->last_expires =3D njiff; + mod_timer(&priv->tlist, njiff); return 0; } =20 diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 55f48fbcca38..73b13a03b2d0 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -2858,6 +2858,7 @@ static void __devinit intel8x0_measure_ac97_clock(str= uct intel8x0 *chip) =20 static struct snd_pci_quirk intel8x0_clock_list[] __devinitdata =3D { SND_PCI_QUIRK(0x0e11, 0x008a, "AD1885", 41000), + SND_PCI_QUIRK(0x1014, 0x0581, "AD1981B", 48000), SND_PCI_QUIRK(0x1028, 0x00be, "AD1885", 44100), SND_PCI_QUIRK(0x1028, 0x0177, "AD1980", 48000), SND_PCI_QUIRK(0x1028, 0x01ad, "AD1981B", 48000), diff --git a/sound/usb/clock.c b/sound/usb/clock.c index 5e634a2eb282..4c01f877227c 100644 --- a/sound/usb/clock.c +++ b/sound/usb/clock.c @@ -211,6 +211,8 @@ static int set_sample_rate_v1(struct snd_usb_audio *chi= p, int iface, unsigned char data[3]; int err, crate; =20 + if (get_iface_desc(alts)->bNumEndpoints < 1) + return -EINVAL; ep =3D get_endpoint(alts, 0)->bEndpointAddress; =20 /* if endpoint doesn't have sampling rate control, bail out */ diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 983e0719f923..d5cdf1fc051a 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -148,6 +148,8 @@ static int init_pitch_v1(struct snd_usb_audio *chip, in= t iface, unsigned char data[1]; int err; =20 + if (get_iface_desc(alts)->bNumEndpoints < 1) + return -EINVAL; ep =3D get_endpoint(alts, 0)->bEndpointAddress; =20 data[0] =3D 1; diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index b01d3cf3759e..a880e24d1962 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -136,6 +136,7 @@ static int create_fixed_stream_quirk(struct snd_usb_aud= io *chip, snd_printk(KERN_ERR "cannot memdup\n"); return -ENOMEM; } + INIT_LIST_HEAD(&fp->list); if (fp->nr_rates > MAX_NR_RATES) { kfree(fp); return -EINVAL; @@ -153,24 +154,31 @@ static int create_fixed_stream_quirk(struct snd_usb_a= udio *chip, stream =3D (fp->endpoint & USB_DIR_IN) ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; err =3D snd_usb_add_audio_stream(chip, stream, fp); - if (err < 0) { - kfree(fp); - kfree(rate_table); - return err; - } + if (err < 0) + goto error; if (fp->iface !=3D get_iface_desc(&iface->altsetting[0])->bInterfaceNumbe= r || fp->altset_idx >=3D iface->num_altsetting) { - kfree(fp); - kfree(rate_table); - return -EINVAL; + err =3D -EINVAL; + goto error; } alts =3D &iface->altsetting[fp->altset_idx]; + if (get_iface_desc(alts)->bNumEndpoints < 1) { + err =3D -EINVAL; + goto error; + } + fp->datainterval =3D snd_usb_parse_datainterval(chip, alts); fp->maxpacksize =3D le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); usb_set_interface(chip->dev, fp->iface, 0); snd_usb_init_pitch(chip, fp->iface, alts, fp); snd_usb_init_sample_rate(chip, fp->iface, alts, fp, fp->rate_max); return 0; + + error: + list_del(&fp->list); /* unlink for avoiding double-free */ + kfree(fp); + kfree(rate_table); + return err; } =20 /* @@ -237,6 +245,7 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip, fp->ep_attr =3D get_endpoint(alts, 0)->bmAttributes; fp->datainterval =3D 0; fp->maxpacksize =3D le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); + INIT_LIST_HEAD(&fp->list); =20 switch (fp->maxpacksize) { case 0x120: @@ -260,6 +269,7 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip, ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; err =3D snd_usb_add_audio_stream(chip, stream, fp); if (err < 0) { + list_del(&fp->list); /* unlink for avoiding double-free */ kfree(fp); return err; } diff --git a/sound/usb/stream.c b/sound/usb/stream.c index 33a335b8a1bd..7dce07496169 100644 --- a/sound/usb/stream.c +++ b/sound/usb/stream.c @@ -77,7 +77,9 @@ static void snd_usb_audio_pcm_free(struct snd_pcm *pcm) /* * add this endpoint to the chip instance. * if a stream with the same endpoint already exists, append to it. - * if not, create a new pcm stream. + * if not, create a new pcm stream. note, fp is added to the substream + * fmt_list and will be freed on the chip instance release. do not free + * fp or do remove it from the substream fmt_list to avoid double-free. */ int snd_usb_add_audio_stream(struct snd_usb_audio *chip, int stream, @@ -403,6 +405,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio = *chip, int iface_no) * (fp->maxpacksize & 0x7ff); fp->attributes =3D parse_uac_endpoint_attributes(chip, alts, protocol, i= face_no); fp->clock =3D clock; + INIT_LIST_HEAD(&fp->list); =20 /* some quirks for attributes here */ =20 @@ -446,6 +449,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio = *chip, int iface_no) snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint %#x\n", dev->devnum,= iface_no, altno, fp->endpoint); err =3D snd_usb_add_audio_stream(chip, stream, fp); if (err < 0) { + list_del(&fp->list); /* unlink for avoiding double-free */ kfree(fp->rate_table); kfree(fp); return err; --llIrKcgUOe3dCx0c-- --Uwl7UQhJk99r8jnw Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIVAwUBVzMb1+e/yOyVhhEJAQrzgRAAkUw2IfWXubL3WmS/HWE6DQgC+Oj9KWIS kO+KAbaJq2OBvAXI1fMl2aj0wR3RUebHwYwA7dlmcNiVeWT/5EIUGMvbkMhkgPQ+ sU9oeUFzYWtuldavcadLlTgvWk9pBRtkI7f6Fzj7bQrQ+EA0GEQJ6reFSNE0BALd MiWJozDErD2iEq8oBuvmbYoFa7MC4BFfpnAgNgUa979n2K5WYbrcx4MZn7kyWcYb fUkPoyDbvfXEiyYu6Ye87rKHTLjc+qbNSJ/+HgbaIUHVdiYSvfhl7WzV9yt40cMe csPwWn5qu6Kw3QcltYwQNIzQCG90L7gBGqSxqj1cTcQ+Irl49lrzJrO5BgVi2SOw tiJcaIP5IeSFPoZweSSHPQcpNPFyQIPakCq+utJ7+wkU7Xnh+ckaQpdZwdkxkTcF mD946SuU/pAIs40rbYs03PFk2YeL/uUYsTfqP0JR8UIAMDJd8KAB/5JkKf0DhjiQ zU+L/fRwQHKhrJQGIMFPe8OGCdQ16xAdLHQ9B+cydd2RdIEfbRis3jWMuD2ieJ5/ 6JIOuXDRkzDivC2WAUNHUcQ1x+LTd9hZOO2vaFS+AVh/0bUcZnlGtFcWqlHtk55j D1PAWSsoWXJPoi0PVU+YvW42LLO8gKCpIDnr53+WHxPeiCS1BnNgqQG8qMsW09te zaoYu3vROuE= =hafb -----END PGP SIGNATURE----- --Uwl7UQhJk99r8jnw--