Skip to contentSkip to conversation

v2.6.34.9 longterm review

PATCH In review Paul Gortmaker 2 participants 212 messages Apr 14, 2011 Page 1 of 2

Subsystems (92)
lore
Share & tools
lore
#0 lore raw

cover v2.6.34.9 longterm review

This is the start of the longterm review cycle for the v2.6.34.9 release. There are 209 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let us know. If anyone is a maintainer of the proper subsystem, and wants to add a Signed-off-by: line to the patch, please respond with it.

Reponses should be made within 72 hours.

Al Viro (1):
Fix sget() race with failing mount

Alan Stern (1):
USB: EHCI: fix obscure race in ehci_endpoint_disable

Alex Deucher (2):
drm/radeon/kms: handle the case of no active displays properly in the
bandwidth code
drm/kms: remove spaces from connector names (v2)

Alexander Shishkin (1):
crypto: testmgr - add an option to disable cryptoalgos' self-tests

Alexey Starikovskiy (1):
ACPI: EC: Add another dmi match entry for MSI hardware

Antonio Ospite (2):
HID: hidraw, fix a NULL pointer dereference in hidraw_ioctl
HID: hidraw, fix a NULL pointer dereference in hidraw_write

Apollon Oikonomopoulos (1):
x25: decrement netdev reference counts on unload

Avi Kivity (1):
KVM: VMX: Fix host userspace gsbase corruption

Ben Hutchings (2):
net: NETIF_F_HW_CSUM does not imply FCoE CRC offload
niu: Fix kernel buffer overflow for ETHTOOL_GRXCLSRLALL

Bob Moore (1):
Subject: [PATCH] ACPICA: Fix Scope() op in module level code

Borislav Petkov (1):
amd64_edac: Fix interleaving check

Changli Gao (2):
act_nat: use stack variable
ifb: goto resched directly if error happens and dp->tq isn't empty

Chris Wilson (1):
drm/i915: Unset cursor if out-of-bounds upon mode change (v4)

Christian Lamparter (1):
p54usb: add 5 more USBIDs

Chuck Lever (1):
NFS: Fix panic after nfs_umount()

Clemens Ladisch (3):
hpet: fix unwanted interrupt due to stale irq status bit
firewire: ohci: fix buffer overflow in AR split packet handling
firewire: ohci: fix race in AR split packet handling

Dan Carpenter (2):
IB/uverbs: Handle large number of entries in poll CQ
av7110: check for negative array offset

Dan Rosenberg (9):
ipc: initialize structure memory to zero for compat functions
sys_semctl: fix kernel stack leakage
DECnet: don't leak uninitialized stack byte V4L/DVB: ivtvfb: prevent reading uninitialized stack memory
x25: Prevent crashing when parsing bad X.25 facilities
rds: Integer overflow in RDS cmsg handling
Fix pktcdvd ioctl dev_minor range check
sound: Prevent buffer overflow in OSS load_mixer_volumes
sctp: Fix out-of-bounds reading in sctp_asoc_get_hmac()

Dan Williams (1):
ioat2: catch and recover from broken vtd configurations v6

Daniel Klaffenbach (1):
ssb: b43-pci-bridge: Add new vendor for BCM4318

Daniel T Chen (4):
ALSA: ac97: Apply quirk for Dell Latitude D610 binding Master and
Headphone controls
ALSA: hda: Use "alienware" model quirk for another SSID
ALSA: hda: Use model=lg quirk for LG P1 Express to enable playback
and capture
ALSA: hda: Use LPIB quirk for Dell Inspiron m101z/1120

Darrick J. Wong (1):
PCI: fix offset check for sysfs mmapped files

Dave Airlie (1):
drm: fix unsigned vs signed comparison issue in modeset ctl ioctl.

Dave Hansen (1):
mm/vfs: revalidate page->mapping in do_generic_file_read()

Dave Jones (1):
ACPI: debugfs custom_method open to non-root

David Henningsson (1):
ALSA: HDA: Add an extra DAC for Realtek ALC887-VD

David Howells (1):
CRED: Fix RCU warning due to previous patch fixing __task_cred()'s
checks

David Kilroy (2):
orinoco: fix TKIP countermeasure behaviour
orinoco: clear countermeasure setting on commit

David S. Miller (10):
sparc64: Fix race in signal instruction flushing.
sparc: Don't mask signal when we can't setup signal frame.
sparc: Prevent no-handler signal syscall restart recursion.
net: Limit socket I/O iovec total length to INT_MAX.
filter: make sure filters dont read uninitialized memory
tcp: Don't change unlocked socket state in tcp_v4_err().
tcp: Increase TCP_MAXSEG socket option minimum.
tcp: Make TCP_MAXSEG minimum more correct.
econet: Fix crash in aun_incoming().
x25: Do not reference freed memory.

Dmitry Torokhov (1):
Input: i8042 - add Sony VAIO VPCZ122GX to nomux list

Eduardo Costa (1):
p54usb: New USB ID for Gemtek WUBI-100GW

Eric Dumazet (11):
udp: add rehash on connect()
numa: fix slab_node(MPOL_BIND)
netfilter: nf_conntrack: allow nf_ct_alloc_hashtable() to get highmem
pages
net: avoid limits overflow
sysctl: min/max bounds are optional
sysctl: fix min/max handling in __do_proc_doulongvec_minmax() net sched: fix some kernel memory leaks
tcp: avoid a possible divide by zero
af_unix: limit unix_tot_inflight
af_unix: limit recursion level
filter: fix sk_filter rcu handling

Felix Fietkau (2):
ath9k: fix retry count for A-MPDU rate control status reports
ath9k_hw: fix antenna diversity on AR9285

Florian Faber (1):
USB: ftdi_sio: Add D.O.Tec PID

Florian Tobias Schandinat (1):
viafb: use proper register for colour when doing fill ops

Francisco Jerez (1):
drm/ttm: Clear the ghost cpu_writers flag on
ttm_buffer_object_transfer.

Gabriele Gorla (2):
hwmon: (adm1026) Allow 1 as a valid divider value
hwmon: (adm1026) Fix setting fan_div

Graham Gower (1):
drivers/char/vt_ioctl.c: fix VT_OPENQRY error value

Greg Kroah-Hartman (12):
Staging: asus_oled: fix up some sysfs attribute permissions
Staging: asus_oled: fix up my fixup for some sysfs attribute
permissions
Staging: line6: fix up some sysfs attribute permissions
Staging: line6: fix up my fixup for some sysfs attribute permissions
USB: storage: sierra_ms: fix sysfs file attribute
USB: atm: ueagle-atm: fix up some permissions on the sysfs files
USB: misc: cypress_cy7c63: fix up some sysfs attribute permissions
USB: misc: usbled: fix up some sysfs attribute permissions
USB: misc: trancevibrator: fix up a sysfs attribute permission
USB: misc: usbsevseg: fix up some sysfs attribute permissions
Staging: frontier: fix up some sysfs attribute permissions
Staging: frontier: fix up my fixup for some sysfs attribute
permissions

Guenter Roeck (1):
hwmon: (w83627ehf) Fix max_output and step_output readings

Guo-Fu Tseng (1):
jme: Fix PHY power-off error

H. Peter Anvin (6):
x86-32: Fix dummy trampoline-related inline stubs
x86, mwait: Move mwait constants to a common header file x86, hotplug: Use mwait to offline a processor, fix the legacy case x86, hotplug: Move WBINVD back outside the play_dead loop x86, hotplug: In the MWAIT case of play_dead, CLFLUSH the cache line x86, gcc-4.6: Use gcc -m options when building vdso

Heiko Carstens (3):
nmi: fix clock comparator revalidation
nohz: Fix printk_needs_cpu() return value on offline cpus
nohz: Fix get_next_timer_interrupt() vs cpu hotplug

Herbert Xu (1):
crypto: padlock - Fix AES-CBC handling on odd-block-sized input

Hillf Danton (1):
bonding: Fix slave selection bug.

Hugh Dickins (1):
x86, mm: Fix CONFIG_VMSPLIT_1G and 2G_OPT trampoline

Ian Campbell (1):
xen: ensure that all event channels start off bound to VCPU 0

Jack Steiner (2):
x86, UV: Delete unneeded boot messages
x86, UV: Fix initialization of max_pnode

Jacques Viviers (1):
USB: serial: ftdi_sio: Vardaan USB RS422/485 converter PID added

James Jones (1):
ARM: 6482/2: Fix find_next_zero_bit and related assembly

Jarek Poplawski (1):
gianfar: Fix crashes on RX path (Was Re: [Bugme-new] [Bug 19692] New:
linux-2.6.36-rc5 crash with gianfar ethernet at full line rate traffic)

Jean Delvare (1):
hwmon: (lm85) Fix ADT7468 frequency table

Jeff Kirsher (1):
e100/e1000*/igb*/ixgb*: Add missing read memory barrier

Jeff Mahoney (1):
net sched: fix kernel leak in act_police

Jens Axboe (4):
block: limit vec count in bio_kmalloc() and bio_alloc_map_data()
block: take care not to overflow when calculating total iov length
block: check for proper length of iov entries in

    blk_rq_map_user_iov()

bio: take care not overflow page count when mapping/copying user data

Jeremy Fitzhardinge (1):
xen: don't bother to stop other cpus on shutdown/reboot

Jiri Olsa (1):
tty: prevent DOS in the flush_to_ldisc

Jiri Slaby (5):
hpet: unmap unused I/O space
TTY: restore tty_ldisc_wait_idle
TTY: ldisc, fix open flag handling
TTY: don't allow reopen when ldisc is changing
HID: hidraw: fix window in hidraw_release

Joe Jin (1):
driver/net/benet: fix be_cmd_multicast_set() memcpy bug

Joerg Roedel (1):
x86-32: Separate 1:1 pagetables from swapper_pg_dir

Johan Hovold (1):
USB: ftdi_sio: revert "USB: ftdi_sio: fix DTR/RTS line modes"

Julien Tinnes (1):
Prevent rt_sigqueueinfo and rt_tgsigqueueinfo from spoofing the
signal code

Justin Maggard (1):
md: fix return value of rdev_size_change()

KAMEZAWA Hiroyuki (2):
mm: fix return value of scan_lru_pages in memory unplug
mm: fix is_mem_section_removable() page_order BUG_ON check

Kees Cook (1):
net: clear heap allocation for ETHTOOL_GRXCLSRLALL

Ken Chen (1):
latencytop: fix per task accumulator

Ken Sumrall (1):
fuse: fix attributes after open(O_TRUNC)

Kenji Kaneshige (2):
x86: Enable the intr-remap fault handling after local APIC setup x86, vt-d: Fix the vt-d fault handling irq migration in the x2apic
mode

Krishna Gudipati (1):
bfa: fix system crash when reading sysfs fc_host statistics

Larry Finger (1):
staging: rtl8187se: Change panic to warn when RF switch turned off

Li Zefan (1):
sunrpc/cache: fix module refcnt leak in a failure path

Linus Torvalds (1):
net: Truncate recvfrom and sendto length to INT_MAX.

Luke Macken (1):
efifb: support the EFI framebuffer on more Apple hardware

Lytochkin Boris (1):
serial: add support for OX16PCI958 card

Martin K. Petersen (2):
block: Ensure physical block size is unsigned int
block: Deprecate QUEUE_FLAG_CLUSTER and use queue_limits instead

Martin Wilck (1):
PCI: fix size checks for mmap() on /proc/bus/pci files

Masanori ITOH (1):
percpu: fix list_head init bug in __percpu_counter_init()

Michael Stuermer (1):
USB: ftdi_sio: Add ID for RT Systems USB-29B radio cable

Michel Dänzer (1):
drm/radeon: fall back to GTT if bo creation/validation in VRAM fails.

Miklos Szeredi (2):
fuse: verify ioctl retries
fuse: fix ioctl when server is 32bit

Mimi Zohar (1):
ima: fix add LSM rule bug

Nandita Dukkipati (1):
tcp: Bug fix in initialization of receive window.

Neil Brown (1):
nfsd: Fix possible BUG_ON firing in set_change_info

NeilBrown (5):
md: fix another deadlock with removing sysfs attributes. md/raid1: really fix recovery looping when single good device fails.
sunrpc: prevent use-after-free on clearing XPT_BUSY
md: fix bug with re-adding of partially recovered device.
md: fix regression with re-adding devices to arrays with no metadata

Nelson Elhage (2):
do_exit(): make sure that we run with get_fs() == USER_DS
econet: Do the correct cleanup after an unprivileged SIOCSIFADDR.

Nobuhiro Iwamatsu (1):
i2c-pca-platform: Change device name of request_irq

Oleg Nesterov (2):
exec: make argv/envp memory visible to oom-killer
posix-cpu-timers: workaround to suppress the problems with mt exec

Oliver Hartkopp (1):
can-bcm: fix minor heap overflow

Pekka Enberg (1):
perf_events: Fix perf_counter_mmap() hook in mprotect()

Peter Jones (1):
efifb: check that the base address is plausible on pci systems

Phil Blundell (3):
econet: disallow NULL remote addr for sendmsg(), fixes CVE-2010-3849
econet: fix CVE-2010-3850
econet: fix CVE-2010-3848

Philipp Reisner (1):
drbd: Initialize all members of sync_conf to their defaults [Bugz

    315]

Philippe Rétornaz (1):
tty_ldisc: Fix BUG() on hangup

Randy Dunlap (1):
PCI: sysfs: fix printk warnings

Richard A. Smith (1):
olpc_battery: Fix endian neutral breakage for s16 values

Richard Weinberger (2):
um: remove PAGE_SIZE alignment in linker script causing kernel
segfault.
um: fix global timer issue when using CONFIG_NO_HZ

[email protected] (1):
sgi-xpc: XPC fails to discover partitions with all nasids above 128

Roland Dreier (1):
Relax si_code check in rt_sigqueueinfo and rt_tgsigqueueinfo

Saeed Bishara (1):
mv_xor: fix race in tasklet function

Samuel Ortiz (2):
irda: Fix parameter extraction stack overflow
irda: Fix heap memory corruption in iriap.c

Sebastien Bourdeauducq (1):
USB: ftdi_sio: add device IDs for Milkymist One JTAG/serial

Sergey Vlasov (1):
NFS: Fix fcntl F_GETLK not reporting some conflicts

Slava Pestov (1):
tracing: Fix panic when lseek() called on "trace" opened for writing

Steven J. Magnani (1):
nommu: yield CPU while disposing VM

Suresh Siddha (2):
x86, vt-d: Handle previous faults after enabling fault handling x86, vt-d: Quirk for masking vtd spec errors to platform error
handling logic

Takashi Iwai (2):
PM / Hibernate: Fix PM_POST_* notification with user-space suspend
ALSA: caiaq - Fix possible string-buffer overflow

Tavis Ormandy (1):
install_special_mapping skips security_file_mmap check.

Tejun Heo (1):
libata: fix NULL sdev dereference race in atapi_qc_complete()

Thomas Backlund (1):
microblaze: Fix build with make 3.82

Thomas Sailer (1):
USB: misc: uss720.c: add another vendor/product ID

Tyler Hicks (1):
eCryptfs: Clear LOOKUP_OPEN flag when creating lower file

Uwe Kleine-König (1):
backlight: grab ops_lock before testing bd->ops

Vasiliy Kulikov (7):
ipc: shm: fix information leak to userland
KVM: x86: fix information leak to userland
usb: misc: sisusbvga: fix information leak to userland
usb: misc: iowarrior: fix information leak to userland
usb: core: fix information leak to userland
net: packet: fix information leak to userland
net: don't allow CAP_NET_ADMIN to load non-netdev kernel modules

Vitaly Kuznetsov (1):
USB: usb-storage: unusual_devs entry for the Samsung YP-CP3

Will Deacon (1):
ARM: 6489/1: thumb2: fix incorrect optimisation in usracc

Will Newton (1):
uml: disable winch irq before freeing handler data

Xiaotian Feng (1):
block: check for proper length of iov entries earlier in

    blk_rq_map_user_iov()

Zhang Rui (1):
acpi-cpufreq: fix a memleak when unloading driver

andrew hendry (1):
memory corruption in X.25 facilities parsing

ma rui (1):
USB: option: fix when the driver is loaded incorrectly for some
Huawei devices.

stephen hemminger (1):
ip6ip6: autoload ip6 tunnel

 MAINTAINERS                                  |    6 +
 arch/arm/include/asm/assembler.h             |    2 +-
 arch/arm/lib/findbit.S                       |    6 +-
 arch/microblaze/Makefile                     |    8 +-
 arch/s390/kernel/nmi.c                       |   10 +-
 arch/s390/lib/delay.c                        |   14 +-
 arch/sparc/kernel/signal32.c                 |  161 ++++++++++++--------
 arch/sparc/kernel/signal_32.c                |   55 +++++---
 arch/sparc/kernel/signal_64.c                |   45 ++++--
 arch/um/drivers/line.c                       |    5 +-
 arch/um/kernel/uml.lds.S                     |    2 +-
 arch/um/os-Linux/time.c                      |    2 +-
 arch/x86/include/asm/mwait.h                 |   15 ++
 arch/x86/include/asm/pgtable_32.h            |    1 +
 arch/x86/include/asm/processor.h             |   23 ---
 arch/x86/include/asm/trampoline.h            |    5 +-
 arch/x86/kernel/acpi/cstate.c                |   11 +--
 arch/x86/kernel/apic/apic.c                  |    8 +
 arch/x86/kernel/apic/io_apic.c               |    1 +
 arch/x86/kernel/apic/probe_64.c              |    7 -
 arch/x86/kernel/apic/x2apic_uv_x.c           |    9 +-
 arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c   |    1 +
 arch/x86/kernel/head_32.S                    |    8 +-
 arch/x86/kernel/setup.c                      |    2 +
 arch/x86/kernel/smpboot.c                    |  112 ++++++++++++---
 arch/x86/kernel/trampoline.c                 |   17 ++
 arch/x86/kvm/vmx.c                           |   15 +-
 arch/x86/kvm/x86.c                           |    5 +
 arch/x86/vdso/Makefile                       |    4 +-
 arch/x86/xen/enlighten.c                     |    4 -
 block/blk-map.c                              |    3 +
 block/blk-merge.c                            |    6 +-
 block/blk-settings.c                         |   27 +---
 block/blk-sysfs.c                            |    2 +-
 block/scsi_ioctl.c                           |   34 +++--
 crypto/Kconfig                               |    8 +
 crypto/algboss.c                             |    4 +
 crypto/testmgr.c                             |   14 ++
 drivers/acpi/acpi_pad.c                      |    7 +-
 drivers/acpi/acpica/dswexec.c                |   19 ++-
 drivers/acpi/debug.c                         |    2 +-
 drivers/acpi/ec.c                            |    3 +
 drivers/ata/libata-scsi.c                    |    5 +-
 drivers/block/drbd/drbd_main.c               |   17 ++-
 drivers/block/pktcdvd.c                      |    2 +-
 drivers/char/hpet.c                          |   17 ++
 drivers/char/tty_buffer.c                    |   14 ++-
 drivers/char/tty_io.c                        |    3 +-
 drivers/char/tty_ldisc.c                     |   51 ++++++-
 drivers/char/vt_ioctl.c                      |   11 +-
 drivers/crypto/padlock-aes.c                 |    2 +-
 drivers/dma/ioat/dma.h                       |    1 +
 drivers/dma/ioat/dma_v2.c                    |   24 +++-
 drivers/dma/ioat/dma_v3.c                    |    5 +-
 drivers/dma/mv_xor.c                         |    2 +-
 drivers/edac/amd64_edac.c                    |    2 +-
 drivers/firewire/ohci.c                      |   64 +++++++--
 drivers/gpu/drm/drm_crtc.c                   |   10 +-
 drivers/gpu/drm/drm_irq.c                    |    3 +-
 drivers/gpu/drm/i915/intel_display.c         |  144 ++++++++++++-------
 drivers/gpu/drm/i915/intel_drv.h             |    8 +-
 drivers/gpu/drm/radeon/radeon_object.c       |   27 +++-
 drivers/gpu/drm/radeon/rs690.c               |   27 +---
 drivers/gpu/drm/radeon/rv515.c               |   23 +--
 drivers/gpu/drm/ttm/ttm_bo_util.c            |    1 +
 drivers/hid/hidraw.c                         |   27 +++-
 drivers/hwmon/adm1026.c                      |   20 ++--
 drivers/hwmon/lm85.c                         |    1 +
 drivers/hwmon/w83627ehf.c                    |   13 ++-
 drivers/i2c/busses/i2c-pca-platform.c        |    2 +-
 drivers/infiniband/core/uverbs_cmd.c         |  101 +++++++------
 drivers/input/serio/i8042-x86ia64io.h        |    7 +
 drivers/md/dm-table.c                        |    5 -
 drivers/md/md.c                              |   50 ++++---
 drivers/md/md.h                              |    4 +
 drivers/md/raid1.c                           |    1 +
 drivers/media/dvb/ttpci/av7110_ca.c          |    2 +-
 drivers/media/video/ivtv/ivtvfb.c            |    2 +
 drivers/misc/sgi-xp/xpc_partition.c          |   25 ++--
 drivers/net/benet/be_cmds.c                  |    2 +-
 drivers/net/bonding/bonding.h                |    4 +-
 drivers/net/e100.c                           |    2 +
 drivers/net/e1000/e1000_main.c               |    3 +
 drivers/net/e1000e/netdev.c                  |    4 +
 drivers/net/gianfar.c                        |    6 +-
 drivers/net/ifb.c                            |    2 +
 drivers/net/igb/igb_main.c                   |    2 +
 drivers/net/igbvf/netdev.c                   |    2 +
 drivers/net/ixgb/ixgb_main.c                 |    2 +
 drivers/net/ixgbe/ixgbe_main.c               |    1 +
 drivers/net/ixgbevf/ixgbevf_main.c           |    2 +
 drivers/net/jme.c                            |   22 +++-
 drivers/net/niu.c                            |   16 +--
 drivers/net/wireless/ath/ath9k/eeprom.h      |    2 +-
 drivers/net/wireless/ath/ath9k/eeprom_4k.c   |    4 +-
 drivers/net/wireless/ath/ath9k/eeprom_9287.c |    4 +-
 drivers/net/wireless/ath/ath9k/eeprom_def.c  |    4 +-
 drivers/net/wireless/ath/ath9k/xmit.c        |   10 +-
 drivers/net/wireless/orinoco/main.c          |    6 +
 drivers/net/wireless/orinoco/wext.c          |    4 +-
 drivers/net/wireless/p54/p54usb.c            |    6 +
 drivers/pci/dmar.c                           |    5 +
 drivers/pci/intel-iommu.c                    |   27 ++++
 drivers/pci/pci-sysfs.c                      |   23 ++-
 drivers/pci/pci.h                            |    7 +-
 drivers/pci/proc.c                           |    2 +-
 drivers/pci/quirks.c                         |   23 +++
 drivers/power/olpc_battery.c                 |    8 +-
 drivers/scsi/bfa/bfa_core.c                  |   22 +++
 drivers/scsi/scsi_lib.c                      |    3 +-
 drivers/serial/8250_pci.c                    |   13 ++
 drivers/ssb/b43_pci_bridge.c                 |    1 +
 drivers/staging/asus_oled/asus_oled.c        |    8 +-
 drivers/staging/frontier/tranzport.c         |    2 +-
 drivers/staging/line6/control.c              |  204 +++++++++++++-------------
 drivers/staging/line6/midi.c                 |    4 +-
 drivers/staging/line6/pod.c                  |   32 ++--
 drivers/staging/line6/toneport.c             |    4 +-
 drivers/staging/line6/variax.c               |   12 +-
 drivers/staging/rtl8187se/r8185b_init.c      |   30 +++-
 drivers/usb/atm/ueagle-atm.c                 |    6 +-
 drivers/usb/core/devio.c                     |    7 +-
 drivers/usb/host/ehci-hcd.c                  |   10 +-
 drivers/usb/misc/cypress_cy7c63.c            |    6 +-
 drivers/usb/misc/iowarrior.c                 |    1 +
 drivers/usb/misc/sisusbvga/sisusb.c          |    1 +
 drivers/usb/misc/trancevibrator.c            |    2 +-
 drivers/usb/misc/usbled.c                    |    2 +-
 drivers/usb/misc/usbsevseg.c                 |   10 +-
 drivers/usb/misc/uss720.c                    |    4 +-
 drivers/usb/serial/ftdi_sio.c                |    9 +-
 drivers/usb/serial/ftdi_sio_ids.h            |   15 ++
 drivers/usb/serial/option.c                  |    2 +-
 drivers/usb/storage/sierra_ms.c              |    2 +-
 drivers/usb/storage/unusual_devs.h           |    7 +
 drivers/video/backlight/backlight.c          |   12 +-
 drivers/video/efifb.c                        |  103 ++++++++++++--
 drivers/video/via/accel.c                    |    7 +-
 drivers/xen/events.c                         |    2 +-
 fs/bio.c                                     |   23 +++-
 fs/ecryptfs/inode.c                          |    4 +
 fs/exec.c                                    |   37 +++++-
 fs/fuse/file.c                               |   82 ++++++++++-
 fs/namespace.c                               |    2 +-
 fs/nfs/file.c                                |    2 +
 fs/nfs/mount_clnt.c                          |    4 +-
 fs/nfsd/nfs3xdr.c                            |    6 +-
 fs/nfsd/xdr4.h                               |   21 ++--
 fs/super.c                                   |    6 +
 include/drm/drmP.h                           |    2 +-
 include/linux/binfmts.h                      |    1 +
 include/linux/blkdev.h                       |   13 +-
 include/linux/fs.h                           |    1 +
 include/linux/netdevice.h                    |    3 +
 include/linux/pci_ids.h                      |    1 +
 include/linux/socket.h                       |    2 +-
 include/net/af_unix.h                        |    2 +
 include/net/dn.h                             |    2 +-
 include/net/sock.h                           |    9 +-
 include/net/tcp.h                            |    6 +-
 include/net/udp.h                            |    5 +-
 ipc/compat.c                                 |    6 +
 ipc/compat_mq.c                              |    5 +
 ipc/sem.c                                    |    2 +
 ipc/shm.c                                    |    1 +
 kernel/exit.c                                |   17 ++
 kernel/latencytop.c                          |   17 +-
 kernel/power/user.c                          |    2 +-
 kernel/printk.c                              |    2 +
 kernel/signal.c                              |   25 +++-
 kernel/sysctl.c                              |    2 +-
 kernel/sysctl_check.c                        |    9 -
 kernel/timer.c                               |    6 +
 kernel/trace/trace.c                         |   10 +-
 lib/percpu_counter.c                         |    1 +
 mm/filemap.c                                 |    3 +
 mm/internal.h                                |    2 +-
 mm/memory_hotplug.c                          |    2 +-
 mm/mempolicy.c                               |    2 +-
 mm/mmap.c                                    |   16 ++-
 mm/mprotect.c                                |    2 +-
 mm/nommu.c                                   |    1 +
 net/can/bcm.c                                |    2 +-
 net/compat.c                                 |   10 +-
 net/core/dev.c                               |   18 ++-
 net/core/ethtool.c                           |    2 +-
 net/core/filter.c                            |   83 +++++------
 net/core/iovec.c                             |   20 +--
 net/core/sock.c                              |   14 +-
 net/decnet/af_decnet.c                       |    4 +-
 net/decnet/sysctl_net_decnet.c               |    4 +-
 net/econet/af_econet.c                       |   99 ++++++-------
 net/ipv4/datagram.c                          |    5 +-
 net/ipv4/ip_gre.c                            |    1 +
 net/ipv4/ipip.c                              |    1 +
 net/ipv4/proc.c                              |    8 +-
 net/ipv4/sysctl_net_ipv4.c                   |    5 +-
 net/ipv4/tcp.c                               |    6 +-
 net/ipv4/tcp_input.c                         |   11 +-
 net/ipv4/tcp_ipv4.c                          |    8 +-
 net/ipv4/tcp_output.c                        |   15 +-
 net/ipv4/udp.c                               |   48 ++++++-
 net/ipv6/datagram.c                          |    7 +-
 net/ipv6/ip6_tunnel.c                        |    1 +
 net/ipv6/sit.c                               |    2 +-
 net/ipv6/udp.c                               |   10 ++
 net/irda/iriap.c                             |    3 +-
 net/irda/parameters.c                        |    4 +-
 net/netfilter/nf_conntrack_core.c            |    3 +-
 net/packet/af_packet.c                       |    3 +-
 net/rds/rdma.c                               |    2 +-
 net/sched/act_gact.c                         |   21 ++-
 net/sched/act_mirred.c                       |   15 +-
 net/sched/act_nat.c                          |   35 ++---
 net/sched/act_police.c                       |   21 +--
 net/sched/act_simple.c                       |   11 +-
 net/sched/act_skbedit.c                      |   11 +-
 net/sctp/auth.c                              |    8 +-
 net/sctp/protocol.c                          |    2 +-
 net/sctp/socket.c                            |    4 +-
 net/sctp/sysctl.c                            |    4 +-
 net/socket.c                                 |    4 +
 net/sunrpc/cache.c                           |    4 +-
 net/sunrpc/svc_xprt.c                        |    9 +-
 net/unix/af_unix.c                           |   37 ++++-
 net/unix/garbage.c                           |    9 +-
 net/x25/x25_facilities.c                     |   20 ++-
 net/x25/x25_in.c                             |    2 +
 net/x25/x25_link.c                           |    4 +
 security/integrity/ima/ima_policy.c          |    2 +
 sound/oss/soundcard.c                        |    4 +-
 sound/pci/hda/hda_intel.c                    |    1 +
 sound/pci/hda/patch_realtek.c                |    5 +-
 sound/pci/hda/patch_sigmatel.c               |    2 +
 sound/pci/intel8x0.c                         |    6 +
 sound/usb/caiaq/audio.c                      |    2 +-
 sound/usb/caiaq/midi.c                       |    2 +-
 237 files changed, 2119 insertions(+), 1056 deletions(-)
 create mode 100644 arch/x86/include/asm/mwait.h
Signature · 1 line
1.7.4.4
#1 lore raw

PATCH 1/209 ath9k: fix retry count for A-MPDU rate control status reports

From: Felix Fietkau <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 78c4653a2274479547e259e1f416d2b3d04c42a8 upstream.

The 'bf_retries' field of the ath_buf structure was used for both software retries (AMPDU subframes) and hardware retries (legacy frames). This led to a wrong retry count being reported for the A-MPDU rate control stats.
This patch changes the code to no longer use bf_retries for reporting retry counts, but instead always using the real on-chip retry count from the ath_tx_status.
Additionally, if the first subframe of an A-MPDU was not acked, the tx status report is submitted along with the first acked subframe, which may not contain the correct rates in the tx info.
This is easily corrected by saving the tx rate info before looping over subframes, and then copying it back once the A-MPDU status report is submitted.
In my tests this change improves throughput visibly.

[PG: 34 doesnt have ts as an alias for ds->ds_txstat, so change accordingly]

---
 drivers/net/wireless/ath/ath9k/xmit.c |   10 ++++++++--
 1 files changed, 8 insertions(+), 2 deletions(-)
drivers/net/wireless/ath/ath9k/xmit.c +8 -2
index 0b2ade3..5111c7d 100644
@@ -302,6 +302,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 	u32 ba[WME_BA_BMP_SIZE >> 5];
 	int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
 	bool rc_update = true;
+	struct ieee80211_tx_rate rates[4];
 
 	skb = bf->bf_mpdu;
 	hdr = (struct ieee80211_hdr *)skb->data;
@@ -309,6 +310,8 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 	tx_info = IEEE80211_SKB_CB(skb);
 	hw = bf->aphy->hw;
 
+	memcpy(rates, tx_info->control.rates, sizeof(rates));
+
 	rcu_read_lock();
 
 	/* XXX: use ieee80211_find_sta! */
@@ -350,6 +353,9 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 		txfail = txpending = 0;
 		bf_next = bf->bf_next;
 
+		skb = bf->bf_mpdu;
+		tx_info = IEEE80211_SKB_CB(skb);
+
 		if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, bf->bf_seqno))) {
 			/* transmit completion, subframe is
 			 * acked by block ack */
@@ -402,6 +408,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 			spin_unlock_bh(&txq->axq_lock);
 
 			if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) {
+				memcpy(tx_info->control.rates, rates, sizeof(rates));
 				ath_tx_rc_status(bf, ds, nbad, txok, true);
 				rc_update = false;
 			} else {
@@ -1952,7 +1959,7 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
 		tx_info->status.rates[i].idx = -1;
 	}
 
-	tx_info->status.rates[tx_rateindex].count = bf->bf_retries + 1;
+	tx_info->status.rates[tx_rateindex].count = ds->ds_txstat.ts_longretry + 1;
 }
 
 static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq)
@@ -2062,7 +2069,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
 			 * This frame is sent out as a single frame.
 			 * Use hardware retry status for this frame.
 			 */
-			bf->bf_retries = ds->ds_txstat.ts_longretry;
 			if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY)
 				bf->bf_state.bf_type |= BUF_XRETRY;
 			ath_tx_rc_status(bf, ds, 0, txok, true);
Signature · 1 line
1.7.4.4
#2 lore raw

PATCH 2/209 ath9k_hw: fix antenna diversity on AR9285

In reply to Paul Gortmaker

From: Felix Fietkau <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 601e0cb165e65dc185b31fe7ebd2c0169ea47306 upstream.

On AR9285, the antenna switch configuration register uses more than just 16 bits. Because of an arbitrary mask applied to the EEPROM value that stores this configuration, diversity was broken in some cases, leading to a significant degradation in signal strength.
Fix this by changing the callback to return a 32 bit value and remove the arbitrary mask.

[PG: drop ar9003_eeprom.c change; v2.6.34 doesn't have it yet]

---
 drivers/net/wireless/ath/ath9k/eeprom.h      |    2 +-
 drivers/net/wireless/ath/ath9k/eeprom_4k.c   |    4 ++--
 drivers/net/wireless/ath/ath9k/eeprom_9287.c |    4 ++--
 drivers/net/wireless/ath/ath9k/eeprom_def.c  |    4 ++--
 4 files changed, 7 insertions(+), 7 deletions(-)
drivers/net/wireless/ath/ath9k/eeprom.h +1 -1
index 104e3ea..b64b3e5 100644
@@ -670,7 +670,7 @@ struct eeprom_ops {
 	int (*get_eeprom_ver)(struct ath_hw *hw);
 	int (*get_eeprom_rev)(struct ath_hw *hw);
 	u8 (*get_num_ant_config)(struct ath_hw *hw, enum ieee80211_band band);
-	u16 (*get_eeprom_antenna_cfg)(struct ath_hw *hw,
+	u32 (*get_eeprom_antenna_cfg)(struct ath_hw *hw,
 				      struct ath9k_channel *chan);
 	void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan);
 	void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan);
drivers/net/wireless/ath/ath9k/eeprom_4k.c +2 -2
index 68db166..73cd4db 100644
@@ -1138,13 +1138,13 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
 	}
 }
 
-static u16 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah,
+static u32 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah,
 					      struct ath9k_channel *chan)
 {
 	struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
 	struct modal_eep_4k_header *pModal = &eep->modalHeader;
 
-	return pModal->antCtrlCommon & 0xFFFF;
+	return pModal->antCtrlCommon;
 }
 
 static u8 ath9k_hw_4k_get_num_ant_config(struct ath_hw *ah,
drivers/net/wireless/ath/ath9k/eeprom_9287.c +2 -2
index 839d05a..c6f77ce 100644
@@ -1130,13 +1130,13 @@ static u8 ath9k_hw_AR9287_get_num_ant_config(struct ath_hw *ah,
 	return 1;
 }
 
-static u16 ath9k_hw_AR9287_get_eeprom_antenna_cfg(struct ath_hw *ah,
+static u32 ath9k_hw_AR9287_get_eeprom_antenna_cfg(struct ath_hw *ah,
 						  struct ath9k_channel *chan)
 {
 	struct ar9287_eeprom *eep = &ah->eeprom.map9287;
 	struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
 
-	return pModal->antCtrlCommon & 0xFFFF;
+	return pModal->antCtrlCommon;
 }
 
 static u16 ath9k_hw_AR9287_get_spur_channel(struct ath_hw *ah,
drivers/net/wireless/ath/ath9k/eeprom_def.c +2 -2
index 1644b1a..e61823e 100644
@@ -1431,14 +1431,14 @@ static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah,
 	return num_ant_config;
 }
 
-static u16 ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw *ah,
+static u32 ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw *ah,
 					       struct ath9k_channel *chan)
 {
 	struct ar5416_eeprom_def *eep = &ah->eeprom.def;
 	struct modal_eep_header *pModal =
 		&(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
 
-	return pModal->antCtrlCommon & 0xFFFF;
+	return pModal->antCtrlCommon;
 }
 
 static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
Signature · 1 line
1.7.4.4
#3 lore raw

PATCH 3/209 CRED: Fix RCU warning due to previous patch fixing __task_cred()'s checks

In reply to Paul Gortmaker

From: David Howells <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 694f690d27dadccc8cb9d90532e76593b61fe098 upstream.

Commit 8f92054e7ca1 ("CRED: Fix __task_cred()'s lockdep check and banner comment") fixed the lockdep checks on __task_cred(). This has shown up a place in the signalling code where a lock should be held - namely that check_kill_permission() requires its callers to hold the RCU lock.

Fix group_send_sig_info() to get the RCU read lock around its call to check_kill_permission().

Without this patch, the following warning can occur:

===================================================
[ INFO: suspicious rcu_dereference_check() usage. ]
---------------------------------------------------
kernel/signal.c:660 invoked rcu_dereference_check() without protection!
...

---
 kernel/signal.c |    9 ++++++---
 1 files changed, 6 insertions(+), 3 deletions(-)
kernel/signal.c +6 -3
index 48f2130..edabc2f 100644
@@ -637,7 +637,7 @@ static inline bool si_fromuser(const struct siginfo *info)
 
 /*
  * Bad permissions for sending the signal
- * - the caller must hold at least the RCU read lock
+ * - the caller must hold the RCU read lock
  */
 static int check_kill_permission(int sig, struct siginfo *info,
 				 struct task_struct *t)
@@ -1126,11 +1126,14 @@ struct sighand_struct *lock_task_sighand(struct task_struct *tsk, unsigned long
 
 /*
  * send signal info to all the members of a group
- * - the caller must hold the RCU read lock at least
  */
 int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
 {
-	int ret = check_kill_permission(sig, info, p);
+	int ret;
+
+	rcu_read_lock();
+	ret = check_kill_permission(sig, info, p);
+	rcu_read_unlock();
 
 	if (!ret && sig)
 		ret = do_send_sig_info(sig, info, p, true);
Signature · 1 line
1.7.4.4
#4 lore raw

PATCH 4/209 drm/radeon: fall back to GTT if bo creation/validation in VRAM fails.

In reply to Paul Gortmaker

From: Michel Dänzer <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit e376573f7267390f4e1bdc552564b6fb913bce76 upstream.

This fixes a problem where on low VRAM cards we'd run out of space for validation.

[airlied: Tested on my M7, Thinkpad T42, compiz works with no problems.]

---
 drivers/gpu/drm/radeon/radeon_object.c |   27 ++++++++++++++++++---------
 1 files changed, 18 insertions(+), 9 deletions(-)
drivers/gpu/drm/radeon/radeon_object.c +18 -9
index 1227747..bae33b7 100644
@@ -110,16 +110,22 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj,
 	bo->surface_reg = -1;
 	INIT_LIST_HEAD(&bo->list);
 
+retry:
 	radeon_ttm_placement_from_domain(bo, domain);
 	/* Kernel allocation are uninterruptible */
 	r = ttm_bo_init(&rdev->mman.bdev, &bo->tbo, size, type,
 			&bo->placement, 0, 0, !kernel, NULL, size,
 			&radeon_ttm_bo_destroy);
 	if (unlikely(r != 0)) {
-		if (r != -ERESTARTSYS)
+		if (r != -ERESTARTSYS) {
+			if (domain == RADEON_GEM_DOMAIN_VRAM) {
+				domain |= RADEON_GEM_DOMAIN_GTT;
+				goto retry;
+			}
 			dev_err(rdev->dev,
 				"object_init failed for (%lu, 0x%08X)\n",
 				size, domain);
+		}
 		return r;
 	}
 	*bo_ptr = bo;
@@ -314,6 +320,7 @@ int radeon_bo_list_validate(struct list_head *head)
 {
 	struct radeon_bo_list *lobj;
 	struct radeon_bo *bo;
+	u32 domain;
 	int r;
 
 	r = radeon_bo_list_reserve(head);
@@ -323,17 +330,19 @@ int radeon_bo_list_validate(struct list_head *head)
 	list_for_each_entry(lobj, head, list) {
 		bo = lobj->bo;
 		if (!bo->pin_count) {
-			if (lobj->wdomain) {
-				radeon_ttm_placement_from_domain(bo,
-								lobj->wdomain);
-			} else {
-				radeon_ttm_placement_from_domain(bo,
-								lobj->rdomain);
-			}
+			domain = lobj->wdomain ? lobj->wdomain : lobj->rdomain;
+
+		retry:
+			radeon_ttm_placement_from_domain(bo, domain);
 			r = ttm_bo_validate(&bo->tbo, &bo->placement,
 						true, false);
-			if (unlikely(r))
+			if (unlikely(r)) {
+				if (r != -ERESTARTSYS && domain == RADEON_GEM_DOMAIN_VRAM) {
+					domain |= RADEON_GEM_DOMAIN_GTT;
+					goto retry;
+				}
 				return r;
+			}
 		}
 		lobj->gpu_offset = radeon_bo_gpu_offset(bo);
 		lobj->tiling_flags = bo->tiling_flags;
Signature · 1 line
1.7.4.4
#5 lore raw

PATCH 5/209 drm/radeon/kms: handle the case of no active displays properly in the bandwidth code

In reply to Paul Gortmaker

From: Alex Deucher <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit e06b14ee91a2ddefc9a67443a6cd8ee0fa800115 upstream.

Logic was:
if (mode0 && mode1)
else if (mode0)
else

Should be:
if (mode0 && mode1)
else if (mode0)
else if (mode1)

Otherwise we may end up calculating the priority regs with unitialized values.

Fixes:
https://bugzilla.kernel.org/show_bug.cgi?id=16492

---
 drivers/gpu/drm/radeon/rs690.c |   27 +++++++++------------------
 drivers/gpu/drm/radeon/rv515.c |   23 +++++++++--------------
 2 files changed, 18 insertions(+), 32 deletions(-)
drivers/gpu/drm/radeon/rs690.c +9 -18
index 97e3002..6249cf7 100644
@@ -400,7 +400,9 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
 	struct drm_display_mode *mode1 = NULL;
 	struct rs690_watermark wm0;
 	struct rs690_watermark wm1;
-	u32 tmp, d1mode_priority_a_cnt, d2mode_priority_a_cnt;
+	u32 tmp;
+	u32 d1mode_priority_a_cnt = S_006548_D1MODE_PRIORITY_A_OFF(1);
+	u32 d2mode_priority_a_cnt = S_006548_D1MODE_PRIORITY_A_OFF(1);
 	fixed20_12 priority_mark02, priority_mark12, fill_rate;
 	fixed20_12 a, b;
 
@@ -497,10 +499,6 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
 			d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1);
 			d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1);
 		}
-		WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
-		WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
-		WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
-		WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
 	} else if (mode0) {
 		if (rfixed_trunc(wm0.dbpp) > 64)
 			a.full = rfixed_mul(wm0.dbpp, wm0.num_line_pair);
@@ -530,13 +528,7 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
 		d1mode_priority_a_cnt = rfixed_trunc(priority_mark02);
 		if (rdev->disp_priority == 2)
 			d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1);
-		WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
-		WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
-		WREG32(R_006D48_D2MODE_PRIORITY_A_CNT,
-			S_006D48_D2MODE_PRIORITY_A_OFF(1));
-		WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT,
-			S_006D4C_D2MODE_PRIORITY_B_OFF(1));
-	} else {
+	} else if (mode1) {
 		if (rfixed_trunc(wm1.dbpp) > 64)
 			a.full = rfixed_mul(wm1.dbpp, wm1.num_line_pair);
 		else
@@ -565,13 +557,12 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
 		d2mode_priority_a_cnt = rfixed_trunc(priority_mark12);
 		if (rdev->disp_priority == 2)
 			d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1);
-		WREG32(R_006548_D1MODE_PRIORITY_A_CNT,
-			S_006548_D1MODE_PRIORITY_A_OFF(1));
-		WREG32(R_00654C_D1MODE_PRIORITY_B_CNT,
-			S_00654C_D1MODE_PRIORITY_B_OFF(1));
-		WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
-		WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
 	}
+
+	WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
+	WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
+	WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
+	WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
 }
 
 uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg)
drivers/gpu/drm/radeon/rv515.c +9 -14
index 9035121..cf8f27f 100644
@@ -1017,7 +1017,9 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev)
 	struct drm_display_mode *mode1 = NULL;
 	struct rv515_watermark wm0;
 	struct rv515_watermark wm1;
-	u32 tmp, d1mode_priority_a_cnt, d2mode_priority_a_cnt;
+	u32 tmp;
+	u32 d1mode_priority_a_cnt = MODE_PRIORITY_OFF;
+	u32 d2mode_priority_a_cnt = MODE_PRIORITY_OFF;
 	fixed20_12 priority_mark02, priority_mark12, fill_rate;
 	fixed20_12 a, b;
 
@@ -1091,10 +1093,6 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev)
 			d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
 			d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
 		}
-		WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
-		WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
-		WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
-		WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
 	} else if (mode0) {
 		if (rfixed_trunc(wm0.dbpp) > 64)
 			a.full = rfixed_div(wm0.dbpp, wm0.num_line_pair);
@@ -1124,11 +1122,7 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev)
 		d1mode_priority_a_cnt = rfixed_trunc(priority_mark02);
 		if (rdev->disp_priority == 2)
 			d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
-		WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
-		WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
-		WREG32(D2MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF);
-		WREG32(D2MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF);
-	} else {
+	} else if (mode1) {
 		if (rfixed_trunc(wm1.dbpp) > 64)
 			a.full = rfixed_div(wm1.dbpp, wm1.num_line_pair);
 		else
@@ -1157,11 +1151,12 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev)
 		d2mode_priority_a_cnt = rfixed_trunc(priority_mark12);
 		if (rdev->disp_priority == 2)
 			d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
-		WREG32(D1MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF);
-		WREG32(D1MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF);
-		WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
-		WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
 	}
+
+	WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
+	WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
+	WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
+	WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
 }
 
 void rv515_bandwidth_update(struct radeon_device *rdev)
Signature · 1 line
1.7.4.4
#6 lore raw

PATCH 6/209 drm/i915: Unset cursor if out-of-bounds upon mode change (v4)

In reply to Paul Gortmaker

From: Chris Wilson <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit cda4b7d3a5b1dcbc0d8e7bad52134347798e9047 upstream.

The docs warn that to position the cursor such that no part of it is visible on the pipe is an undefined operation. Avoid such circumstances upon changing the mode, or at any other time, by unsetting the cursor if it moves out of bounds.

"For normal high resolution display modes, the cursor must have at least a single pixel positioned over the active screen.” (p143, p148 of the hardware registers docs).

Fixes:

Bug 24748 - [965G] Graphics crashes when resolution is changed with KMS
enabled
https://bugs.freedesktop.org/show_bug.cgi?id=24748

v2: Only update the cursor registers if they change.
v3: Fix the unsigned comparision of x,y against width,height.
v4: Always set CUR.BASE or else the cursor may become corrupt.

---
 drivers/gpu/drm/i915/intel_display.c |  144 ++++++++++++++++++++++------------
 drivers/gpu/drm/i915/intel_drv.h     |    8 ++-
 2 files changed, 99 insertions(+), 53 deletions(-)
drivers/gpu/drm/i915/intel_display.c +93 -51
index 28eebc5..614bda1 100644
@@ -42,6 +42,7 @@
 bool intel_pipe_has_type (struct drm_crtc *crtc, int type);
 static void intel_update_watermarks(struct drm_device *dev);
 static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule);
+static void intel_crtc_update_cursor(struct drm_crtc *crtc);
 
 typedef struct {
     /* given values */
@@ -3010,6 +3011,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
 		return -EINVAL;
 	}
 
+	/* Ensure that the cursor is valid for the new mode before changing... */
+	intel_crtc_update_cursor(crtc);
+
 	if (is_lvds && dev_priv->lvds_downclock_avail) {
 		has_reduced_clock = limit->find_pll(limit, crtc,
 							    dev_priv->lvds_downclock,
@@ -3473,6 +3477,85 @@ void intel_crtc_load_lut(struct drm_crtc *crtc)
 	}
 }
 
+/* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */
+static void intel_crtc_update_cursor(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int pipe = intel_crtc->pipe;
+	int x = intel_crtc->cursor_x;
+	int y = intel_crtc->cursor_y;
+	uint32_t base, pos;
+	bool visible;
+
+	pos = 0;
+
+	if (crtc->fb) {
+		base = intel_crtc->cursor_addr;
+		if (x > (int) crtc->fb->width)
+			base = 0;
+
+		if (y > (int) crtc->fb->height)
+			base = 0;
+	} else
+		base = 0;
+
+	if (x < 0) {
+		if (x + intel_crtc->cursor_width < 0)
+			base = 0;
+
+		pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
+		x = -x;
+	}
+	pos |= x << CURSOR_X_SHIFT;
+
+	if (y < 0) {
+		if (y + intel_crtc->cursor_height < 0)
+			base = 0;
+
+		pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT;
+		y = -y;
+	}
+	pos |= y << CURSOR_Y_SHIFT;
+
+	visible = base != 0;
+	if (!visible && !intel_crtc->cursor_visble)
+		return;
+
+	I915_WRITE(pipe == 0 ? CURAPOS : CURBPOS, pos);
+	if (intel_crtc->cursor_visble != visible) {
+		uint32_t cntl = I915_READ(pipe == 0 ? CURACNTR : CURBCNTR);
+		if (base) {
+			/* Hooray for CUR*CNTR differences */
+			if (IS_MOBILE(dev) || IS_I9XX(dev)) {
+				cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
+				cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
+				cntl |= pipe << 28; /* Connect to correct pipe */
+			} else {
+				cntl &= ~(CURSOR_FORMAT_MASK);
+				cntl |= CURSOR_ENABLE;
+				cntl |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE;
+			}
+		} else {
+			if (IS_MOBILE(dev) || IS_I9XX(dev)) {
+				cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE);
+				cntl |= CURSOR_MODE_DISABLE;
+			} else {
+				cntl &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE);
+			}
+		}
+		I915_WRITE(pipe == 0 ? CURACNTR : CURBCNTR, cntl);
+
+		intel_crtc->cursor_visble = visible;
+	}
+	/* and commit changes on next vblank */
+	I915_WRITE(pipe == 0 ? CURABASE : CURBBASE, base);
+
+	if (visible)
+		intel_mark_busy(dev, to_intel_framebuffer(crtc->fb)->obj);
+}
+
 static int intel_crtc_cursor_set(struct drm_crtc *crtc,
 				 struct drm_file *file_priv,
 				 uint32_t handle,
@@ -3483,11 +3566,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct drm_gem_object *bo;
 	struct drm_i915_gem_object *obj_priv;
-	int pipe = intel_crtc->pipe;
-	uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR;
-	uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
-	uint32_t temp = I915_READ(control);
-	size_t addr;
+	uint32_t addr;
 	int ret;
 
 	DRM_DEBUG_KMS("\n");
@@ -3495,12 +3574,6 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
 	/* if we want to turn off the cursor ignore width and height */
 	if (!handle) {
 		DRM_DEBUG_KMS("cursor off\n");
-		if (IS_MOBILE(dev) || IS_I9XX(dev)) {
-			temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE);
-			temp |= CURSOR_MODE_DISABLE;
-		} else {
-			temp &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE);
-		}
 		addr = 0;
 		bo = NULL;
 		mutex_lock(&dev->struct_mutex);
@@ -3535,7 +3608,8 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
 		}
 		addr = obj_priv->gtt_offset;
 	} else {
-		ret = i915_gem_attach_phys_object(dev, bo, (pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1);
+		ret = i915_gem_attach_phys_object(dev, bo,
+						  (intel_crtc->pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1);
 		if (ret) {
 			DRM_ERROR("failed to attach phys object\n");
 			goto fail_locked;
@@ -3546,21 +3620,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
 	if (!IS_I9XX(dev))
 		I915_WRITE(CURSIZE, (height << 12) | width);
 
-	/* Hooray for CUR*CNTR differences */
-	if (IS_MOBILE(dev) || IS_I9XX(dev)) {
-		temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
-		temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
-		temp |= (pipe << 28); /* Connect to correct pipe */
-	} else {
-		temp &= ~(CURSOR_FORMAT_MASK);
-		temp |= CURSOR_ENABLE;
-		temp |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE;
-	}
-
  finish:
-	I915_WRITE(control, temp);
-	I915_WRITE(base, addr);
-
 	if (intel_crtc->cursor_bo) {
 		if (dev_priv->info->cursor_needs_physical) {
 			if (intel_crtc->cursor_bo != bo)
@@ -3574,6 +3634,10 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
 
 	intel_crtc->cursor_addr = addr;
 	intel_crtc->cursor_bo = bo;
+	intel_crtc->cursor_width = width;
+	intel_crtc->cursor_height = height;
+
+	intel_crtc_update_cursor(crtc);
 
 	return 0;
 fail_locked:
@@ -3585,34 +3649,12 @@ fail:
 
 static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
 {
-	struct drm_device *dev = crtc->dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	struct intel_framebuffer *intel_fb;
-	int pipe = intel_crtc->pipe;
-	uint32_t temp = 0;
-	uint32_t adder;
-
-	if (crtc->fb) {
-		intel_fb = to_intel_framebuffer(crtc->fb);
-		intel_mark_busy(dev, intel_fb->obj);
-	}
-
-	if (x < 0) {
-		temp |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
-		x = -x;
-	}
-	if (y < 0) {
-		temp |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT;
-		y = -y;
-	}
 
-	temp |= x << CURSOR_X_SHIFT;
-	temp |= y << CURSOR_Y_SHIFT;
+	intel_crtc->cursor_x = x;
+	intel_crtc->cursor_y = y;
 
-	adder = intel_crtc->cursor_addr;
-	I915_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp);
-	I915_WRITE((pipe == 0) ? CURABASE : CURBBASE, adder);
+	intel_crtc_update_cursor(crtc);
 
 	return 0;
 }
drivers/gpu/drm/i915/intel_drv.h +6 -2
index 7a1ad65..4e9f24a 100644
@@ -140,8 +140,6 @@ struct intel_crtc {
 	struct drm_crtc base;
 	enum pipe pipe;
 	enum plane plane;
-	struct drm_gem_object *cursor_bo;
-	uint32_t cursor_addr;
 	u8 lut_r[256], lut_g[256], lut_b[256];
 	int dpms_mode;
 	bool busy; /* is scanout buffer being updated frequently? */
@@ -149,6 +147,12 @@ struct intel_crtc {
 	bool lowfreq_avail;
 	struct intel_overlay *overlay;
 	struct intel_unpin_work *unpin_work;
+
+	struct drm_gem_object *cursor_bo;
+	uint32_t cursor_addr;
+	int16_t cursor_x, cursor_y;
+	int16_t cursor_width, cursor_height;
+	bool cursor_visble;
 };
 
 #define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
Signature · 1 line
1.7.4.4
#7 lore raw

PATCH 7/209 serial: add support for OX16PCI958 card

In reply to Paul Gortmaker

From: Lytochkin Boris <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit e847003f00d5eca3e3b3a6a1199f82b51293faf6 upstream.

---
 drivers/serial/8250_pci.c |   13 +++++++++++++
 1 files changed, 13 insertions(+), 0 deletions(-)
drivers/serial/8250_pci.c +13 -0
index 01c012d..c0a4860 100644
@@ -982,6 +982,7 @@ static int skip_tx_en_setup(struct serial_private *priv,
 #define PCI_SUBDEVICE_ID_POCTAL422	0x0408
 #define PCI_VENDOR_ID_ADVANTECH		0x13fe
 #define PCI_DEVICE_ID_ADVANTECH_PCI3620	0x3620
+#define PCI_DEVICE_ID_OXSEMI_16PCI958	0x9538
 
 /* Unknown vendors/cards - this should not be in linux/pci_ids.h */
 #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584	0x1584
@@ -1530,6 +1531,8 @@ enum pci_board_num_t {
 	pbn_b2_4_921600,
 	pbn_b2_8_921600,
 
+	pbn_b2_8_1152000,
+
 	pbn_b2_bt_1_115200,
 	pbn_b2_bt_2_115200,
 	pbn_b2_bt_4_115200,
@@ -1944,6 +1947,13 @@ static struct pciserial_board pci_boards[] __devinitdata = {
 		.uart_offset	= 8,
 	},
 
+	[pbn_b2_8_1152000] = {
+		.flags		= FL_BASE2,
+		.num_ports	= 8,
+		.base_baud	= 1152000,
+		.uart_offset	= 8,
+	},
+
 	[pbn_b2_bt_1_115200] = {
 		.flags		= FL_BASE2|FL_BASE_BARS,
 		.num_ports	= 1,
@@ -2840,6 +2850,9 @@ static struct pci_device_id serial_pci_tbl[] = {
 	{	PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI952,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_b0_bt_2_921600 },
+	{	PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI958,
+		PCI_ANY_ID , PCI_ANY_ID, 0, 0,
+		pbn_b2_8_1152000 },
 
 	/*
 	 * Oxford Semiconductor Inc. Tornado PCI express device range.
Signature · 1 line
1.7.4.4
#8 lore raw

PATCH 8/209 md: fix another deadlock with removing sysfs attributes.

In reply to Paul Gortmaker

From: NeilBrown <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit bb4f1e9d0e2ef93de8e36ca0f5f26625fcd70b7d upstream.

Move the deletion of sysfs attributes from reconfig_mutex to open_mutex didn't really help as a process can try to take open_mutex while holding reconfig_mutex, so the same deadlock can happen, just requiring one more process to be involved in the chain.

I looks like I cannot easily use locking to wait for the sysfs deletion to complete, so don't.

The only things that we cannot do while the deletions are still pending is other things which can change the sysfs namespace: run, takeover, stop. Each of these can fail with -EBUSY.
So set a flag while doing a sysfs deletion, and fail run, takeover, stop if that flag is set.

This is suitable for 2.6.35.x

---
 drivers/md/md.c |   31 +++++++++++++++++--------------
 drivers/md/md.h |    4 ++++
 2 files changed, 21 insertions(+), 14 deletions(-)
drivers/md/md.c +17 -14
index 336792e..81c0282 100644
@@ -517,13 +517,17 @@ static void mddev_unlock(mddev_t * mddev)
 		 * an access to the files will try to take reconfig_mutex
 		 * while holding the file unremovable, which leads to
 		 * a deadlock.
-		 * So hold open_mutex instead - we are allowed to take
-		 * it while holding reconfig_mutex, and md_run can
-		 * use it to wait for the remove to complete.
+		 * So hold set sysfs_active while the remove in happeing,
+		 * and anything else which might set ->to_remove or my
+		 * otherwise change the sysfs namespace will fail with
+		 * -EBUSY if sysfs_active is still set.
+		 * We set sysfs_active under reconfig_mutex and elsewhere
+		 * test it under the same mutex to ensure its correct value
+		 * is seen.
 		 */
 		struct attribute_group *to_remove = mddev->to_remove;
 		mddev->to_remove = NULL;
-		mutex_lock(&mddev->open_mutex);
+		mddev->sysfs_active = 1;
 		mutex_unlock(&mddev->reconfig_mutex);
 
 		if (to_remove != &md_redundancy_group)
@@ -535,7 +539,7 @@ static void mddev_unlock(mddev_t * mddev)
 				sysfs_put(mddev->sysfs_action);
 			mddev->sysfs_action = NULL;
 		}
-		mutex_unlock(&mddev->open_mutex);
+		mddev->sysfs_active = 0;
 	} else
 		mutex_unlock(&mddev->reconfig_mutex);
 
@@ -2949,7 +2953,9 @@ level_store(mddev_t *mddev, const char *buf, size_t len)
 	 *  - new personality will access other array.
 	 */
 
-	if (mddev->sync_thread || mddev->reshape_position != MaxSector)
+	if (mddev->sync_thread ||
+	    mddev->reshape_position != MaxSector ||
+	    mddev->sysfs_active)
 		return -EBUSY;
 
 	if (!mddev->pers->quiesce) {
@@ -4282,13 +4288,9 @@ static int do_md_run(mddev_t * mddev)
 
 	if (mddev->pers)
 		return -EBUSY;
-
-	/* These two calls synchronise us with the
-	 * sysfs_remove_group calls in mddev_unlock,
-	 * so they must have completed.
-	 */
-	mutex_lock(&mddev->open_mutex);
-	mutex_unlock(&mddev->open_mutex);
+	/* Cannot run until previous stop completes properly */
+	if (mddev->sysfs_active)
+		return -EBUSY;
 
 	/*
 	 * Analyze all RAID superblock(s)
@@ -4545,7 +4547,8 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
 	mdk_rdev_t *rdev;
 
 	mutex_lock(&mddev->open_mutex);
-	if (atomic_read(&mddev->openers) > is_open) {
+	if (atomic_read(&mddev->openers) > is_open ||
+	    mddev->sysfs_active) {
 		printk("md: %s still in use.\n",mdname(mddev));
 		err = -EBUSY;
 	} else if (mddev->pers) {
drivers/md/md.h +4 -0
index 722f5df..1d49c4e 100644
@@ -125,6 +125,10 @@ struct mddev_s
 	int				suspended;
 	atomic_t			active_io;
 	int				ro;
+	int				sysfs_active; /* set when sysfs deletes
+						       * are happening, so run/
+						       * takeover/stop are not safe
+						       */
 
 	struct gendisk			*gendisk;
 
Signature · 1 line
1.7.4.4
#9 lore raw

PATCH 9/209 e100/e1000*/igb*/ixgb*: Add missing read memory barrier

In reply to Paul Gortmaker

From: Jeff Kirsher <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 2d0bb1c1f4524befe9f0fcf0d0cd3081a451223f upstream.

Based on patches from Sonny Rao and Milton Miller...

Combined the patches to fix up clean_tx_irq and clean_rx_irq.

The PowerPC architecture does not require loads to independent bytes to be ordered without adding an explicit barrier.

In ixgbe_clean_rx_irq we load the status bit then load the packet data. With packet split disabled if these loads go out of order we get a stale packet, but we will notice the bad sequence numbers and drop it.

The problem occurs with packet split enabled where the TCP/IP header and data are in different descriptors. If the reads go out of order we may have data that doesn't match the TCP/IP header. Since we use hardware checksumming this bad data is never verified and it makes it all the way to the application.

This bug was found during stress testing and adding this barrier has been shown to fix it. The bug can manifest as a data integrity issue (bad payload data) or as a BUG in skb_pull().

This was a nasty bug to hunt down, if people agree with the fix I think it's a candidate for stable.

Previously Submitted to e1000-devel only for ixgbe

http://marc.info/?l=e1000-devel&m=126593062701537&w=3

We've now seen this problem hit with other device drivers (e1000e mostly) So I'm resubmitting with fixes for other Intel Device Drivers with similar issues.

---
 drivers/net/e100.c                 |    2 ++
 drivers/net/e1000/e1000_main.c     |    3 +++
 drivers/net/e1000e/netdev.c        |    4 ++++
 drivers/net/igb/igb_main.c         |    2 ++
 drivers/net/igbvf/netdev.c         |    2 ++
 drivers/net/ixgb/ixgb_main.c       |    2 ++
 drivers/net/ixgbe/ixgbe_main.c     |    1 +
 drivers/net/ixgbevf/ixgbevf_main.c |    2 ++
 8 files changed, 18 insertions(+), 0 deletions(-)
drivers/net/e100.c +2 -0
index 7910803..f6bb11e 100644
@@ -1768,6 +1768,7 @@ static int e100_tx_clean(struct nic *nic)
 	for (cb = nic->cb_to_clean;
 	    cb->status & cpu_to_le16(cb_complete);
 	    cb = nic->cb_to_clean = cb->next) {
+		rmb(); /* read skb after status */
 		DPRINTK(TX_DONE, DEBUG, "cb[%d]->status = 0x%04X\n",
 		        (int)(((void*)cb - (void*)nic->cbs)/sizeof(struct cb)),
 		        cb->status);
@@ -1914,6 +1915,7 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx,
 	rfd_status = le16_to_cpu(rfd->status);
 
 	DPRINTK(RX_STATUS, DEBUG, "status=0x%04X\n", rfd_status);
+	rmb(); /* read size after status bit */
 
 	/* If data isn't ready, nothing to indicate */
 	if (unlikely(!(rfd_status & cb_complete))) {
drivers/net/e1000/e1000_main.c +3 -0
index b15ece2..13e34d2 100644
@@ -3433,6 +3433,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
 	while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
 	       (count < tx_ring->count)) {
 		bool cleaned = false;
+		rmb();	/* read buffer_info after eop_desc */
 		for ( ; !cleaned; count++) {
 			tx_desc = E1000_TX_DESC(*tx_ring, i);
 			buffer_info = &tx_ring->buffer_info[i];
@@ -3622,6 +3623,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
 		if (*work_done >= work_to_do)
 			break;
 		(*work_done)++;
+		rmb(); /* read descriptor and rx_buffer_info after status DD */
 
 		status = rx_desc->status;
 		skb = buffer_info->skb;
@@ -3803,6 +3805,7 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
 		if (*work_done >= work_to_do)
 			break;
 		(*work_done)++;
+		rmb(); /* read descriptor and rx_buffer_info after status DD */
 
 		status = rx_desc->status;
 		skb = buffer_info->skb;
drivers/net/e1000e/netdev.c +4 -0
index 64a06ed..56c9e69 100644
@@ -637,6 +637,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
 	while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
 	       (count < tx_ring->count)) {
 		bool cleaned = false;
+		rmb(); /* read buffer_info after eop_desc */
 		for (; !cleaned; count++) {
 			tx_desc = E1000_TX_DESC(*tx_ring, i);
 			buffer_info = &tx_ring->buffer_info[i];
@@ -739,6 +740,7 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
 			break;
 		(*work_done)++;
 		skb = buffer_info->skb;
+		rmb();	/* read descriptor and rx_buffer_info after status DD */
 
 		/* in the packet split case this is header only */
 		prefetch(skb->data - NET_IP_ALIGN);
@@ -938,6 +940,8 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
 		if (*work_done >= work_to_do)
 			break;
 		(*work_done)++;
+		rmb();	/* read descriptor and rx_buffer_info after status DD */
+		rmb();	/* read descriptor and rx_buffer_info after status DD */
 
 		status = rx_desc->status;
 		skb = buffer_info->skb;
drivers/net/igb/igb_main.c +2 -0
index c5edd41..acc618a 100644
@@ -5005,6 +5005,7 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector)
 
 	while ((eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD)) &&
 	       (count < tx_ring->count)) {
+		rmb();	/* read buffer_info after eop_desc status */
 		for (cleaned = false; !cleaned; count++) {
 			tx_desc = E1000_TX_DESC_ADV(*tx_ring, i);
 			buffer_info = &tx_ring->buffer_info[i];
@@ -5212,6 +5213,7 @@ static bool igb_clean_rx_irq_adv(struct igb_q_vector *q_vector,
 		if (*work_done >= budget)
 			break;
 		(*work_done)++;
+		rmb(); /* read descriptor and rx_buffer_info after status DD */
 
 		skb = buffer_info->skb;
 		prefetch(skb->data - NET_IP_ALIGN);
drivers/net/igbvf/netdev.c +2 -0
index 1b1edad..709e83d 100644
@@ -247,6 +247,7 @@ static bool igbvf_clean_rx_irq(struct igbvf_adapter *adapter,
 		if (*work_done >= work_to_do)
 			break;
 		(*work_done)++;
+		rmb(); /* read descriptor and rx_buffer_info after status DD */
 
 		buffer_info = &rx_ring->buffer_info[i];
 
@@ -777,6 +778,7 @@ static bool igbvf_clean_tx_irq(struct igbvf_ring *tx_ring)
 
 	while ((eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD)) &&
 	       (count < tx_ring->count)) {
+		rmb();	/* read buffer_info after eop_desc status */
 		for (cleaned = false; !cleaned; count++) {
 			tx_desc = IGBVF_TX_DESC_ADV(*tx_ring, i);
 			buffer_info = &tx_ring->buffer_info[i];
drivers/net/ixgb/ixgb_main.c +2 -0
index c9fef65..be88a1d 100644
@@ -1811,6 +1811,7 @@ ixgb_clean_tx_irq(struct ixgb_adapter *adapter)
 
 	while (eop_desc->status & IXGB_TX_DESC_STATUS_DD) {
 
+		rmb(); /* read buffer_info after eop_desc */
 		for (cleaned = false; !cleaned; ) {
 			tx_desc = IXGB_TX_DESC(*tx_ring, i);
 			buffer_info = &tx_ring->buffer_info[i];
@@ -1946,6 +1947,7 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter, int *work_done, int work_to_do)
 			break;
 
 		(*work_done)++;
+		rmb();	/* read descriptor and rx_buffer_info after status DD */
 		status = rx_desc->status;
 		skb = buffer_info->skb;
 		buffer_info->skb = NULL;
drivers/net/ixgbe/ixgbe_main.c +1 -0
index 6c00ee4..156dfcb 100644
@@ -407,6 +407,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
 	while ((eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)) &&
 	       (count < tx_ring->work_limit)) {
 		bool cleaned = false;
+		rmb(); /* read buffer_info after eop_desc */
 		for ( ; !cleaned; count++) {
 			struct sk_buff *skb;
 			tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
drivers/net/ixgbevf/ixgbevf_main.c +2 -0
index 0cd6202..75be3c9 100644
@@ -231,6 +231,7 @@ static bool ixgbevf_clean_tx_irq(struct ixgbevf_adapter *adapter,
 	while ((eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)) &&
 	       (count < tx_ring->work_limit)) {
 		bool cleaned = false;
+		rmb(); /* read buffer_info after eop_desc */
 		for ( ; !cleaned; count++) {
 			struct sk_buff *skb;
 			tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
@@ -518,6 +519,7 @@ static bool ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,
 			break;
 		(*work_done)++;
 
+		rmb(); /* read descriptor and rx_buffer_info after status DD */
 		if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
 			hdr_info = le16_to_cpu(ixgbevf_get_hdr_info(rx_desc));
 			len = (hdr_info & IXGBE_RXDADV_HDRBUFLEN_MASK) >>
Signature · 1 line
1.7.4.4
#10 lore raw

PATCH 10/209 ioat2: catch and recover from broken vtd configurations v6

In reply to Paul Gortmaker

From: Dan Williams <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 556ab45f9a775bfa4762bacc0a4afb5b44b067bc upstream.

On some platforms (MacPro3,1) the BIOS assigns the ioatdma device to the incorrect iommu causing faults when the driver initializes. Add a quirk to catch this misconfiguration and try falling back to untranslated operation (which works in the MacPro3,1 case).

Assuming there are other platforms with misconfigured iommus teach the ioatdma driver to treat initialization failures as non-fatal (just fail the driver load and emit a warning instead of triggering a BUG_ON).

This can be classified as a boot regression since 2.6.32 on affected platforms since the ioatdma module did not autoload prior to that kernel.

[PG: 34 has no WARN_TAINT_ONCE, use WARN_ONCE instead]

---
 drivers/dma/ioat/dma.h    |    1 +
 drivers/dma/ioat/dma_v2.c |   24 ++++++++++++++++++++++--
 drivers/dma/ioat/dma_v3.c |    5 ++++-
 drivers/pci/intel-iommu.c |   27 +++++++++++++++++++++++++++
 4 files changed, 54 insertions(+), 3 deletions(-)
drivers/dma/ioat/dma.h +1 -0
index 86b97ac..4eda2e5 100644
@@ -96,6 +96,7 @@ struct ioat_chan_common {
 	#define IOAT_COMPLETION_ACK 1
 	#define IOAT_RESET_PENDING 2
 	#define IOAT_KOBJ_INIT_FAIL 3
+	#define IOAT_RUN 5
 	struct timer_list timer;
 	#define COMPLETION_TIMEOUT msecs_to_jiffies(100)
 	#define IDLE_TIMEOUT msecs_to_jiffies(2000)
drivers/dma/ioat/dma_v2.c +22 -2
index b5ae56c..63e6929 100644
@@ -304,7 +304,10 @@ void ioat2_timer_event(unsigned long data)
 			chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET);
 			dev_err(to_dev(chan), "%s: Channel halted (%x)\n",
 				__func__, chanerr);
-			BUG_ON(is_ioat_bug(chanerr));
+			if (test_bit(IOAT_RUN, &chan->state))
+				BUG_ON(is_ioat_bug(chanerr));
+			else /* we never got off the ground */
+				return;
 		}
 
 		/* if we haven't made progress and we have already
@@ -496,6 +499,8 @@ static struct ioat_ring_ent **ioat2_alloc_ring(struct dma_chan *c, int order, gf
 	return ring;
 }
 
+void ioat2_free_chan_resources(struct dma_chan *c);
+
 /* ioat2_alloc_chan_resources - allocate/initialize ioat2 descriptor ring
  * @chan: channel to be initialized
  */
@@ -504,6 +509,7 @@ int ioat2_alloc_chan_resources(struct dma_chan *c)
 	struct ioat2_dma_chan *ioat = to_ioat2_chan(c);
 	struct ioat_chan_common *chan = &ioat->base;
 	struct ioat_ring_ent **ring;
+	u64 status;
 	int order;
 
 	/* have we already been set up? */
@@ -542,7 +548,20 @@ int ioat2_alloc_chan_resources(struct dma_chan *c)
 	tasklet_enable(&chan->cleanup_task);
 	ioat2_start_null_desc(ioat);
 
-	return 1 << ioat->alloc_order;
+	/* check that we got off the ground */
+	udelay(5);
+	status = ioat_chansts(chan);
+	if (is_ioat_active(status) || is_ioat_idle(status)) {
+		set_bit(IOAT_RUN, &chan->state);
+		return 1 << ioat->alloc_order;
+	} else {
+		u32 chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET);
+
+		dev_WARN(to_dev(chan),
+			"failed to start channel chanerr: %#x\n", chanerr);
+		ioat2_free_chan_resources(c);
+		return -EFAULT;
+	}
 }
 
 bool reshape_ring(struct ioat2_dma_chan *ioat, int order)
@@ -776,6 +795,7 @@ void ioat2_free_chan_resources(struct dma_chan *c)
 	del_timer_sync(&chan->timer);
 	device->cleanup_fn((unsigned long) c);
 	device->reset_hw(chan);
+	clear_bit(IOAT_RUN, &chan->state);
 
 	spin_lock_bh(&ioat->ring_lock);
 	descs = ioat2_ring_space(ioat);
drivers/dma/ioat/dma_v3.c +4 -1
index 6740e31..52b1e3d 100644
@@ -401,7 +401,10 @@ static void ioat3_timer_event(unsigned long data)
 			chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET);
 			dev_err(to_dev(chan), "%s: Channel halted (%x)\n",
 				__func__, chanerr);
-			BUG_ON(is_ioat_bug(chanerr));
+			if (test_bit(IOAT_RUN, &chan->state))
+				BUG_ON(is_ioat_bug(chanerr));
+			else /* we never got off the ground */
+				return;
 		}
 
 		/* if we haven't made progress and we have already
drivers/pci/intel-iommu.c +27 -0
index fff8832..3507692 100644
@@ -3028,6 +3028,33 @@ static void __init iommu_exit_mempool(void)
 
 }
 
+static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev)
+{
+	struct dmar_drhd_unit *drhd;
+	u32 vtbar;
+	int rc;
+
+	/* We know that this device on this chipset has its own IOMMU.
+	 * If we find it under a different IOMMU, then the BIOS is lying
+	 * to us. Hope that the IOMMU for this device is actually
+	 * disabled, and it needs no translation...
+	 */
+	rc = pci_bus_read_config_dword(pdev->bus, PCI_DEVFN(0, 0), 0xb0, &vtbar);
+	if (rc) {
+		/* "can't" happen */
+		dev_info(&pdev->dev, "failed to run vt-d quirk\n");
+		return;
+	}
+	vtbar &= 0xffff0000;
+
+	/* we know that the this iommu should be at offset 0xa000 from vtbar */
+	drhd = dmar_find_matched_drhd_unit(pdev);
+	if (WARN_ONCE(!drhd || drhd->reg_base_addr - vtbar != 0xa000,
+			    "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n"))
+		pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
+}
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu);
+
 static void __init init_no_remapping_devices(void)
 {
 	struct dmar_drhd_unit *drhd;
Signature · 1 line
1.7.4.4
#11 lore raw

PATCH 11/209 Fix sget() race with failing mount

In reply to Paul Gortmaker

From: Al Viro <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 7a4dec53897ecd3367efb1e12fe8a4edc47dc0e9 upstream.

If sget() finds a matching superblock being set up, it'll grab an active reference to it and grab s_umount. That's fine - we'll wait for completion of foofs_get_sb() that way. However, if said foofs_get_sb() fails we'll end up holding the halfway-created superblock. deactivate_locked_super() called by foofs_get_sb() will just unlock the sucker since we are holding another active reference to it.

What we need is a way to tell if superblock has been successfully set up. Unfortunately, neither ->s_root nor the check for MS_ACTIVE quite fit. Cheap and easy way, suitable for backport:
new flag set by the (only) caller of ->get_sb(). If that flag isn't present by the time sget() grabbed s_umount on preexisting superblock it has found, it's seeing a stillborn and should just bury it with deactivate_locked_super() (and repeat the search).

Longer term we want to set that flag in ->get_sb() instances (and check for it to distinguish between "sget() found us a live sb" and "sget() has allocated an sb, we need to set it up" in there, instead of checking ->s_root as we do now).

---
 fs/namespace.c     |    2 +-
 fs/super.c         |    6 ++++++
 include/linux/fs.h |    1 +
 3 files changed, 8 insertions(+), 1 deletions(-)
fs/namespace.c +1 -1
index f20cb57..bfe3f3e 100644
@@ -1996,7 +1996,7 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
 	if (flags & MS_RDONLY)
 		mnt_flags |= MNT_READONLY;
 
-	flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE |
+	flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | MS_BORN |
 		   MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT |
 		   MS_STRICTATIME);
 
fs/super.c +6 -0
index 1527e6a..53040a6 100644
@@ -356,6 +356,11 @@ retry:
 			if (s) {
 				up_write(&s->s_umount);
 				destroy_super(s);
+				s = NULL;
+			}
+			if (unlikely(!(old->s_flags & MS_BORN))) {
+				deactivate_locked_super(old);
+				goto retry;
 			}
 			return old;
 		}
@@ -957,6 +962,7 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
 		goto out_free_secdata;
 	BUG_ON(!mnt->mnt_sb);
 	WARN_ON(!mnt->mnt_sb->s_bdi);
+	mnt->mnt_sb->s_flags |= MS_BORN;
 
 	error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata);
 	if (error)
include/linux/fs.h +1 -0
index e93529d..8aa6bd9 100644
@@ -209,6 +209,7 @@ struct inodes_stat_t {
 #define MS_KERNMOUNT	(1<<22) /* this is a kern_mount call */
 #define MS_I_VERSION	(1<<23) /* Update inode I_version field */
 #define MS_STRICTATIME	(1<<24) /* Always perform atime updates */
+#define MS_BORN		(1<<29)
 #define MS_ACTIVE	(1<<30)
 #define MS_NOUSER	(1<<31)
 
Signature · 1 line
1.7.4.4
#12 lore raw

PATCH 12/209 drbd: Initialize all members of sync_conf to their defaults [Bugz 315]

In reply to Paul Gortmaker

From: Philipp Reisner <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 85f4cc17a62c3ac9edeaf120cdae7261df458053 upstream.

[PG: remove fields volume, interval, throttle, hold_off; not in 34]

---
 drivers/block/drbd/drbd_main.c |   17 ++++++++++++++---
 1 files changed, 14 insertions(+), 3 deletions(-)
drivers/block/drbd/drbd_main.c +14 -3
index 93d1f9b..6c79e02 100644
@@ -2567,9 +2567,20 @@ static void drbd_unplug_fn(struct request_queue *q)
 
 static void drbd_set_defaults(struct drbd_conf *mdev)
 {
-	mdev->sync_conf.after      = DRBD_AFTER_DEF;
-	mdev->sync_conf.rate       = DRBD_RATE_DEF;
-	mdev->sync_conf.al_extents = DRBD_AL_EXTENTS_DEF;
+	/* This way we get a compile error when sync_conf grows,
+	   and we forgot to initialize it here */
+	mdev->sync_conf = (struct syncer_conf) {
+		/* .rate = */		DRBD_RATE_DEF,
+		/* .after = */		DRBD_AFTER_DEF,
+		/* .al_extents = */	DRBD_AL_EXTENTS_DEF,
+		/* .verify_alg = */	{}, 0,
+		/* .cpu_mask = */	{}, 0,
+		/* .csums_alg = */	{}, 0,
+		/* .use_rle = */	0
+	};
+
+	/* Have to use that way, because the layout differs between
+	   big endian and little endian */
 	mdev->state = (union drbd_state) {
 		{ .role = R_SECONDARY,
 		  .peer = R_UNKNOWN,
Signature · 1 line
1.7.4.4
#13 lore raw

PATCH 13/209 crypto: testmgr - add an option to disable cryptoalgos' self-tests

In reply to Paul Gortmaker

From: Alexander Shishkin <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 0b767f96164b2b27488e3daa722ff16e89d49314 upstream.

By default, CONFIG_CRYPTO_MANAGER_TESTS will be enabled and thus self-tests will still run, but it is now possible to disable them to gain some time during bootup.

---
 crypto/Kconfig   |    8 ++++++++
 crypto/algboss.c |    4 ++++
 crypto/testmgr.c |   14 ++++++++++++++
 3 files changed, 26 insertions(+), 0 deletions(-)
crypto/Kconfig +8 -0
index 403857a..00f9341 100644
@@ -96,6 +96,14 @@ config CRYPTO_MANAGER2
 	select CRYPTO_BLKCIPHER2
 	select CRYPTO_PCOMP
 
+config CRYPTO_MANAGER_TESTS
+	bool "Run algolithms' self-tests"
+	default y
+	depends on CRYPTO_MANAGER2
+	help
+	  Run cryptomanager's tests for the new crypto algorithms being
+	  registered.
+
 config CRYPTO_GF128MUL
 	tristate "GF(2^128) multiplication functions (EXPERIMENTAL)"
 	depends on EXPERIMENTAL
crypto/algboss.c +4 -0
index c3c196b..40bd391 100644
@@ -206,6 +206,7 @@ err:
 	return NOTIFY_OK;
 }
 
+#ifdef CONFIG_CRYPTO_MANAGER_TESTS
 static int cryptomgr_test(void *data)
 {
 	struct crypto_test_param *param = data;
@@ -266,6 +267,7 @@ err_put_module:
 err:
 	return NOTIFY_OK;
 }
+#endif /* CONFIG_CRYPTO_MANAGER_TESTS */
 
 static int cryptomgr_notify(struct notifier_block *this, unsigned long msg,
 			    void *data)
@@ -273,8 +275,10 @@ static int cryptomgr_notify(struct notifier_block *this, unsigned long msg,
 	switch (msg) {
 	case CRYPTO_MSG_ALG_REQUEST:
 		return cryptomgr_schedule_probe(data);
+#ifdef CONFIG_CRYPTO_MANAGER_TESTS
 	case CRYPTO_MSG_ALG_REGISTER:
 		return cryptomgr_schedule_test(data);
+#endif
 	}
 
 	return NOTIFY_DONE;
crypto/testmgr.c +14 -0
index c494d76..73e8a46 100644
@@ -22,6 +22,17 @@
 #include <crypto/rng.h>
 
 #include "internal.h"
+
+#ifndef CONFIG_CRYPTO_MANAGER_TESTS
+
+/* a perfect nop */
+int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
+{
+	return 0;
+}
+
+#else
+
 #include "testmgr.h"
 
 /*
@@ -2500,4 +2511,7 @@ notest:
 non_fips_alg:
 	return -EINVAL;
 }
+
+#endif /* CONFIG_CRYPTO_MANAGER_TESTS */
+
 EXPORT_SYMBOL_GPL(alg_test);
Signature · 1 line
1.7.4.4
#14 lore raw

PATCH 14/209 udp: add rehash on connect()

In reply to Paul Gortmaker

From: Eric Dumazet <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 719f835853a92f6090258114a72ffe41f09155cd upstream

commit 30fff923 introduced in linux-2.6.33 (udp: bind() optimisation) added a secondary hash on UDP, hashed on (local addr, local port).

Problem is that following sequence :

fd = socket(...)
connect(fd, &remote, ...)

not only selects remote end point (address and port), but also sets local address, while UDP stack stored in secondary hash table the socket while its local address was INADDR_ANY (or ipv6 equivalent)

Sequence is :
- autobind() : choose a random local port, insert socket in hash tables [while local address is INADDR_ANY]
- connect() : set remote address and port, change local address to IP given by a route lookup.

When an incoming UDP frame comes, if more than 10 sockets are found in primary hash table, we switch to secondary table, and fail to find socket because its local address changed.

One solution to this problem is to rehash datagram socket if needed.

We add a new rehash(struct socket *) method in "struct proto", and implement this method for UDP v4 & v6, using a common helper.

This rehashing only takes care of secondary hash table, since primary hash (based on local port only) is not changed.

---
 include/net/sock.h  |    1 +
 include/net/udp.h   |    1 +
 net/ipv4/datagram.c |    5 ++++-
 net/ipv4/udp.c      |   44 ++++++++++++++++++++++++++++++++++++++++++++
 net/ipv6/datagram.c |    7 ++++++-
 net/ipv6/udp.c      |   10 ++++++++++
 6 files changed, 66 insertions(+), 2 deletions(-)
include/net/sock.h +1 -0
index d910528..efb5730 100644
@@ -697,6 +697,7 @@ struct proto {
 	/* Keeping track of sk's, looking them up, and port selection methods. */
 	void			(*hash)(struct sock *sk);
 	void			(*unhash)(struct sock *sk);
+	void			(*rehash)(struct sock *sk);
 	int			(*get_port)(struct sock *sk, unsigned short snum);
 
 	/* Keeping track of sockets in use */
include/net/udp.h +1 -0
index 5348d80..4201dc8 100644
@@ -151,6 +151,7 @@ static inline void udp_lib_hash(struct sock *sk)
 }
 
 extern void udp_lib_unhash(struct sock *sk);
+extern void udp_lib_rehash(struct sock *sk, u16 new_hash);
 
 static inline void udp_lib_close(struct sock *sk, long timeout)
 {
net/ipv4/datagram.c +4 -1
index fb24658..31cafd4 100644
@@ -62,8 +62,11 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 	}
 	if (!inet->inet_saddr)
 		inet->inet_saddr = rt->rt_src;	/* Update source address */
-	if (!inet->inet_rcv_saddr)
+	if (!inet->inet_rcv_saddr) {
 		inet->inet_rcv_saddr = rt->rt_src;
+		if (sk->sk_prot->rehash)
+			sk->sk_prot->rehash(sk);
+	}
 	inet->inet_daddr = rt->rt_dst;
 	inet->inet_dport = usin->sin_port;
 	sk->sk_state = TCP_ESTABLISHED;
net/ipv4/udp.c +44 -0

56 lines not on this page · raw message

net/ipv6/datagram.c +6 -1
index 6157388..fc9db30 100644
@@ -104,9 +104,12 @@ ipv4_connected:
 		if (ipv6_addr_any(&np->saddr))
 			ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr);
 
-		if (ipv6_addr_any(&np->rcv_saddr))
+		if (ipv6_addr_any(&np->rcv_saddr)) {
 			ipv6_addr_set_v4mapped(inet->inet_rcv_saddr,
 					       &np->rcv_saddr);
+			if (sk->sk_prot->rehash)
+				sk->sk_prot->rehash(sk);
+		}
 
 		goto out;
 	}
@@ -191,6 +194,8 @@ ipv4_connected:
 	if (ipv6_addr_any(&np->rcv_saddr)) {
 		ipv6_addr_copy(&np->rcv_saddr, &fl.fl6_src);
 		inet->inet_rcv_saddr = LOOPBACK4_IPV6;
+		if (sk->sk_prot->rehash)
+			sk->sk_prot->rehash(sk);
 	}
 
 	ip6_dst_store(sk, dst,
net/ipv6/udp.c +10 -0
index 9082485..be5e5a1 100644
@@ -111,6 +111,15 @@ int udp_v6_get_port(struct sock *sk, unsigned short snum)
 	return udp_lib_get_port(sk, snum, ipv6_rcv_saddr_equal, hash2_nulladdr);
 }
 
+static void udp_v6_rehash(struct sock *sk)
+{
+	u16 new_hash = udp6_portaddr_hash(sock_net(sk),
+					  &inet6_sk(sk)->rcv_saddr,
+					  inet_sk(sk)->inet_num);
+
+	udp_lib_rehash(sk, new_hash);
+}
+
 static inline int compute_score(struct sock *sk, struct net *net,
 				unsigned short hnum,
 				struct in6_addr *saddr, __be16 sport,
@@ -1430,6 +1439,7 @@ struct proto udpv6_prot = {
 	.backlog_rcv	   = udpv6_queue_rcv_skb,
 	.hash		   = udp_lib_hash,
 	.unhash		   = udp_lib_unhash,
+	.rehash		   = udp_v6_rehash,
 	.get_port	   = udp_v6_get_port,
 	.memory_allocated  = &udp_memory_allocated,
 	.sysctl_mem	   = sysctl_udp_mem,
Signature · 1 line
1.7.4.4
#15 lore raw

PATCH 15/209 block: Ensure physical block size is unsigned int

In reply to Paul Gortmaker

From: Martin K. Petersen <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 892b6f90db81cccb723d5d92f4fddc2d68b206e1 upstream.

Physical block size was declared unsigned int to accomodate the maximum size reported by READ CAPACITY(16). Make sure we use the right type in the related functions.

---
 block/blk-settings.c   |    2 +-
 include/linux/blkdev.h |    4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)
block/blk-settings.c +1 -1
index f5ed5a1..3430c1f 100644
@@ -326,7 +326,7 @@ EXPORT_SYMBOL(blk_queue_logical_block_size);
  *   hardware can operate on without reverting to read-modify-write
  *   operations.
  */
-void blk_queue_physical_block_size(struct request_queue *q, unsigned short size)
+void blk_queue_physical_block_size(struct request_queue *q, unsigned int size)
 {
 	q->limits.physical_block_size = size;
 
include/linux/blkdev.h +2 -2
index 6690e8b..68eef76 100644
@@ -927,7 +927,7 @@ extern void blk_queue_max_segment_size(struct request_queue *, unsigned int);
 extern void blk_queue_max_discard_sectors(struct request_queue *q,
 		unsigned int max_discard_sectors);
 extern void blk_queue_logical_block_size(struct request_queue *, unsigned short);
-extern void blk_queue_physical_block_size(struct request_queue *, unsigned short);
+extern void blk_queue_physical_block_size(struct request_queue *, unsigned int);
 extern void blk_queue_alignment_offset(struct request_queue *q,
 				       unsigned int alignment);
 extern void blk_limits_io_min(struct queue_limits *limits, unsigned int min);
@@ -1072,7 +1072,7 @@ static inline unsigned int queue_physical_block_size(struct request_queue *q)
 	return q->limits.physical_block_size;
 }
 
-static inline int bdev_physical_block_size(struct block_device *bdev)
+static inline unsigned int bdev_physical_block_size(struct block_device *bdev)
 {
 	return queue_physical_block_size(bdev_get_queue(bdev));
 }
Signature · 1 line
1.7.4.4
#16 lore raw

PATCH 16/209 block: limit vec count in bio_kmalloc() and bio_alloc_map_data()

In reply to Paul Gortmaker

From: Jens Axboe <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit f3f63c1c28bc861a931fac283b5bc3585efb8967 upstream.

---
 fs/bio.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)
fs/bio.c +8 -1
index e7bf6ca..75ea4c3 100644
@@ -370,6 +370,9 @@ struct bio *bio_kmalloc(gfp_t gfp_mask, int nr_iovecs)
 {
 	struct bio *bio;
 
+	if (nr_iovecs > UIO_MAXIOV)
+		return NULL;
+
 	bio = kmalloc(sizeof(struct bio) + nr_iovecs * sizeof(struct bio_vec),
 		      gfp_mask);
 	if (unlikely(!bio))
@@ -697,8 +700,12 @@ static void bio_free_map_data(struct bio_map_data *bmd)
 static struct bio_map_data *bio_alloc_map_data(int nr_segs, int iov_count,
 					       gfp_t gfp_mask)
 {
-	struct bio_map_data *bmd = kmalloc(sizeof(*bmd), gfp_mask);
+	struct bio_map_data *bmd;
+
+	if (iov_count > UIO_MAXIOV)
+		return NULL;
 
+	bmd = kmalloc(sizeof(*bmd), gfp_mask);
 	if (!bmd)
 		return NULL;
 
Signature · 1 line
1.7.4.4
#17 lore raw

PATCH 17/209 block: take care not to overflow when calculating total iov length

In reply to Paul Gortmaker

From: Jens Axboe <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 9f864c80913467312c7b8690e41fb5ebd1b50e92 upstream.

---
 block/scsi_ioctl.c |   34 ++++++++++++++++++++++++----------
 1 files changed, 24 insertions(+), 10 deletions(-)
block/scsi_ioctl.c +24 -10
index a8b5a10..4f4230b 100644
@@ -321,33 +321,47 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
 	if (hdr->iovec_count) {
 		const int size = sizeof(struct sg_iovec) * hdr->iovec_count;
 		size_t iov_data_len;
-		struct sg_iovec *iov;
+		struct sg_iovec *sg_iov;
+		struct iovec *iov;
+		int i;
 
-		iov = kmalloc(size, GFP_KERNEL);
-		if (!iov) {
+		sg_iov = kmalloc(size, GFP_KERNEL);
+		if (!sg_iov) {
 			ret = -ENOMEM;
 			goto out;
 		}
 
-		if (copy_from_user(iov, hdr->dxferp, size)) {
-			kfree(iov);
+		if (copy_from_user(sg_iov, hdr->dxferp, size)) {
+			kfree(sg_iov);
 			ret = -EFAULT;
 			goto out;
 		}
 
+		/*
+		 * Sum up the vecs, making sure they don't overflow
+		 */
+		iov = (struct iovec *) sg_iov;
+		iov_data_len = 0;
+		for (i = 0; i < hdr->iovec_count; i++) {
+			if (iov_data_len + iov[i].iov_len < iov_data_len) {
+				kfree(sg_iov);
+				ret = -EINVAL;
+				goto out;
+			}
+			iov_data_len += iov[i].iov_len;
+		}
+
 		/* SG_IO howto says that the shorter of the two wins */
-		iov_data_len = iov_length((struct iovec *)iov,
-					  hdr->iovec_count);
 		if (hdr->dxfer_len < iov_data_len) {
-			hdr->iovec_count = iov_shorten((struct iovec *)iov,
+			hdr->iovec_count = iov_shorten(iov,
 						       hdr->iovec_count,
 						       hdr->dxfer_len);
 			iov_data_len = hdr->dxfer_len;
 		}
 
-		ret = blk_rq_map_user_iov(q, rq, NULL, iov, hdr->iovec_count,
+		ret = blk_rq_map_user_iov(q, rq, NULL, sg_iov, hdr->iovec_count,
 					  iov_data_len, GFP_KERNEL);
-		kfree(iov);
+		kfree(sg_iov);
 	} else if (hdr->dxfer_len)
 		ret = blk_rq_map_user(q, rq, NULL, hdr->dxferp, hdr->dxfer_len,
 				      GFP_KERNEL);
Signature · 1 line
1.7.4.4
#18 lore raw

PATCH 18/209 block: check for proper length of iov entries in blk_rq_map_user_iov()

In reply to Paul Gortmaker

From: Jens Axboe <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 9284bcf4e335e5f18a8bc7b26461c33ab60d0689 upstream.

Ensure that we pass down properly validated iov segments before calling into the mapping or copy functions.

---
 block/blk-map.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
block/blk-map.c +2 -0
index 9083cf0..30a7e51 100644
@@ -205,6 +205,8 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
 			unaligned = 1;
 			break;
 		}
+		if (!iov[i].iov_len)
+			return -EINVAL;
 	}
 
 	if (unaligned || (q->dma_pad_mask & len) || map_data)
Signature · 1 line
1.7.4.4
#19 lore raw

PATCH 19/209 jme: Fix PHY power-off error

In reply to Paul Gortmaker

From: Guo-Fu Tseng <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit c8a8684d5cfb0f110a962c93586630c0bf91ebc1 upstream.

Adding phy_on in opposition to phy_off.

---
 drivers/net/jme.c |   22 ++++++++++++++++++----
 1 files changed, 18 insertions(+), 4 deletions(-)
drivers/net/jme.c +18 -4
index b705ad3..b2d190e 100644
@@ -1579,6 +1579,16 @@ jme_free_irq(struct jme_adapter *jme)
 	}
 }
 
+static inline void
+jme_phy_on(struct jme_adapter *jme)
+{
+	u32 bmcr;
+
+	bmcr = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_BMCR);
+	bmcr &= ~BMCR_PDOWN;
+	jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_BMCR, bmcr);
+}
+
 static int
 jme_open(struct net_device *netdev)
 {
@@ -1599,10 +1609,12 @@ jme_open(struct net_device *netdev)
 
 	jme_start_irq(jme);
 
-	if (test_bit(JME_FLAG_SSET, &jme->flags))
+	if (test_bit(JME_FLAG_SSET, &jme->flags)) {
+		jme_phy_on(jme);
 		jme_set_settings(netdev, &jme->old_ecmd);
-	else
+	} else {
 		jme_reset_phy_processor(jme);
+	}
 
 	jme_reset_link(jme);
 
@@ -3010,10 +3022,12 @@ jme_resume(struct pci_dev *pdev)
 	jme_clear_pm(jme);
 	pci_restore_state(pdev);
 
-	if (test_bit(JME_FLAG_SSET, &jme->flags))
+	if (test_bit(JME_FLAG_SSET, &jme->flags)) {
+		jme_phy_on(jme);
 		jme_set_settings(netdev, &jme->old_ecmd);
-	else
+	} else {
 		jme_reset_phy_processor(jme);
+	}
 
 	jme_start_irq(jme);
 	netif_device_attach(netdev);
Signature · 1 line
1.7.4.4
#20 lore raw

PATCH 20/209 irda: Fix parameter extraction stack overflow

In reply to Paul Gortmaker

From: Samuel Ortiz <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit efc463eb508798da4243625b08c7396462cabf9f upstream.

---
 net/irda/parameters.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)
net/irda/parameters.c +3 -1
index fc1a205..71cd38c 100644
@@ -298,6 +298,8 @@ static int irda_extract_string(void *self, __u8 *buf, int len, __u8 pi,
 
 	p.pi = pi;     /* In case handler needs to know */
 	p.pl = buf[1]; /* Extract length of value */
+	if (p.pl > 32)
+		p.pl = 32;
 
 	IRDA_DEBUG(2, "%s(), pi=%#x, pl=%d\n", __func__,
 		   p.pi, p.pl);
@@ -318,7 +320,7 @@ static int irda_extract_string(void *self, __u8 *buf, int len, __u8 pi,
 		   (__u8) str[0], (__u8) str[1]);
 
 	/* Null terminate string */
-	str[p.pl+1] = '\0';
+	str[p.pl] = '\0';
 
 	p.pv.c = str; /* Handler will need to take a copy */
 
Signature · 1 line
1.7.4.4
#21 lore raw

PATCH 21/209 irda: Fix heap memory corruption in iriap.c

In reply to Paul Gortmaker

From: Samuel Ortiz <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 37f9fc452d138dfc4da2ee1ce5ae85094efc3606 upstream.

While parsing the GetValuebyClass command frame, we could potentially write passed the skb->data pointer.

---
 net/irda/iriap.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
net/irda/iriap.c +2 -1
index 79a1e5a..b6fd6d1 100644
@@ -502,7 +502,8 @@ static void iriap_getvaluebyclass_confirm(struct iriap_cb *self,
 		IRDA_DEBUG(4, "%s(), strlen=%d\n", __func__, value_len);
 
 		/* Make sure the string is null-terminated */
-		fp[n+value_len] = 0x00;
+		if (n + value_len < skb->len)
+			fp[n + value_len] = 0x00;
 		IRDA_DEBUG(4, "Got string %s\n", fp+n);
 
 		/* Will truncate to IAS_MAX_STRING bytes */
Signature · 1 line
1.7.4.4
#22 lore raw

PATCH 22/209 i2c-pca-platform: Change device name of request_irq

In reply to Paul Gortmaker

From: Nobuhiro Iwamatsu <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 323584436db0cb05286425d4dfd9516fce88487f upstream.

i2c->adap.name shouldn't be used in request_irq. Instead the driver name "i2c-pca-platform" should be used.

---
 drivers/i2c/busses/i2c-pca-platform.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/i2c/busses/i2c-pca-platform.c +1 -1
index 1d8c208..fd295dd 100644
@@ -224,7 +224,7 @@ static int __devinit i2c_pca_pf_probe(struct platform_device *pdev)
 
 	if (irq) {
 		ret = request_irq(irq, i2c_pca_pf_handler,
-			IRQF_TRIGGER_FALLING, i2c->adap.name, i2c);
+			IRQF_TRIGGER_FALLING, pdev->name, i2c);
 		if (ret)
 			goto e_reqirq;
 	}
Signature · 1 line
1.7.4.4
#23 lore raw

PATCH 23/209 microblaze: Fix build with make 3.82

In reply to Paul Gortmaker

From: Thomas Backlund <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit b843e4ec01991a386a9e0e9030703524446e03da upstream.

When running make headers_install_all on x86_64 and make 3.82 I hit this:

arch/microblaze/Makefile:80: *** mixed implicit and normal rules. Stop.
make: *** [headers_install_all] Error 2

So split the rules to satisfy make 3.82.

---
 arch/microblaze/Makefile |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)
arch/microblaze/Makefile +6 -2
index 72f6e85..45e6afc 100644
@@ -72,12 +72,16 @@ export MMU DTB
 
 all: linux.bin
 
-BOOT_TARGETS = linux.bin linux.bin.gz simpleImage.%
+# With make 3.82 we cannot mix normal and wildcard targets
+BOOT_TARGETS1 = linux.bin linux.bin.gz
+BOOT_TARGETS2 = simpleImage.%
 
 archclean:
 	$(Q)$(MAKE) $(clean)=$(boot)
 
-$(BOOT_TARGETS): vmlinux
+$(BOOT_TARGETS1): vmlinux
+	$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+$(BOOT_TARGETS2): vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
 
 define archhelp
Signature · 1 line
1.7.4.4
#24 lore raw

PATCH 24/209 net: clear heap allocation for ETHTOOL_GRXCLSRLALL

In reply to Paul Gortmaker

From: Kees Cook <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit ae6df5f96a51818d6376da5307d773baeece4014 upstream.

Calling ETHTOOL_GRXCLSRLALL with a large rule_cnt will allocate kernel heap without clearing it. For the one driver (niu) that implements it, it will leave the unused portion of heap unchanged and copy the full contents back to userspace.

---
 net/core/ethtool.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
net/core/ethtool.c +1 -1
index 5328c62..49a2338 100644
@@ -349,7 +349,7 @@ static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev,
 	if (info.cmd == ETHTOOL_GRXCLSRLALL) {
 		if (info.rule_cnt > 0) {
 			if (info.rule_cnt <= KMALLOC_MAX_SIZE / sizeof(u32))
-				rule_buf = kmalloc(info.rule_cnt * sizeof(u32),
+				rule_buf = kzalloc(info.rule_cnt * sizeof(u32),
 						   GFP_USER);
 			if (!rule_buf)
 				return -ENOMEM;
Signature · 1 line
1.7.4.4
#25 lore raw

PATCH 25/209 Staging: asus_oled: fix up some sysfs attribute permissions

In reply to Paul Gortmaker

From: Greg Kroah-Hartman <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 590b0b9754bd8928926bae7194b6da7ead9bda3b upstream.

They should not be writable by any user

---
 drivers/staging/asus_oled/asus_oled.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)
drivers/staging/asus_oled/asus_oled.c +4 -4
index 7ebecc9..3dd5173 100644
@@ -620,13 +620,13 @@ static ssize_t class_set_picture(struct device *device,
 
 #define ASUS_OLED_DEVICE_ATTR(_file)		dev_attr_asus_oled_##_file
 
-static DEVICE_ATTR(asus_oled_enabled, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(asus_oled_enabled, S_IRUSR | S_IRUGO,
 		   get_enabled, set_enabled);
-static DEVICE_ATTR(asus_oled_picture, S_IWUGO , NULL, set_picture);
+static DEVICE_ATTR(asus_oled_picture, S_IRUSR , NULL, set_picture);
 
-static DEVICE_ATTR(enabled, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(enabled, S_IRUSR | S_IRUGO,
 		   class_get_enabled, class_set_enabled);
-static DEVICE_ATTR(picture, S_IWUGO, NULL, class_set_picture);
+static DEVICE_ATTR(picture, S_IRUSR, NULL, class_set_picture);
 
 static int asus_oled_probe(struct usb_interface *interface,
 			   const struct usb_device_id *id)
Signature · 1 line
1.7.4.4
#26 lore raw

PATCH 26/209 Staging: asus_oled: fix up my fixup for some sysfs attribute permissions

In reply to Paul Gortmaker

From: Greg Kroah-Hartman <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 515b4987ccd097cdf5416530b05fdf9e01afe95a upstream.

They should be writable by root, not readable. Doh, stupid me with the wrong flags.

---
 drivers/staging/asus_oled/asus_oled.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)
drivers/staging/asus_oled/asus_oled.c +4 -4
index 3dd5173..5820286 100644
@@ -620,13 +620,13 @@ static ssize_t class_set_picture(struct device *device,
 
 #define ASUS_OLED_DEVICE_ATTR(_file)		dev_attr_asus_oled_##_file
 
-static DEVICE_ATTR(asus_oled_enabled, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR(asus_oled_enabled, S_IWUSR | S_IRUGO,
 		   get_enabled, set_enabled);
-static DEVICE_ATTR(asus_oled_picture, S_IRUSR , NULL, set_picture);
+static DEVICE_ATTR(asus_oled_picture, S_IWUSR , NULL, set_picture);
 
-static DEVICE_ATTR(enabled, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR(enabled, S_IWUSR | S_IRUGO,
 		   class_get_enabled, class_set_enabled);
-static DEVICE_ATTR(picture, S_IRUSR, NULL, class_set_picture);
+static DEVICE_ATTR(picture, S_IWUSR, NULL, class_set_picture);
 
 static int asus_oled_probe(struct usb_interface *interface,
 			   const struct usb_device_id *id)
Signature · 1 line
1.7.4.4
#27 lore raw

PATCH 27/209 Staging: line6: fix up some sysfs attribute permissions

In reply to Paul Gortmaker

From: Greg Kroah-Hartman <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 2018845b6a169f75341f8e68ad1089cb6697cf24 upstream

They should not be writable by any user

[PG: 34 doesn't have the DEVICE_ATTR chunk in pcm.c so drop that chunk]

---
 drivers/staging/line6/control.c  |  204 +++++++++++++++++++-------------------
 drivers/staging/line6/midi.c     |    4 +-
 drivers/staging/line6/pod.c      |   32 +++---
 drivers/staging/line6/toneport.c |    4 +-
 drivers/staging/line6/variax.c   |   12 +-
 5 files changed, 128 insertions(+), 128 deletions(-)
drivers/staging/line6/control.c +102 -102
index 0b59852..7f7c57b 100644
@@ -268,210 +268,210 @@ VARIAX_PARAM_R(float, mix2);
 VARIAX_PARAM_R(float, mix1);
 VARIAX_PARAM_R(int, pickup_wiring);
 
-static DEVICE_ATTR(tweak, S_IWUGO | S_IRUGO, pod_get_tweak, pod_set_tweak);
-static DEVICE_ATTR(wah_position, S_IWUGO | S_IRUGO, pod_get_wah_position,
+static DEVICE_ATTR(tweak, S_IRUSR | S_IRUGO, pod_get_tweak, pod_set_tweak);
+static DEVICE_ATTR(wah_position, S_IRUSR | S_IRUGO, pod_get_wah_position,
 		   pod_set_wah_position);
-static DEVICE_ATTR(compression_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(compression_gain, S_IRUSR | S_IRUGO,
 		   pod_get_compression_gain, pod_set_compression_gain);
-static DEVICE_ATTR(vol_pedal_position, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(vol_pedal_position, S_IRUSR | S_IRUGO,
 		   pod_get_vol_pedal_position, pod_set_vol_pedal_position);
-static DEVICE_ATTR(compression_threshold, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(compression_threshold, S_IRUSR | S_IRUGO,
 		   pod_get_compression_threshold,
 		   pod_set_compression_threshold);
-static DEVICE_ATTR(pan, S_IWUGO | S_IRUGO, pod_get_pan, pod_set_pan);
-static DEVICE_ATTR(amp_model_setup, S_IWUGO | S_IRUGO, pod_get_amp_model_setup,
+static DEVICE_ATTR(pan, S_IRUSR | S_IRUGO, pod_get_pan, pod_set_pan);
+static DEVICE_ATTR(amp_model_setup, S_IRUSR | S_IRUGO, pod_get_amp_model_setup,
 		   pod_set_amp_model_setup);
-static DEVICE_ATTR(amp_model, S_IWUGO | S_IRUGO, pod_get_amp_model,
+static DEVICE_ATTR(amp_model, S_IRUSR | S_IRUGO, pod_get_amp_model,
 		   pod_set_amp_model);
-static DEVICE_ATTR(drive, S_IWUGO | S_IRUGO, pod_get_drive, pod_set_drive);
-static DEVICE_ATTR(bass, S_IWUGO | S_IRUGO, pod_get_bass, pod_set_bass);
-static DEVICE_ATTR(mid, S_IWUGO | S_IRUGO, pod_get_mid, pod_set_mid);
-static DEVICE_ATTR(lowmid, S_IWUGO | S_IRUGO, pod_get_lowmid, pod_set_lowmid);
-static DEVICE_ATTR(treble, S_IWUGO | S_IRUGO, pod_get_treble, pod_set_treble);
-static DEVICE_ATTR(highmid, S_IWUGO | S_IRUGO, pod_get_highmid,
+static DEVICE_ATTR(drive, S_IRUSR | S_IRUGO, pod_get_drive, pod_set_drive);
+static DEVICE_ATTR(bass, S_IRUSR | S_IRUGO, pod_get_bass, pod_set_bass);
+static DEVICE_ATTR(mid, S_IRUSR | S_IRUGO, pod_get_mid, pod_set_mid);
+static DEVICE_ATTR(lowmid, S_IRUSR | S_IRUGO, pod_get_lowmid, pod_set_lowmid);
+static DEVICE_ATTR(treble, S_IRUSR | S_IRUGO, pod_get_treble, pod_set_treble);
+static DEVICE_ATTR(highmid, S_IRUSR | S_IRUGO, pod_get_highmid,
 		   pod_set_highmid);
-static DEVICE_ATTR(chan_vol, S_IWUGO | S_IRUGO, pod_get_chan_vol,
+static DEVICE_ATTR(chan_vol, S_IRUSR | S_IRUGO, pod_get_chan_vol,
 		   pod_set_chan_vol);
-static DEVICE_ATTR(reverb_mix, S_IWUGO | S_IRUGO, pod_get_reverb_mix,
+static DEVICE_ATTR(reverb_mix, S_IRUSR | S_IRUGO, pod_get_reverb_mix,
 		   pod_set_reverb_mix);
-static DEVICE_ATTR(effect_setup, S_IWUGO | S_IRUGO, pod_get_effect_setup,
+static DEVICE_ATTR(effect_setup, S_IRUSR | S_IRUGO, pod_get_effect_setup,
 		   pod_set_effect_setup);
-static DEVICE_ATTR(band_1_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_1_frequency, S_IRUSR | S_IRUGO,
 		   pod_get_band_1_frequency, pod_set_band_1_frequency);
-static DEVICE_ATTR(presence, S_IWUGO | S_IRUGO, pod_get_presence,
+static DEVICE_ATTR(presence, S_IRUSR | S_IRUGO, pod_get_presence,
 		   pod_set_presence);
-static DEVICE_ATTR2(treble__bass, treble, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(treble__bass, treble, S_IRUSR | S_IRUGO,
 		    pod_get_treble__bass, pod_set_treble__bass);
-static DEVICE_ATTR(noise_gate_enable, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(noise_gate_enable, S_IRUSR | S_IRUGO,
 		   pod_get_noise_gate_enable, pod_set_noise_gate_enable);
-static DEVICE_ATTR(gate_threshold, S_IWUGO | S_IRUGO, pod_get_gate_threshold,
+static DEVICE_ATTR(gate_threshold, S_IRUSR | S_IRUGO, pod_get_gate_threshold,
 		   pod_set_gate_threshold);
-static DEVICE_ATTR(gate_decay_time, S_IWUGO | S_IRUGO, pod_get_gate_decay_time,
+static DEVICE_ATTR(gate_decay_time, S_IRUSR | S_IRUGO, pod_get_gate_decay_time,
 		   pod_set_gate_decay_time);
-static DEVICE_ATTR(stomp_enable, S_IWUGO | S_IRUGO, pod_get_stomp_enable,
+static DEVICE_ATTR(stomp_enable, S_IRUSR | S_IRUGO, pod_get_stomp_enable,
 		   pod_set_stomp_enable);
-static DEVICE_ATTR(comp_enable, S_IWUGO | S_IRUGO, pod_get_comp_enable,
+static DEVICE_ATTR(comp_enable, S_IRUSR | S_IRUGO, pod_get_comp_enable,
 		   pod_set_comp_enable);
-static DEVICE_ATTR(stomp_time, S_IWUGO | S_IRUGO, pod_get_stomp_time,
+static DEVICE_ATTR(stomp_time, S_IRUSR | S_IRUGO, pod_get_stomp_time,
 		   pod_set_stomp_time);
-static DEVICE_ATTR(delay_enable, S_IWUGO | S_IRUGO, pod_get_delay_enable,
+static DEVICE_ATTR(delay_enable, S_IRUSR | S_IRUGO, pod_get_delay_enable,
 		   pod_set_delay_enable);
-static DEVICE_ATTR(mod_param_1, S_IWUGO | S_IRUGO, pod_get_mod_param_1,
+static DEVICE_ATTR(mod_param_1, S_IRUSR | S_IRUGO, pod_get_mod_param_1,
 		   pod_set_mod_param_1);
-static DEVICE_ATTR(delay_param_1, S_IWUGO | S_IRUGO, pod_get_delay_param_1,
+static DEVICE_ATTR(delay_param_1, S_IRUSR | S_IRUGO, pod_get_delay_param_1,
 		   pod_set_delay_param_1);
-static DEVICE_ATTR(delay_param_1_note_value, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(delay_param_1_note_value, S_IRUSR | S_IRUGO,
 		   pod_get_delay_param_1_note_value,
 		   pod_set_delay_param_1_note_value);
-static DEVICE_ATTR2(band_2_frequency__bass, band_2_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_2_frequency__bass, band_2_frequency, S_IRUSR | S_IRUGO,
 		    pod_get_band_2_frequency__bass,
 		    pod_set_band_2_frequency__bass);
-static DEVICE_ATTR(delay_param_2, S_IWUGO | S_IRUGO, pod_get_delay_param_2,
+static DEVICE_ATTR(delay_param_2, S_IRUSR | S_IRUGO, pod_get_delay_param_2,
 		   pod_set_delay_param_2);
-static DEVICE_ATTR(delay_volume_mix, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(delay_volume_mix, S_IRUSR | S_IRUGO,
 		   pod_get_delay_volume_mix, pod_set_delay_volume_mix);
-static DEVICE_ATTR(delay_param_3, S_IWUGO | S_IRUGO, pod_get_delay_param_3,
+static DEVICE_ATTR(delay_param_3, S_IRUSR | S_IRUGO, pod_get_delay_param_3,
 		   pod_set_delay_param_3);
-static DEVICE_ATTR(reverb_enable, S_IWUGO | S_IRUGO, pod_get_reverb_enable,
+static DEVICE_ATTR(reverb_enable, S_IRUSR | S_IRUGO, pod_get_reverb_enable,
 		   pod_set_reverb_enable);
-static DEVICE_ATTR(reverb_type, S_IWUGO | S_IRUGO, pod_get_reverb_type,
+static DEVICE_ATTR(reverb_type, S_IRUSR | S_IRUGO, pod_get_reverb_type,
 		   pod_set_reverb_type);
-static DEVICE_ATTR(reverb_decay, S_IWUGO | S_IRUGO, pod_get_reverb_decay,
+static DEVICE_ATTR(reverb_decay, S_IRUSR | S_IRUGO, pod_get_reverb_decay,
 		   pod_set_reverb_decay);
-static DEVICE_ATTR(reverb_tone, S_IWUGO | S_IRUGO, pod_get_reverb_tone,
+static DEVICE_ATTR(reverb_tone, S_IRUSR | S_IRUGO, pod_get_reverb_tone,
 		   pod_set_reverb_tone);
-static DEVICE_ATTR(reverb_pre_delay, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(reverb_pre_delay, S_IRUSR | S_IRUGO,
 		   pod_get_reverb_pre_delay, pod_set_reverb_pre_delay);
-static DEVICE_ATTR(reverb_pre_post, S_IWUGO | S_IRUGO, pod_get_reverb_pre_post,
+static DEVICE_ATTR(reverb_pre_post, S_IRUSR | S_IRUGO, pod_get_reverb_pre_post,
 		   pod_set_reverb_pre_post);
-static DEVICE_ATTR(band_2_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_2_frequency, S_IRUSR | S_IRUGO,
 		   pod_get_band_2_frequency, pod_set_band_2_frequency);
-static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IRUSR | S_IRUGO,
 		    pod_get_band_3_frequency__bass,
 		    pod_set_band_3_frequency__bass);
-static DEVICE_ATTR(wah_enable, S_IWUGO | S_IRUGO, pod_get_wah_enable,
+static DEVICE_ATTR(wah_enable, S_IRUSR | S_IRUGO, pod_get_wah_enable,
 		   pod_set_wah_enable);
-static DEVICE_ATTR(modulation_lo_cut, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(modulation_lo_cut, S_IRUSR | S_IRUGO,
 		   pod_get_modulation_lo_cut, pod_set_modulation_lo_cut);
-static DEVICE_ATTR(delay_reverb_lo_cut, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(delay_reverb_lo_cut, S_IRUSR | S_IRUGO,
 		   pod_get_delay_reverb_lo_cut, pod_set_delay_reverb_lo_cut);
-static DEVICE_ATTR(volume_pedal_minimum, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(volume_pedal_minimum, S_IRUSR | S_IRUGO,
 		   pod_get_volume_pedal_minimum, pod_set_volume_pedal_minimum);
-static DEVICE_ATTR(eq_pre_post, S_IWUGO | S_IRUGO, pod_get_eq_pre_post,
+static DEVICE_ATTR(eq_pre_post, S_IRUSR | S_IRUGO, pod_get_eq_pre_post,
 		   pod_set_eq_pre_post);
-static DEVICE_ATTR(volume_pre_post, S_IWUGO | S_IRUGO, pod_get_volume_pre_post,
+static DEVICE_ATTR(volume_pre_post, S_IRUSR | S_IRUGO, pod_get_volume_pre_post,
 		   pod_set_volume_pre_post);
-static DEVICE_ATTR(di_model, S_IWUGO | S_IRUGO, pod_get_di_model,
+static DEVICE_ATTR(di_model, S_IRUSR | S_IRUGO, pod_get_di_model,
 		   pod_set_di_model);
-static DEVICE_ATTR(di_delay, S_IWUGO | S_IRUGO, pod_get_di_delay,
+static DEVICE_ATTR(di_delay, S_IRUSR | S_IRUGO, pod_get_di_delay,
 		   pod_set_di_delay);
-static DEVICE_ATTR(mod_enable, S_IWUGO | S_IRUGO, pod_get_mod_enable,
+static DEVICE_ATTR(mod_enable, S_IRUSR | S_IRUGO, pod_get_mod_enable,
 		   pod_set_mod_enable);
-static DEVICE_ATTR(mod_param_1_note_value, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(mod_param_1_note_value, S_IRUSR | S_IRUGO,
 		   pod_get_mod_param_1_note_value,
 		   pod_set_mod_param_1_note_value);
-static DEVICE_ATTR(mod_param_2, S_IWUGO | S_IRUGO, pod_get_mod_param_2,
+static DEVICE_ATTR(mod_param_2, S_IRUSR | S_IRUGO, pod_get_mod_param_2,
 		   pod_set_mod_param_2);
-static DEVICE_ATTR(mod_param_3, S_IWUGO | S_IRUGO, pod_get_mod_param_3,
+static DEVICE_ATTR(mod_param_3, S_IRUSR | S_IRUGO, pod_get_mod_param_3,
 		   pod_set_mod_param_3);
-static DEVICE_ATTR(mod_param_4, S_IWUGO | S_IRUGO, pod_get_mod_param_4,
+static DEVICE_ATTR(mod_param_4, S_IRUSR | S_IRUGO, pod_get_mod_param_4,
 		   pod_set_mod_param_4);
-static DEVICE_ATTR(mod_param_5, S_IWUGO | S_IRUGO, pod_get_mod_param_5,
+static DEVICE_ATTR(mod_param_5, S_IRUSR | S_IRUGO, pod_get_mod_param_5,
 		   pod_set_mod_param_5);
-static DEVICE_ATTR(mod_volume_mix, S_IWUGO | S_IRUGO, pod_get_mod_volume_mix,
+static DEVICE_ATTR(mod_volume_mix, S_IRUSR | S_IRUGO, pod_get_mod_volume_mix,
 		   pod_set_mod_volume_mix);
-static DEVICE_ATTR(mod_pre_post, S_IWUGO | S_IRUGO, pod_get_mod_pre_post,
+static DEVICE_ATTR(mod_pre_post, S_IRUSR | S_IRUGO, pod_get_mod_pre_post,
 		   pod_set_mod_pre_post);
-static DEVICE_ATTR(modulation_model, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(modulation_model, S_IRUSR | S_IRUGO,
 		   pod_get_modulation_model, pod_set_modulation_model);
-static DEVICE_ATTR(band_3_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_3_frequency, S_IRUSR | S_IRUGO,
 		   pod_get_band_3_frequency, pod_set_band_3_frequency);
-static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IRUSR | S_IRUGO,
 		    pod_get_band_4_frequency__bass,
 		    pod_set_band_4_frequency__bass);
-static DEVICE_ATTR(mod_param_1_double_precision, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(mod_param_1_double_precision, S_IRUSR | S_IRUGO,
 		   pod_get_mod_param_1_double_precision,
 		   pod_set_mod_param_1_double_precision);
-static DEVICE_ATTR(delay_param_1_double_precision, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(delay_param_1_double_precision, S_IRUSR | S_IRUGO,
 		   pod_get_delay_param_1_double_precision,
 		   pod_set_delay_param_1_double_precision);
-static DEVICE_ATTR(eq_enable, S_IWUGO | S_IRUGO, pod_get_eq_enable,
+static DEVICE_ATTR(eq_enable, S_IRUSR | S_IRUGO, pod_get_eq_enable,
 		   pod_set_eq_enable);
-static DEVICE_ATTR(tap, S_IWUGO | S_IRUGO, pod_get_tap, pod_set_tap);
-static DEVICE_ATTR(volume_tweak_pedal_assign, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(tap, S_IRUSR | S_IRUGO, pod_get_tap, pod_set_tap);
+static DEVICE_ATTR(volume_tweak_pedal_assign, S_IRUSR | S_IRUGO,
 		   pod_get_volume_tweak_pedal_assign,
 		   pod_set_volume_tweak_pedal_assign);
-static DEVICE_ATTR(band_5_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_5_frequency, S_IRUSR | S_IRUGO,
 		   pod_get_band_5_frequency, pod_set_band_5_frequency);
-static DEVICE_ATTR(tuner, S_IWUGO | S_IRUGO, pod_get_tuner, pod_set_tuner);
-static DEVICE_ATTR(mic_selection, S_IWUGO | S_IRUGO, pod_get_mic_selection,
+static DEVICE_ATTR(tuner, S_IRUSR | S_IRUGO, pod_get_tuner, pod_set_tuner);
+static DEVICE_ATTR(mic_selection, S_IRUSR | S_IRUGO, pod_get_mic_selection,
 		   pod_set_mic_selection);
-static DEVICE_ATTR(cabinet_model, S_IWUGO | S_IRUGO, pod_get_cabinet_model,
+static DEVICE_ATTR(cabinet_model, S_IRUSR | S_IRUGO, pod_get_cabinet_model,
 		   pod_set_cabinet_model);
-static DEVICE_ATTR(stomp_model, S_IWUGO | S_IRUGO, pod_get_stomp_model,
+static DEVICE_ATTR(stomp_model, S_IRUSR | S_IRUGO, pod_get_stomp_model,
 		   pod_set_stomp_model);
-static DEVICE_ATTR(roomlevel, S_IWUGO | S_IRUGO, pod_get_roomlevel,
+static DEVICE_ATTR(roomlevel, S_IRUSR | S_IRUGO, pod_get_roomlevel,
 		   pod_set_roomlevel);
-static DEVICE_ATTR(band_4_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_4_frequency, S_IRUSR | S_IRUGO,
 		   pod_get_band_4_frequency, pod_set_band_4_frequency);
-static DEVICE_ATTR(band_6_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_6_frequency, S_IRUSR | S_IRUGO,
 		   pod_get_band_6_frequency, pod_set_band_6_frequency);
-static DEVICE_ATTR(stomp_param_1_note_value, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(stomp_param_1_note_value, S_IRUSR | S_IRUGO,
 		   pod_get_stomp_param_1_note_value,
 		   pod_set_stomp_param_1_note_value);
-static DEVICE_ATTR(stomp_param_2, S_IWUGO | S_IRUGO, pod_get_stomp_param_2,
+static DEVICE_ATTR(stomp_param_2, S_IRUSR | S_IRUGO, pod_get_stomp_param_2,
 		   pod_set_stomp_param_2);
-static DEVICE_ATTR(stomp_param_3, S_IWUGO | S_IRUGO, pod_get_stomp_param_3,
+static DEVICE_ATTR(stomp_param_3, S_IRUSR | S_IRUGO, pod_get_stomp_param_3,
 		   pod_set_stomp_param_3);
-static DEVICE_ATTR(stomp_param_4, S_IWUGO | S_IRUGO, pod_get_stomp_param_4,
+static DEVICE_ATTR(stomp_param_4, S_IRUSR | S_IRUGO, pod_get_stomp_param_4,
 		   pod_set_stomp_param_4);
-static DEVICE_ATTR(stomp_param_5, S_IWUGO | S_IRUGO, pod_get_stomp_param_5,
+static DEVICE_ATTR(stomp_param_5, S_IRUSR | S_IRUGO, pod_get_stomp_param_5,
 		   pod_set_stomp_param_5);
-static DEVICE_ATTR(stomp_param_6, S_IWUGO | S_IRUGO, pod_get_stomp_param_6,
+static DEVICE_ATTR(stomp_param_6, S_IRUSR | S_IRUGO, pod_get_stomp_param_6,
 		   pod_set_stomp_param_6);
-static DEVICE_ATTR(amp_switch_select, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(amp_switch_select, S_IRUSR | S_IRUGO,
 		   pod_get_amp_switch_select, pod_set_amp_switch_select);
-static DEVICE_ATTR(delay_param_4, S_IWUGO | S_IRUGO, pod_get_delay_param_4,
+static DEVICE_ATTR(delay_param_4, S_IRUSR | S_IRUGO, pod_get_delay_param_4,
 		   pod_set_delay_param_4);
-static DEVICE_ATTR(delay_param_5, S_IWUGO | S_IRUGO, pod_get_delay_param_5,
+static DEVICE_ATTR(delay_param_5, S_IRUSR | S_IRUGO, pod_get_delay_param_5,
 		   pod_set_delay_param_5);
-static DEVICE_ATTR(delay_pre_post, S_IWUGO | S_IRUGO, pod_get_delay_pre_post,
+static DEVICE_ATTR(delay_pre_post, S_IRUSR | S_IRUGO, pod_get_delay_pre_post,
 		   pod_set_delay_pre_post);
-static DEVICE_ATTR(delay_model, S_IWUGO | S_IRUGO, pod_get_delay_model,
+static DEVICE_ATTR(delay_model, S_IRUSR | S_IRUGO, pod_get_delay_model,
 		   pod_set_delay_model);
-static DEVICE_ATTR(delay_verb_model, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(delay_verb_model, S_IRUSR | S_IRUGO,
 		   pod_get_delay_verb_model, pod_set_delay_verb_model);
-static DEVICE_ATTR(tempo_msb, S_IWUGO | S_IRUGO, pod_get_tempo_msb,
+static DEVICE_ATTR(tempo_msb, S_IRUSR | S_IRUGO, pod_get_tempo_msb,
 		   pod_set_tempo_msb);
-static DEVICE_ATTR(tempo_lsb, S_IWUGO | S_IRUGO, pod_get_tempo_lsb,
+static DEVICE_ATTR(tempo_lsb, S_IRUSR | S_IRUGO, pod_get_tempo_lsb,
 		   pod_set_tempo_lsb);
-static DEVICE_ATTR(wah_model, S_IWUGO | S_IRUGO, pod_get_wah_model,
+static DEVICE_ATTR(wah_model, S_IRUSR | S_IRUGO, pod_get_wah_model,
 		   pod_set_wah_model);
-static DEVICE_ATTR(bypass_volume, S_IWUGO | S_IRUGO, pod_get_bypass_volume,
+static DEVICE_ATTR(bypass_volume, S_IRUSR | S_IRUGO, pod_get_bypass_volume,
 		   pod_set_bypass_volume);
-static DEVICE_ATTR(fx_loop_on_off, S_IWUGO | S_IRUGO, pod_get_fx_loop_on_off,
+static DEVICE_ATTR(fx_loop_on_off, S_IRUSR | S_IRUGO, pod_get_fx_loop_on_off,
 		   pod_set_fx_loop_on_off);
-static DEVICE_ATTR(tweak_param_select, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(tweak_param_select, S_IRUSR | S_IRUGO,
 		   pod_get_tweak_param_select, pod_set_tweak_param_select);
-static DEVICE_ATTR(amp1_engage, S_IWUGO | S_IRUGO, pod_get_amp1_engage,
+static DEVICE_ATTR(amp1_engage, S_IRUSR | S_IRUGO, pod_get_amp1_engage,
 		   pod_set_amp1_engage);
-static DEVICE_ATTR(band_1_gain, S_IWUGO | S_IRUGO, pod_get_band_1_gain,
+static DEVICE_ATTR(band_1_gain, S_IRUSR | S_IRUGO, pod_get_band_1_gain,
 		   pod_set_band_1_gain);
-static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IRUSR | S_IRUGO,
 		    pod_get_band_2_gain__bass, pod_set_band_2_gain__bass);
-static DEVICE_ATTR(band_2_gain, S_IWUGO | S_IRUGO, pod_get_band_2_gain,
+static DEVICE_ATTR(band_2_gain, S_IRUSR | S_IRUGO, pod_get_band_2_gain,
 		   pod_set_band_2_gain);
-static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IRUSR | S_IRUGO,
 		    pod_get_band_3_gain__bass, pod_set_band_3_gain__bass);
-static DEVICE_ATTR(band_3_gain, S_IWUGO | S_IRUGO, pod_get_band_3_gain,
+static DEVICE_ATTR(band_3_gain, S_IRUSR | S_IRUGO, pod_get_band_3_gain,
 		   pod_set_band_3_gain);
-static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IRUSR | S_IRUGO,
 		    pod_get_band_4_gain__bass, pod_set_band_4_gain__bass);
-static DEVICE_ATTR2(band_5_gain__bass, band_5_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_5_gain__bass, band_5_gain, S_IRUSR | S_IRUGO,
 		    pod_get_band_5_gain__bass, pod_set_band_5_gain__bass);
-static DEVICE_ATTR(band_4_gain, S_IWUGO | S_IRUGO, pod_get_band_4_gain,
+static DEVICE_ATTR(band_4_gain, S_IRUSR | S_IRUGO, pod_get_band_4_gain,
 		   pod_set_band_4_gain);
-static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IRUSR | S_IRUGO,
 		    pod_get_band_6_gain__bass, pod_set_band_6_gain__bass);
 static DEVICE_ATTR(body, S_IRUGO, variax_get_body, line6_nop_write);
 static DEVICE_ATTR(pickup1_enable, S_IRUGO, variax_get_pickup1_enable,
drivers/staging/line6/midi.c +2 -2
index 32b6ca7..02becee 100644
@@ -362,8 +362,8 @@ static ssize_t midi_set_midi_mask_receive(struct device *dev,
 	return count;
 }
 
-static DEVICE_ATTR(midi_mask_transmit, S_IWUGO | S_IRUGO, midi_get_midi_mask_transmit, midi_set_midi_mask_transmit);
-static DEVICE_ATTR(midi_mask_receive, S_IWUGO | S_IRUGO, midi_get_midi_mask_receive, midi_set_midi_mask_receive);
+static DEVICE_ATTR(midi_mask_transmit, S_IRUSR | S_IRUGO, midi_get_midi_mask_transmit, midi_set_midi_mask_transmit);
+static DEVICE_ATTR(midi_mask_receive, S_IRUSR | S_IRUGO, midi_get_midi_mask_receive, midi_set_midi_mask_receive);
 
 /* MIDI device destructor */
 static int snd_line6_midi_free(struct snd_device *device)
drivers/staging/line6/pod.c +16 -16
index 4983f2b..90c3cb6 100644
@@ -952,33 +952,33 @@ POD_GET_SYSTEM_PARAM(tuner_pitch, 1, 1);
 #undef GET_SYSTEM_PARAM
 
 /* POD special files: */
-static DEVICE_ATTR(channel, S_IWUGO | S_IRUGO, pod_get_channel, pod_set_channel);
+static DEVICE_ATTR(channel, S_IRUSR | S_IRUGO, pod_get_channel, pod_set_channel);
 static DEVICE_ATTR(clip, S_IRUGO, pod_wait_for_clip, line6_nop_write);
 static DEVICE_ATTR(device_id, S_IRUGO, pod_get_device_id, line6_nop_write);
 static DEVICE_ATTR(dirty, S_IRUGO, pod_get_dirty, line6_nop_write);
-static DEVICE_ATTR(dump, S_IWUGO | S_IRUGO, pod_get_dump, pod_set_dump);
-static DEVICE_ATTR(dump_buf, S_IWUGO | S_IRUGO, pod_get_dump_buf, pod_set_dump_buf);
-static DEVICE_ATTR(finish, S_IWUGO, line6_nop_read, pod_set_finish);
+static DEVICE_ATTR(dump, S_IRUSR | S_IRUGO, pod_get_dump, pod_set_dump);
+static DEVICE_ATTR(dump_buf, S_IRUSR | S_IRUGO, pod_get_dump_buf, pod_set_dump_buf);
+static DEVICE_ATTR(finish, S_IRUSR, line6_nop_read, pod_set_finish);
 static DEVICE_ATTR(firmware_version, S_IRUGO, pod_get_firmware_version, line6_nop_write);
-static DEVICE_ATTR(midi_postprocess, S_IWUGO | S_IRUGO, pod_get_midi_postprocess, pod_set_midi_postprocess);
-static DEVICE_ATTR(monitor_level, S_IWUGO | S_IRUGO, pod_get_monitor_level, pod_set_monitor_level);
+static DEVICE_ATTR(midi_postprocess, S_IRUSR | S_IRUGO, pod_get_midi_postprocess, pod_set_midi_postprocess);
+static DEVICE_ATTR(monitor_level, S_IRUSR | S_IRUGO, pod_get_monitor_level, pod_set_monitor_level);
 static DEVICE_ATTR(name, S_IRUGO, pod_get_name, line6_nop_write);
 static DEVICE_ATTR(name_buf, S_IRUGO, pod_get_name_buf, line6_nop_write);
-static DEVICE_ATTR(retrieve_amp_setup, S_IWUGO, line6_nop_read, pod_set_retrieve_amp_setup);
-static DEVICE_ATTR(retrieve_channel, S_IWUGO, line6_nop_read, pod_set_retrieve_channel);
-static DEVICE_ATTR(retrieve_effects_setup, S_IWUGO, line6_nop_read, pod_set_retrieve_effects_setup);
-static DEVICE_ATTR(routing, S_IWUGO | S_IRUGO, pod_get_routing, pod_set_routing);
+static DEVICE_ATTR(retrieve_amp_setup, S_IRUSR, line6_nop_read, pod_set_retrieve_amp_setup);
+static DEVICE_ATTR(retrieve_channel, S_IRUSR, line6_nop_read, pod_set_retrieve_channel);
+static DEVICE_ATTR(retrieve_effects_setup, S_IRUSR, line6_nop_read, pod_set_retrieve_effects_setup);
+static DEVICE_ATTR(routing, S_IRUSR | S_IRUGO, pod_get_routing, pod_set_routing);
 static DEVICE_ATTR(serial_number, S_IRUGO, pod_get_serial_number, line6_nop_write);
-static DEVICE_ATTR(store_amp_setup, S_IWUGO, line6_nop_read, pod_set_store_amp_setup);
-static DEVICE_ATTR(store_channel, S_IWUGO, line6_nop_read, pod_set_store_channel);
-static DEVICE_ATTR(store_effects_setup, S_IWUGO, line6_nop_read, pod_set_store_effects_setup);
-static DEVICE_ATTR(tuner_freq, S_IWUGO | S_IRUGO, pod_get_tuner_freq, pod_set_tuner_freq);
-static DEVICE_ATTR(tuner_mute, S_IWUGO | S_IRUGO, pod_get_tuner_mute, pod_set_tuner_mute);
+static DEVICE_ATTR(store_amp_setup, S_IRUSR, line6_nop_read, pod_set_store_amp_setup);
+static DEVICE_ATTR(store_channel, S_IRUSR, line6_nop_read, pod_set_store_channel);
+static DEVICE_ATTR(store_effects_setup, S_IRUSR, line6_nop_read, pod_set_store_effects_setup);
+static DEVICE_ATTR(tuner_freq, S_IRUSR | S_IRUGO, pod_get_tuner_freq, pod_set_tuner_freq);
+static DEVICE_ATTR(tuner_mute, S_IRUSR | S_IRUGO, pod_get_tuner_mute, pod_set_tuner_mute);
 static DEVICE_ATTR(tuner_note, S_IRUGO, pod_get_tuner_note, line6_nop_write);
 static DEVICE_ATTR(tuner_pitch, S_IRUGO, pod_get_tuner_pitch, line6_nop_write);
 
 #if CREATE_RAW_FILE
-static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw);
+static DEVICE_ATTR(raw, S_IRUSR, line6_nop_read, line6_set_raw);
 #endif
 
 /*
drivers/staging/line6/toneport.c +2 -2
index e6770ea..e20fbf2 100644
@@ -124,9 +124,9 @@ static ssize_t toneport_set_led_green(struct device *dev,
 	return count;
 }
 
-static DEVICE_ATTR(led_red, S_IWUGO | S_IRUGO, line6_nop_read,
+static DEVICE_ATTR(led_red, S_IRUSR | S_IRUGO, line6_nop_read,
 		   toneport_set_led_red);
-static DEVICE_ATTR(led_green, S_IWUGO | S_IRUGO, line6_nop_read,
+static DEVICE_ATTR(led_green, S_IRUSR | S_IRUGO, line6_nop_read,
 		   toneport_set_led_green);
 
 static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2)
drivers/staging/line6/variax.c +6 -6
index 28eb899..c2ff9c2 100644
@@ -389,17 +389,17 @@ static ssize_t variax_set_raw2(struct device *dev,
 #endif
 
 /* Variax workbench special files: */
-static DEVICE_ATTR(model, S_IWUGO | S_IRUGO, variax_get_model, variax_set_model);
-static DEVICE_ATTR(volume, S_IWUGO | S_IRUGO, variax_get_volume, variax_set_volume);
-static DEVICE_ATTR(tone, S_IWUGO | S_IRUGO, variax_get_tone, variax_set_tone);
+static DEVICE_ATTR(model, S_IRUSR | S_IRUGO, variax_get_model, variax_set_model);
+static DEVICE_ATTR(volume, S_IRUSR | S_IRUGO, variax_get_volume, variax_set_volume);
+static DEVICE_ATTR(tone, S_IRUSR | S_IRUGO, variax_get_tone, variax_set_tone);
 static DEVICE_ATTR(name, S_IRUGO, variax_get_name, line6_nop_write);
 static DEVICE_ATTR(bank, S_IRUGO, variax_get_bank, line6_nop_write);
 static DEVICE_ATTR(dump, S_IRUGO, variax_get_dump, line6_nop_write);
-static DEVICE_ATTR(active, S_IWUGO | S_IRUGO, variax_get_active, variax_set_active);
+static DEVICE_ATTR(active, S_IRUSR | S_IRUGO, variax_get_active, variax_set_active);
 
 #if CREATE_RAW_FILE
-static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw);
-static DEVICE_ATTR(raw2, S_IWUGO, line6_nop_read, variax_set_raw2);
+static DEVICE_ATTR(raw, S_IRUSR, line6_nop_read, line6_set_raw);
+static DEVICE_ATTR(raw2, S_IRUSR, line6_nop_read, variax_set_raw2);
 #endif
 
 
Signature · 1 line
1.7.4.4
#28 lore raw

PATCH 28/209 Staging: line6: fix up my fixup for some sysfs attribute permissions

In reply to Paul Gortmaker

From: Greg Kroah-Hartman <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit a3a972a053010bfd61c13cfa4ce688d4eebd9a19 upstream

They should be writable by root, not readable. Doh, stupid me with the wrong flags.

[PG: 34 doesn't have the DEVICE_ATTR chunk in pcm.c so drop that chunk]

---
 drivers/staging/line6/control.c  |  204 +++++++++++++++++++-------------------
 drivers/staging/line6/midi.c     |    4 +-
 drivers/staging/line6/pod.c      |   32 +++---
 drivers/staging/line6/toneport.c |    4 +-
 drivers/staging/line6/variax.c   |   12 +-
 5 files changed, 128 insertions(+), 128 deletions(-)
drivers/staging/line6/control.c +102 -102
index 7f7c57b..e414571 100644
@@ -268,210 +268,210 @@ VARIAX_PARAM_R(float, mix2);
 VARIAX_PARAM_R(float, mix1);
 VARIAX_PARAM_R(int, pickup_wiring);
 
-static DEVICE_ATTR(tweak, S_IRUSR | S_IRUGO, pod_get_tweak, pod_set_tweak);
-static DEVICE_ATTR(wah_position, S_IRUSR | S_IRUGO, pod_get_wah_position,
+static DEVICE_ATTR(tweak, S_IWUSR | S_IRUGO, pod_get_tweak, pod_set_tweak);
+static DEVICE_ATTR(wah_position, S_IWUSR | S_IRUGO, pod_get_wah_position,
 		   pod_set_wah_position);
-static DEVICE_ATTR(compression_gain, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR(compression_gain, S_IWUSR | S_IRUGO,
 		   pod_get_compression_gain, pod_set_compression_gain);
-static DEVICE_ATTR(vol_pedal_position, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR(vol_pedal_position, S_IWUSR | S_IRUGO,
 		   pod_get_vol_pedal_position, pod_set_vol_pedal_position);
-static DEVICE_ATTR(compression_threshold, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR(compression_threshold, S_IWUSR | S_IRUGO,
 		   pod_get_compression_threshold,
 		   pod_set_compression_threshold);
-static DEVICE_ATTR(pan, S_IRUSR | S_IRUGO, pod_get_pan, pod_set_pan);
-static DEVICE_ATTR(amp_model_setup, S_IRUSR | S_IRUGO, pod_get_amp_model_setup,
+static DEVICE_ATTR(pan, S_IWUSR | S_IRUGO, pod_get_pan, pod_set_pan);
+static DEVICE_ATTR(amp_model_setup, S_IWUSR | S_IRUGO, pod_get_amp_model_setup,
 		   pod_set_amp_model_setup);
-static DEVICE_ATTR(amp_model, S_IRUSR | S_IRUGO, pod_get_amp_model,
+static DEVICE_ATTR(amp_model, S_IWUSR | S_IRUGO, pod_get_amp_model,
 		   pod_set_amp_model);
-static DEVICE_ATTR(drive, S_IRUSR | S_IRUGO, pod_get_drive, pod_set_drive);
-static DEVICE_ATTR(bass, S_IRUSR | S_IRUGO, pod_get_bass, pod_set_bass);
-static DEVICE_ATTR(mid, S_IRUSR | S_IRUGO, pod_get_mid, pod_set_mid);
-static DEVICE_ATTR(lowmid, S_IRUSR | S_IRUGO, pod_get_lowmid, pod_set_lowmid);
-static DEVICE_ATTR(treble, S_IRUSR | S_IRUGO, pod_get_treble, pod_set_treble);
-static DEVICE_ATTR(highmid, S_IRUSR | S_IRUGO, pod_get_highmid,
+static DEVICE_ATTR(drive, S_IWUSR | S_IRUGO, pod_get_drive, pod_set_drive);
+static DEVICE_ATTR(bass, S_IWUSR | S_IRUGO, pod_get_bass, pod_set_bass);
+static DEVICE_ATTR(mid, S_IWUSR | S_IRUGO, pod_get_mid, pod_set_mid);
+static DEVICE_ATTR(lowmid, S_IWUSR | S_IRUGO, pod_get_lowmid, pod_set_lowmid);
+static DEVICE_ATTR(treble, S_IWUSR | S_IRUGO, pod_get_treble, pod_set_treble);
+static DEVICE_ATTR(highmid, S_IWUSR | S_IRUGO, pod_get_highmid,
 		   pod_set_highmid);
-static DEVICE_ATTR(chan_vol, S_IRUSR | S_IRUGO, pod_get_chan_vol,
+static DEVICE_ATTR(chan_vol, S_IWUSR | S_IRUGO, pod_get_chan_vol,
 		   pod_set_chan_vol);
-static DEVICE_ATTR(reverb_mix, S_IRUSR | S_IRUGO, pod_get_reverb_mix,
+static DEVICE_ATTR(reverb_mix, S_IWUSR | S_IRUGO, pod_get_reverb_mix,
 		   pod_set_reverb_mix);
-static DEVICE_ATTR(effect_setup, S_IRUSR | S_IRUGO, pod_get_effect_setup,
+static DEVICE_ATTR(effect_setup, S_IWUSR | S_IRUGO, pod_get_effect_setup,
 		   pod_set_effect_setup);
-static DEVICE_ATTR(band_1_frequency, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR(band_1_frequency, S_IWUSR | S_IRUGO,
 		   pod_get_band_1_frequency, pod_set_band_1_frequency);
-static DEVICE_ATTR(presence, S_IRUSR | S_IRUGO, pod_get_presence,
+static DEVICE_ATTR(presence, S_IWUSR | S_IRUGO, pod_get_presence,
 		   pod_set_presence);
-static DEVICE_ATTR2(treble__bass, treble, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR2(treble__bass, treble, S_IWUSR | S_IRUGO,
 		    pod_get_treble__bass, pod_set_treble__bass);
-static DEVICE_ATTR(noise_gate_enable, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR(noise_gate_enable, S_IWUSR | S_IRUGO,
 		   pod_get_noise_gate_enable, pod_set_noise_gate_enable);
-static DEVICE_ATTR(gate_threshold, S_IRUSR | S_IRUGO, pod_get_gate_threshold,
+static DEVICE_ATTR(gate_threshold, S_IWUSR | S_IRUGO, pod_get_gate_threshold,
 		   pod_set_gate_threshold);
-static DEVICE_ATTR(gate_decay_time, S_IRUSR | S_IRUGO, pod_get_gate_decay_time,
+static DEVICE_ATTR(gate_decay_time, S_IWUSR | S_IRUGO, pod_get_gate_decay_time,
 		   pod_set_gate_decay_time);
-static DEVICE_ATTR(stomp_enable, S_IRUSR | S_IRUGO, pod_get_stomp_enable,
+static DEVICE_ATTR(stomp_enable, S_IWUSR | S_IRUGO, pod_get_stomp_enable,
 		   pod_set_stomp_enable);
-static DEVICE_ATTR(comp_enable, S_IRUSR | S_IRUGO, pod_get_comp_enable,
+static DEVICE_ATTR(comp_enable, S_IWUSR | S_IRUGO, pod_get_comp_enable,
 		   pod_set_comp_enable);
-static DEVICE_ATTR(stomp_time, S_IRUSR | S_IRUGO, pod_get_stomp_time,
+static DEVICE_ATTR(stomp_time, S_IWUSR | S_IRUGO, pod_get_stomp_time,
 		   pod_set_stomp_time);
-static DEVICE_ATTR(delay_enable, S_IRUSR | S_IRUGO, pod_get_delay_enable,
+static DEVICE_ATTR(delay_enable, S_IWUSR | S_IRUGO, pod_get_delay_enable,
 		   pod_set_delay_enable);
-static DEVICE_ATTR(mod_param_1, S_IRUSR | S_IRUGO, pod_get_mod_param_1,
+static DEVICE_ATTR(mod_param_1, S_IWUSR | S_IRUGO, pod_get_mod_param_1,
 		   pod_set_mod_param_1);
-static DEVICE_ATTR(delay_param_1, S_IRUSR | S_IRUGO, pod_get_delay_param_1,
+static DEVICE_ATTR(delay_param_1, S_IWUSR | S_IRUGO, pod_get_delay_param_1,
 		   pod_set_delay_param_1);
-static DEVICE_ATTR(delay_param_1_note_value, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR(delay_param_1_note_value, S_IWUSR | S_IRUGO,
 		   pod_get_delay_param_1_note_value,
 		   pod_set_delay_param_1_note_value);
-static DEVICE_ATTR2(band_2_frequency__bass, band_2_frequency, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR2(band_2_frequency__bass, band_2_frequency, S_IWUSR | S_IRUGO,
 		    pod_get_band_2_frequency__bass,
 		    pod_set_band_2_frequency__bass);
-static DEVICE_ATTR(delay_param_2, S_IRUSR | S_IRUGO, pod_get_delay_param_2,
+static DEVICE_ATTR(delay_param_2, S_IWUSR | S_IRUGO, pod_get_delay_param_2,
 		   pod_set_delay_param_2);
-static DEVICE_ATTR(delay_volume_mix, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR(delay_volume_mix, S_IWUSR | S_IRUGO,
 		   pod_get_delay_volume_mix, pod_set_delay_volume_mix);
-static DEVICE_ATTR(delay_param_3, S_IRUSR | S_IRUGO, pod_get_delay_param_3,
+static DEVICE_ATTR(delay_param_3, S_IWUSR | S_IRUGO, pod_get_delay_param_3,
 		   pod_set_delay_param_3);
-static DEVICE_ATTR(reverb_enable, S_IRUSR | S_IRUGO, pod_get_reverb_enable,
+static DEVICE_ATTR(reverb_enable, S_IWUSR | S_IRUGO, pod_get_reverb_enable,
 		   pod_set_reverb_enable);
-static DEVICE_ATTR(reverb_type, S_IRUSR | S_IRUGO, pod_get_reverb_type,
+static DEVICE_ATTR(reverb_type, S_IWUSR | S_IRUGO, pod_get_reverb_type,
 		   pod_set_reverb_type);
-static DEVICE_ATTR(reverb_decay, S_IRUSR | S_IRUGO, pod_get_reverb_decay,
+static DEVICE_ATTR(reverb_decay, S_IWUSR | S_IRUGO, pod_get_reverb_decay,
 		   pod_set_reverb_decay);
-static DEVICE_ATTR(reverb_tone, S_IRUSR | S_IRUGO, pod_get_reverb_tone,
+static DEVICE_ATTR(reverb_tone, S_IWUSR | S_IRUGO, pod_get_reverb_tone,
 		   pod_set_reverb_tone);
-static DEVICE_ATTR(reverb_pre_delay, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR(reverb_pre_delay, S_IWUSR | S_IRUGO,
 		   pod_get_reverb_pre_delay, pod_set_reverb_pre_delay);
-static DEVICE_ATTR(reverb_pre_post, S_IRUSR | S_IRUGO, pod_get_reverb_pre_post,
+static DEVICE_ATTR(reverb_pre_post, S_IWUSR | S_IRUGO, pod_get_reverb_pre_post,
 		   pod_set_reverb_pre_post);
-static DEVICE_ATTR(band_2_frequency, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR(band_2_frequency, S_IWUSR | S_IRUGO,
 		   pod_get_band_2_frequency, pod_set_band_2_frequency);
-static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IWUSR | S_IRUGO,
 		    pod_get_band_3_frequency__bass,
 		    pod_set_band_3_frequency__bass);
-static DEVICE_ATTR(wah_enable, S_IRUSR | S_IRUGO, pod_get_wah_enable,
+static DEVICE_ATTR(wah_enable, S_IWUSR | S_IRUGO, pod_get_wah_enable,
 		   pod_set_wah_enable);
-static DEVICE_ATTR(modulation_lo_cut, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR(modulation_lo_cut, S_IWUSR | S_IRUGO,
 		   pod_get_modulation_lo_cut, pod_set_modulation_lo_cut);
-static DEVICE_ATTR(delay_reverb_lo_cut, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR(delay_reverb_lo_cut, S_IWUSR | S_IRUGO,
 		   pod_get_delay_reverb_lo_cut, pod_set_delay_reverb_lo_cut);
-static DEVICE_ATTR(volume_pedal_minimum, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR(volume_pedal_minimum, S_IWUSR | S_IRUGO,
 		   pod_get_volume_pedal_minimum, pod_set_volume_pedal_minimum);
-static DEVICE_ATTR(eq_pre_post, S_IRUSR | S_IRUGO, pod_get_eq_pre_post,
+static DEVICE_ATTR(eq_pre_post, S_IWUSR | S_IRUGO, pod_get_eq_pre_post,
 		   pod_set_eq_pre_post);
-static DEVICE_ATTR(volume_pre_post, S_IRUSR | S_IRUGO, pod_get_volume_pre_post,
+static DEVICE_ATTR(volume_pre_post, S_IWUSR | S_IRUGO, pod_get_volume_pre_post,
 		   pod_set_volume_pre_post);
-static DEVICE_ATTR(di_model, S_IRUSR | S_IRUGO, pod_get_di_model,
+static DEVICE_ATTR(di_model, S_IWUSR | S_IRUGO, pod_get_di_model,
 		   pod_set_di_model);
-static DEVICE_ATTR(di_delay, S_IRUSR | S_IRUGO, pod_get_di_delay,
+static DEVICE_ATTR(di_delay, S_IWUSR | S_IRUGO, pod_get_di_delay,
 		   pod_set_di_delay);
-static DEVICE_ATTR(mod_enable, S_IRUSR | S_IRUGO, pod_get_mod_enable,
+static DEVICE_ATTR(mod_enable, S_IWUSR | S_IRUGO, pod_get_mod_enable,
 		   pod_set_mod_enable);
-static DEVICE_ATTR(mod_param_1_note_value, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR(mod_param_1_note_value, S_IWUSR | S_IRUGO,
 		   pod_get_mod_param_1_note_value,
 		   pod_set_mod_param_1_note_value);
-static DEVICE_ATTR(mod_param_2, S_IRUSR | S_IRUGO, pod_get_mod_param_2,
+static DEVICE_ATTR(mod_param_2, S_IWUSR | S_IRUGO, pod_get_mod_param_2,
 		   pod_set_mod_param_2);
-static DEVICE_ATTR(mod_param_3, S_IRUSR | S_IRUGO, pod_get_mod_param_3,
+static DEVICE_ATTR(mod_param_3, S_IWUSR | S_IRUGO, pod_get_mod_param_3,
 		   pod_set_mod_param_3);
-static DEVICE_ATTR(mod_param_4, S_IRUSR | S_IRUGO, pod_get_mod_param_4,
+static DEVICE_ATTR(mod_param_4, S_IWUSR | S_IRUGO, pod_get_mod_param_4,
 		   pod_set_mod_param_4);
-static DEVICE_ATTR(mod_param_5, S_IRUSR | S_IRUGO, pod_get_mod_param_5,
+static DEVICE_ATTR(mod_param_5, S_IWUSR | S_IRUGO, pod_get_mod_param_5,
 		   pod_set_mod_param_5);
-static DEVICE_ATTR(mod_volume_mix, S_IRUSR | S_IRUGO, pod_get_mod_volume_mix,
+static DEVICE_ATTR(mod_volume_mix, S_IWUSR | S_IRUGO, pod_get_mod_volume_mix,
 		   pod_set_mod_volume_mix);
-static DEVICE_ATTR(mod_pre_post, S_IRUSR | S_IRUGO, pod_get_mod_pre_post,
+static DEVICE_ATTR(mod_pre_post, S_IWUSR | S_IRUGO, pod_get_mod_pre_post,
 		   pod_set_mod_pre_post);
-static DEVICE_ATTR(modulation_model, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR(modulation_model, S_IWUSR | S_IRUGO,
 		   pod_get_modulation_model, pod_set_modulation_model);
-static DEVICE_ATTR(band_3_frequency, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR(band_3_frequency, S_IWUSR | S_IRUGO,
 		   pod_get_band_3_frequency, pod_set_band_3_frequency);
-static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IWUSR | S_IRUGO,
 		    pod_get_band_4_frequency__bass,
 		    pod_set_band_4_frequency__bass);
-static DEVICE_ATTR(mod_param_1_double_precision, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR(mod_param_1_double_precision, S_IWUSR | S_IRUGO,
 		   pod_get_mod_param_1_double_precision,
 		   pod_set_mod_param_1_double_precision);
-static DEVICE_ATTR(delay_param_1_double_precision, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR(delay_param_1_double_precision, S_IWUSR | S_IRUGO,
 		   pod_get_delay_param_1_double_precision,
 		   pod_set_delay_param_1_double_precision);
-static DEVICE_ATTR(eq_enable, S_IRUSR | S_IRUGO, pod_get_eq_enable,
+static DEVICE_ATTR(eq_enable, S_IWUSR | S_IRUGO, pod_get_eq_enable,
 		   pod_set_eq_enable);
-static DEVICE_ATTR(tap, S_IRUSR | S_IRUGO, pod_get_tap, pod_set_tap);
-static DEVICE_ATTR(volume_tweak_pedal_assign, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR(tap, S_IWUSR | S_IRUGO, pod_get_tap, pod_set_tap);
+static DEVICE_ATTR(volume_tweak_pedal_assign, S_IWUSR | S_IRUGO,
 		   pod_get_volume_tweak_pedal_assign,
 		   pod_set_volume_tweak_pedal_assign);
-static DEVICE_ATTR(band_5_frequency, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR(band_5_frequency, S_IWUSR | S_IRUGO,
 		   pod_get_band_5_frequency, pod_set_band_5_frequency);
-static DEVICE_ATTR(tuner, S_IRUSR | S_IRUGO, pod_get_tuner, pod_set_tuner);
-static DEVICE_ATTR(mic_selection, S_IRUSR | S_IRUGO, pod_get_mic_selection,
+static DEVICE_ATTR(tuner, S_IWUSR | S_IRUGO, pod_get_tuner, pod_set_tuner);
+static DEVICE_ATTR(mic_selection, S_IWUSR | S_IRUGO, pod_get_mic_selection,
 		   pod_set_mic_selection);
-static DEVICE_ATTR(cabinet_model, S_IRUSR | S_IRUGO, pod_get_cabinet_model,
+static DEVICE_ATTR(cabinet_model, S_IWUSR | S_IRUGO, pod_get_cabinet_model,
 		   pod_set_cabinet_model);
-static DEVICE_ATTR(stomp_model, S_IRUSR | S_IRUGO, pod_get_stomp_model,
+static DEVICE_ATTR(stomp_model, S_IWUSR | S_IRUGO, pod_get_stomp_model,
 		   pod_set_stomp_model);
-static DEVICE_ATTR(roomlevel, S_IRUSR | S_IRUGO, pod_get_roomlevel,
+static DEVICE_ATTR(roomlevel, S_IWUSR | S_IRUGO, pod_get_roomlevel,
 		   pod_set_roomlevel);
-static DEVICE_ATTR(band_4_frequency, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR(band_4_frequency, S_IWUSR | S_IRUGO,
 		   pod_get_band_4_frequency, pod_set_band_4_frequency);
-static DEVICE_ATTR(band_6_frequency, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR(band_6_frequency, S_IWUSR | S_IRUGO,
 		   pod_get_band_6_frequency, pod_set_band_6_frequency);
-static DEVICE_ATTR(stomp_param_1_note_value, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR(stomp_param_1_note_value, S_IWUSR | S_IRUGO,
 		   pod_get_stomp_param_1_note_value,
 		   pod_set_stomp_param_1_note_value);
-static DEVICE_ATTR(stomp_param_2, S_IRUSR | S_IRUGO, pod_get_stomp_param_2,
+static DEVICE_ATTR(stomp_param_2, S_IWUSR | S_IRUGO, pod_get_stomp_param_2,
 		   pod_set_stomp_param_2);
-static DEVICE_ATTR(stomp_param_3, S_IRUSR | S_IRUGO, pod_get_stomp_param_3,
+static DEVICE_ATTR(stomp_param_3, S_IWUSR | S_IRUGO, pod_get_stomp_param_3,
 		   pod_set_stomp_param_3);
-static DEVICE_ATTR(stomp_param_4, S_IRUSR | S_IRUGO, pod_get_stomp_param_4,
+static DEVICE_ATTR(stomp_param_4, S_IWUSR | S_IRUGO, pod_get_stomp_param_4,
 		   pod_set_stomp_param_4);
-static DEVICE_ATTR(stomp_param_5, S_IRUSR | S_IRUGO, pod_get_stomp_param_5,
+static DEVICE_ATTR(stomp_param_5, S_IWUSR | S_IRUGO, pod_get_stomp_param_5,
 		   pod_set_stomp_param_5);
-static DEVICE_ATTR(stomp_param_6, S_IRUSR | S_IRUGO, pod_get_stomp_param_6,
+static DEVICE_ATTR(stomp_param_6, S_IWUSR | S_IRUGO, pod_get_stomp_param_6,
 		   pod_set_stomp_param_6);
-static DEVICE_ATTR(amp_switch_select, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR(amp_switch_select, S_IWUSR | S_IRUGO,
 		   pod_get_amp_switch_select, pod_set_amp_switch_select);
-static DEVICE_ATTR(delay_param_4, S_IRUSR | S_IRUGO, pod_get_delay_param_4,
+static DEVICE_ATTR(delay_param_4, S_IWUSR | S_IRUGO, pod_get_delay_param_4,
 		   pod_set_delay_param_4);
-static DEVICE_ATTR(delay_param_5, S_IRUSR | S_IRUGO, pod_get_delay_param_5,
+static DEVICE_ATTR(delay_param_5, S_IWUSR | S_IRUGO, pod_get_delay_param_5,
 		   pod_set_delay_param_5);
-static DEVICE_ATTR(delay_pre_post, S_IRUSR | S_IRUGO, pod_get_delay_pre_post,
+static DEVICE_ATTR(delay_pre_post, S_IWUSR | S_IRUGO, pod_get_delay_pre_post,
 		   pod_set_delay_pre_post);
-static DEVICE_ATTR(delay_model, S_IRUSR | S_IRUGO, pod_get_delay_model,
+static DEVICE_ATTR(delay_model, S_IWUSR | S_IRUGO, pod_get_delay_model,
 		   pod_set_delay_model);
-static DEVICE_ATTR(delay_verb_model, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR(delay_verb_model, S_IWUSR | S_IRUGO,
 		   pod_get_delay_verb_model, pod_set_delay_verb_model);
-static DEVICE_ATTR(tempo_msb, S_IRUSR | S_IRUGO, pod_get_tempo_msb,
+static DEVICE_ATTR(tempo_msb, S_IWUSR | S_IRUGO, pod_get_tempo_msb,
 		   pod_set_tempo_msb);
-static DEVICE_ATTR(tempo_lsb, S_IRUSR | S_IRUGO, pod_get_tempo_lsb,
+static DEVICE_ATTR(tempo_lsb, S_IWUSR | S_IRUGO, pod_get_tempo_lsb,
 		   pod_set_tempo_lsb);
-static DEVICE_ATTR(wah_model, S_IRUSR | S_IRUGO, pod_get_wah_model,
+static DEVICE_ATTR(wah_model, S_IWUSR | S_IRUGO, pod_get_wah_model,
 		   pod_set_wah_model);
-static DEVICE_ATTR(bypass_volume, S_IRUSR | S_IRUGO, pod_get_bypass_volume,
+static DEVICE_ATTR(bypass_volume, S_IWUSR | S_IRUGO, pod_get_bypass_volume,
 		   pod_set_bypass_volume);
-static DEVICE_ATTR(fx_loop_on_off, S_IRUSR | S_IRUGO, pod_get_fx_loop_on_off,
+static DEVICE_ATTR(fx_loop_on_off, S_IWUSR | S_IRUGO, pod_get_fx_loop_on_off,
 		   pod_set_fx_loop_on_off);
-static DEVICE_ATTR(tweak_param_select, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR(tweak_param_select, S_IWUSR | S_IRUGO,
 		   pod_get_tweak_param_select, pod_set_tweak_param_select);
-static DEVICE_ATTR(amp1_engage, S_IRUSR | S_IRUGO, pod_get_amp1_engage,
+static DEVICE_ATTR(amp1_engage, S_IWUSR | S_IRUGO, pod_get_amp1_engage,
 		   pod_set_amp1_engage);
-static DEVICE_ATTR(band_1_gain, S_IRUSR | S_IRUGO, pod_get_band_1_gain,
+static DEVICE_ATTR(band_1_gain, S_IWUSR | S_IRUGO, pod_get_band_1_gain,
 		   pod_set_band_1_gain);
-static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IWUSR | S_IRUGO,
 		    pod_get_band_2_gain__bass, pod_set_band_2_gain__bass);
-static DEVICE_ATTR(band_2_gain, S_IRUSR | S_IRUGO, pod_get_band_2_gain,
+static DEVICE_ATTR(band_2_gain, S_IWUSR | S_IRUGO, pod_get_band_2_gain,
 		   pod_set_band_2_gain);
-static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IWUSR | S_IRUGO,
 		    pod_get_band_3_gain__bass, pod_set_band_3_gain__bass);
-static DEVICE_ATTR(band_3_gain, S_IRUSR | S_IRUGO, pod_get_band_3_gain,
+static DEVICE_ATTR(band_3_gain, S_IWUSR | S_IRUGO, pod_get_band_3_gain,
 		   pod_set_band_3_gain);
-static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IWUSR | S_IRUGO,
 		    pod_get_band_4_gain__bass, pod_set_band_4_gain__bass);
-static DEVICE_ATTR2(band_5_gain__bass, band_5_gain, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR2(band_5_gain__bass, band_5_gain, S_IWUSR | S_IRUGO,
 		    pod_get_band_5_gain__bass, pod_set_band_5_gain__bass);
-static DEVICE_ATTR(band_4_gain, S_IRUSR | S_IRUGO, pod_get_band_4_gain,
+static DEVICE_ATTR(band_4_gain, S_IWUSR | S_IRUGO, pod_get_band_4_gain,
 		   pod_set_band_4_gain);
-static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IRUSR | S_IRUGO,
+static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IWUSR | S_IRUGO,
 		    pod_get_band_6_gain__bass, pod_set_band_6_gain__bass);
 static DEVICE_ATTR(body, S_IRUGO, variax_get_body, line6_nop_write);
 static DEVICE_ATTR(pickup1_enable, S_IRUGO, variax_get_pickup1_enable,
drivers/staging/line6/midi.c +2 -2
index 02becee..9b42e34 100644
@@ -362,8 +362,8 @@ static ssize_t midi_set_midi_mask_receive(struct device *dev,
 	return count;
 }
 
-static DEVICE_ATTR(midi_mask_transmit, S_IRUSR | S_IRUGO, midi_get_midi_mask_transmit, midi_set_midi_mask_transmit);
-static DEVICE_ATTR(midi_mask_receive, S_IRUSR | S_IRUGO, midi_get_midi_mask_receive, midi_set_midi_mask_receive);
+static DEVICE_ATTR(midi_mask_transmit, S_IWUSR | S_IRUGO, midi_get_midi_mask_transmit, midi_set_midi_mask_transmit);
+static DEVICE_ATTR(midi_mask_receive, S_IWUSR | S_IRUGO, midi_get_midi_mask_receive, midi_set_midi_mask_receive);
 
 /* MIDI device destructor */
 static int snd_line6_midi_free(struct snd_device *device)
drivers/staging/line6/pod.c +16 -16
index 90c3cb6..6d2f4c5 100644
@@ -952,33 +952,33 @@ POD_GET_SYSTEM_PARAM(tuner_pitch, 1, 1);
 #undef GET_SYSTEM_PARAM
 
 /* POD special files: */
-static DEVICE_ATTR(channel, S_IRUSR | S_IRUGO, pod_get_channel, pod_set_channel);
+static DEVICE_ATTR(channel, S_IWUSR | S_IRUGO, pod_get_channel, pod_set_channel);
 static DEVICE_ATTR(clip, S_IRUGO, pod_wait_for_clip, line6_nop_write);
 static DEVICE_ATTR(device_id, S_IRUGO, pod_get_device_id, line6_nop_write);
 static DEVICE_ATTR(dirty, S_IRUGO, pod_get_dirty, line6_nop_write);
-static DEVICE_ATTR(dump, S_IRUSR | S_IRUGO, pod_get_dump, pod_set_dump);
-static DEVICE_ATTR(dump_buf, S_IRUSR | S_IRUGO, pod_get_dump_buf, pod_set_dump_buf);
-static DEVICE_ATTR(finish, S_IRUSR, line6_nop_read, pod_set_finish);
+static DEVICE_ATTR(dump, S_IWUSR | S_IRUGO, pod_get_dump, pod_set_dump);
+static DEVICE_ATTR(dump_buf, S_IWUSR | S_IRUGO, pod_get_dump_buf, pod_set_dump_buf);
+static DEVICE_ATTR(finish, S_IWUSR, line6_nop_read, pod_set_finish);
 static DEVICE_ATTR(firmware_version, S_IRUGO, pod_get_firmware_version, line6_nop_write);
-static DEVICE_ATTR(midi_postprocess, S_IRUSR | S_IRUGO, pod_get_midi_postprocess, pod_set_midi_postprocess);
-static DEVICE_ATTR(monitor_level, S_IRUSR | S_IRUGO, pod_get_monitor_level, pod_set_monitor_level);
+static DEVICE_ATTR(midi_postprocess, S_IWUSR | S_IRUGO, pod_get_midi_postprocess, pod_set_midi_postprocess);
+static DEVICE_ATTR(monitor_level, S_IWUSR | S_IRUGO, pod_get_monitor_level, pod_set_monitor_level);
 static DEVICE_ATTR(name, S_IRUGO, pod_get_name, line6_nop_write);
 static DEVICE_ATTR(name_buf, S_IRUGO, pod_get_name_buf, line6_nop_write);
-static DEVICE_ATTR(retrieve_amp_setup, S_IRUSR, line6_nop_read, pod_set_retrieve_amp_setup);
-static DEVICE_ATTR(retrieve_channel, S_IRUSR, line6_nop_read, pod_set_retrieve_channel);
-static DEVICE_ATTR(retrieve_effects_setup, S_IRUSR, line6_nop_read, pod_set_retrieve_effects_setup);
-static DEVICE_ATTR(routing, S_IRUSR | S_IRUGO, pod_get_routing, pod_set_routing);
+static DEVICE_ATTR(retrieve_amp_setup, S_IWUSR, line6_nop_read, pod_set_retrieve_amp_setup);
+static DEVICE_ATTR(retrieve_channel, S_IWUSR, line6_nop_read, pod_set_retrieve_channel);
+static DEVICE_ATTR(retrieve_effects_setup, S_IWUSR, line6_nop_read, pod_set_retrieve_effects_setup);
+static DEVICE_ATTR(routing, S_IWUSR | S_IRUGO, pod_get_routing, pod_set_routing);
 static DEVICE_ATTR(serial_number, S_IRUGO, pod_get_serial_number, line6_nop_write);
-static DEVICE_ATTR(store_amp_setup, S_IRUSR, line6_nop_read, pod_set_store_amp_setup);
-static DEVICE_ATTR(store_channel, S_IRUSR, line6_nop_read, pod_set_store_channel);
-static DEVICE_ATTR(store_effects_setup, S_IRUSR, line6_nop_read, pod_set_store_effects_setup);
-static DEVICE_ATTR(tuner_freq, S_IRUSR | S_IRUGO, pod_get_tuner_freq, pod_set_tuner_freq);
-static DEVICE_ATTR(tuner_mute, S_IRUSR | S_IRUGO, pod_get_tuner_mute, pod_set_tuner_mute);
+static DEVICE_ATTR(store_amp_setup, S_IWUSR, line6_nop_read, pod_set_store_amp_setup);
+static DEVICE_ATTR(store_channel, S_IWUSR, line6_nop_read, pod_set_store_channel);
+static DEVICE_ATTR(store_effects_setup, S_IWUSR, line6_nop_read, pod_set_store_effects_setup);
+static DEVICE_ATTR(tuner_freq, S_IWUSR | S_IRUGO, pod_get_tuner_freq, pod_set_tuner_freq);
+static DEVICE_ATTR(tuner_mute, S_IWUSR | S_IRUGO, pod_get_tuner_mute, pod_set_tuner_mute);
 static DEVICE_ATTR(tuner_note, S_IRUGO, pod_get_tuner_note, line6_nop_write);
 static DEVICE_ATTR(tuner_pitch, S_IRUGO, pod_get_tuner_pitch, line6_nop_write);
 
 #if CREATE_RAW_FILE
-static DEVICE_ATTR(raw, S_IRUSR, line6_nop_read, line6_set_raw);
+static DEVICE_ATTR(raw, S_IWUSR, line6_nop_read, line6_set_raw);
 #endif
 
 /*
drivers/staging/line6/toneport.c +2 -2
index e20fbf2..db42178 100644
@@ -124,9 +124,9 @@ static ssize_t toneport_set_led_green(struct device *dev,
 	return count;
 }
 
-static DEVICE_ATTR(led_red, S_IRUSR | S_IRUGO, line6_nop_read,
+static DEVICE_ATTR(led_red, S_IWUSR | S_IRUGO, line6_nop_read,
 		   toneport_set_led_red);
-static DEVICE_ATTR(led_green, S_IRUSR | S_IRUGO, line6_nop_read,
+static DEVICE_ATTR(led_green, S_IWUSR | S_IRUGO, line6_nop_read,
 		   toneport_set_led_green);
 
 static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2)
drivers/staging/line6/variax.c +6 -6
index c2ff9c2..0f48914 100644
@@ -389,17 +389,17 @@ static ssize_t variax_set_raw2(struct device *dev,
 #endif
 
 /* Variax workbench special files: */
-static DEVICE_ATTR(model, S_IRUSR | S_IRUGO, variax_get_model, variax_set_model);
-static DEVICE_ATTR(volume, S_IRUSR | S_IRUGO, variax_get_volume, variax_set_volume);
-static DEVICE_ATTR(tone, S_IRUSR | S_IRUGO, variax_get_tone, variax_set_tone);
+static DEVICE_ATTR(model, S_IWUSR | S_IRUGO, variax_get_model, variax_set_model);
+static DEVICE_ATTR(volume, S_IWUSR | S_IRUGO, variax_get_volume, variax_set_volume);
+static DEVICE_ATTR(tone, S_IWUSR | S_IRUGO, variax_get_tone, variax_set_tone);
 static DEVICE_ATTR(name, S_IRUGO, variax_get_name, line6_nop_write);
 static DEVICE_ATTR(bank, S_IRUGO, variax_get_bank, line6_nop_write);
 static DEVICE_ATTR(dump, S_IRUGO, variax_get_dump, line6_nop_write);
-static DEVICE_ATTR(active, S_IRUSR | S_IRUGO, variax_get_active, variax_set_active);
+static DEVICE_ATTR(active, S_IWUSR | S_IRUGO, variax_get_active, variax_set_active);
 
 #if CREATE_RAW_FILE
-static DEVICE_ATTR(raw, S_IRUSR, line6_nop_read, line6_set_raw);
-static DEVICE_ATTR(raw2, S_IRUSR, line6_nop_read, variax_set_raw2);
+static DEVICE_ATTR(raw, S_IWUSR, line6_nop_read, line6_set_raw);
+static DEVICE_ATTR(raw2, S_IWUSR, line6_nop_read, variax_set_raw2);
 #endif
 
 
Signature · 1 line
1.7.4.4
#29 lore raw

PATCH 29/209 hpet: fix unwanted interrupt due to stale irq status bit

In reply to Paul Gortmaker

From: Clemens Ladisch <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 96e9694df446d1154ec2f4fdba8908588b9cba38 upstream.

Quoted 5 lines · Jaswinder Singh Rajput

By executing Documentation/timers/hpet_example.c

for polling, I requested for 3 iterations but it seems iteration work for only 2 as first expired time is always very small.

Quoted 12 lines
# ./hpet_example poll /dev/hpet 10 3
-hpet: executing poll
hpet_poll: info.hi_flags 0x0
hpet_poll: expired time = 0x13
hpet_poll: revents = 0x1
hpet_poll: data 0x1
hpet_poll: expired time = 0x1868c
hpet_poll: revents = 0x1
hpet_poll: data 0x1
hpet_poll: expired time = 0x18645
hpet_poll: revents = 0x1
hpet_poll: data 0x1

Clearing the HPET interrupt enable bit disables interrupt generation but does not disable the timer, so the interrupt status bit will still be set when the timer elapses. If another interrupt arrives before the timer has been correctly programmed (due to some other device on the same interrupt line, or CONFIG_DEBUG_SHIRQ), this results in an extra unwanted interrupt event because the status bit is likely to be set from comparator matches that happened before the device was opened.

Therefore, we have to ensure that the interrupt status bit is and stays cleared until we actually program the timer.

---
 drivers/char/hpet.c |   15 +++++++++++++++
 1 files changed, 15 insertions(+), 0 deletions(-)
drivers/char/hpet.c +15 -0
index 9ded667..7447ffa 100644
@@ -475,6 +475,21 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp)
 	if (irq) {
 		unsigned long irq_flags;
 
+		if (devp->hd_flags & HPET_SHARED_IRQ) {
+			/*
+			 * To prevent the interrupt handler from seeing an
+			 * unwanted interrupt status bit, program the timer
+			 * so that it will not fire in the near future ...
+			 */
+			writel(readl(&timer->hpet_config) & ~Tn_TYPE_CNF_MASK,
+			       &timer->hpet_config);
+			write_counter(read_counter(&hpet->hpet_mc),
+				      &timer->hpet_compare);
+			/* ... and clear any left-over status. */
+			isr = 1 << (devp - devp->hd_hpets->hp_dev);
+			writel(isr, &hpet->hpet_isr);
+		}
+
 		sprintf(devp->hd_name, "hpet%d", (int)(devp - hpetp->hp_dev));
 		irq_flags = devp->hd_flags & HPET_SHARED_IRQ
 						? IRQF_SHARED : IRQF_DISABLED;
Signature · 1 line
1.7.4.4
#30 lore raw

PATCH 30/209 hpet: unmap unused I/O space

In reply to Paul Gortmaker

From: Jiri Slaby <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit a56d5318716d120e040294bb258901ba89fb9c90 upstream.

When the initialization code in hpet finds a memory resource and does not find an IRQ, it does not unmap the memory resource previously mapped.

There are buggy BIOSes which report resources exactly like this and what is worse the memory region bases point to normal RAM. This normally would not matter since the space is not touched. But when PAT is turned on, ioremap causes the page to be uncached and sets this bit in page->flags.

Then when the page is about to be used by the allocator, it is reported as:

BUG: Bad page state in process md5sum  pfn:3ed00
page:ffffea0000dbd800 count:0 mapcount:0 mapping:(null) index:0x0
page flags: 0x20000001000000(uncached)
Pid: 7956, comm: md5sum Not tainted 2.6.34-12-desktop #1
Call Trace:
 [<ffffffff810df851>] bad_page+0xb1/0x100
 [<ffffffff810dfa45>] prep_new_page+0x1a5/0x1c0
 [<ffffffff810dfe01>] get_page_from_freelist+0x3a1/0x640
 [<ffffffff810e01af>] __alloc_pages_nodemask+0x10f/0x6b0

...

In this particular case:

1) HPET returns 3ed00000 as memory region base, but it is not in reserved ranges reported by the BIOS (excerpt):
BIOS-e820: 0000000000100000 - 00000000af6cf000 (usable)
BIOS-e820: 00000000af6cf000 - 00000000afdcf000 (reserved)

2) there is no IRQ resource reported by HPET method. On the other hand, the Intel HPET specs (1.0a) says (3.2.5.1):
_CRS (
// Report 1K of memory consumed by this Timer Block memory range consumed
// Optional: only used if BIOS allocates Interrupts [1] IRQs consumed
)

[1] For case where Timer Block is configured to consume IRQ0/IRQ8 AND Legacy 8254/Legacy RTC hardware still exists, the device objects associated with 8254 & RTC devices should not report IRQ0/IRQ8 as "consumed resources".

So in theory we should check whether if it is the case and use those interrupts instead.

Anyway the address reported by the BIOS here is bogus, so non-presence of IRQ doesn't mean the "optional" part in point 2).

Since I got no reply previously, fix this by simply unmapping the space when IRQ is not found and memory region was mapped previously. It would be probably more safe to walk the resources again and unmap appropriately depending on type. But as we now use only ioremap for both 2 memory resource types, it is not necessarily needed right now.

Addresses https://bugzilla.novell.com/show_bug.cgi?id=629908

---
 drivers/char/hpet.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
drivers/char/hpet.c +2 -0
index 7447ffa..1716177 100644
@@ -981,6 +981,8 @@ static int hpet_acpi_add(struct acpi_device *device)
 		return -ENODEV;
 
 	if (!data.hd_address || !data.hd_nirqs) {
+		if (data.hd_address)
+			iounmap(data.hd_address);
 		printk("%s: no address or irqs in _CRS\n", __func__);
 		return -ENODEV;
 	}
Signature · 1 line
1.7.4.4
#31 lore raw

PATCH 31/209 olpc_battery: Fix endian neutral breakage for s16 values

In reply to Paul Gortmaker

From: Richard A. Smith <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 7cfbb29466633e6ecdc14f76a693c8478c2b22af upstream.

When the driver was updated to be endian neutral (8e9c7716c) the signed part of the s16 values was lost. This is because be16_to_cpu() returns an unsigned value. This patch casts the values back to a s16 number prior to the the implicit cast up to an int.

---
 drivers/power/olpc_battery.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)
drivers/power/olpc_battery.c +4 -4
index 8fefe5a..4b38eaa 100644
@@ -271,14 +271,14 @@ static int olpc_bat_get_property(struct power_supply *psy,
 		if (ret)
 			return ret;
 
-		val->intval = (int)be16_to_cpu(ec_word) * 9760L / 32;
+		val->intval = (s16)be16_to_cpu(ec_word) * 9760L / 32;
 		break;
 	case POWER_SUPPLY_PROP_CURRENT_AVG:
 		ret = olpc_ec_cmd(EC_BAT_CURRENT, NULL, 0, (void *)&ec_word, 2);
 		if (ret)
 			return ret;
 
-		val->intval = (int)be16_to_cpu(ec_word) * 15625L / 120;
+		val->intval = (s16)be16_to_cpu(ec_word) * 15625L / 120;
 		break;
 	case POWER_SUPPLY_PROP_CAPACITY:
 		ret = olpc_ec_cmd(EC_BAT_SOC, NULL, 0, &ec_byte, 1);
@@ -299,7 +299,7 @@ static int olpc_bat_get_property(struct power_supply *psy,
 		if (ret)
 			return ret;
 
-		val->intval = (int)be16_to_cpu(ec_word) * 100 / 256;
+		val->intval = (s16)be16_to_cpu(ec_word) * 100 / 256;
 		break;
 	case POWER_SUPPLY_PROP_TEMP_AMBIENT:
 		ret = olpc_ec_cmd(EC_AMB_TEMP, NULL, 0, (void *)&ec_word, 2);
@@ -313,7 +313,7 @@ static int olpc_bat_get_property(struct power_supply *psy,
 		if (ret)
 			return ret;
 
-		val->intval = (int)be16_to_cpu(ec_word) * 6250 / 15;
+		val->intval = (s16)be16_to_cpu(ec_word) * 6250 / 15;
 		break;
 	case POWER_SUPPLY_PROP_SERIAL_NUMBER:
 		ret = olpc_ec_cmd(EC_BAT_SERIAL, NULL, 0, (void *)&ser_buf, 8);
Signature · 1 line
1.7.4.4
#32 lore raw

PATCH 32/209 percpu: fix list_head init bug in __percpu_counter_init()

In reply to Paul Gortmaker

From: Masanori ITOH <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 8474b591faf3bb0a1e08a60d21d6baac498f15e4 upstream.

WARNING: at lib/list_debug.c:26 __list_add+0x3f/0x81()
Hardware name: Express5800/B120a [N8400-085]
list_add corruption. next->prev should be prev (ffffffff81a7ea00), but was dead000000200200. (next=ffff88080b872d58).
Modules linked in: aoe ipt_MASQUERADE iptable_nat nf_nat autofs4 sunrpc bridge 8021q garp stp llc ipv6 cpufreq_ondemand acpi_cpufreq freq_table dm_round_robin dm_multipath kvm_intel kvm uinput lpfc scsi_transport_fc igb ioatdma scsi_tgt i2c_i801 i2c_core dca iTCO_wdt iTCO_vendor_support pcspkr shpchp megaraid_sas [last unloaded: aoe]
Pid: 54, comm: events/3 Tainted: G        W  2.6.34-vanilla1 #1
Call Trace:
[<ffffffff8104bd77>] warn_slowpath_common+0x7c/0x94
[<ffffffff8104bde6>] warn_slowpath_fmt+0x41/0x43
[<ffffffff8120fd2e>] __list_add+0x3f/0x81
[<ffffffff81212a12>] __percpu_counter_init+0x59/0x6b
[<ffffffff810d8499>] bdi_init+0x118/0x17e
[<ffffffff811f2c50>] blk_alloc_queue_node+0x79/0x143
[<ffffffff811f2d2b>] blk_alloc_queue+0x11/0x13
[<ffffffffa02a931d>] aoeblk_gdalloc+0x8e/0x1c9 [aoe]
[<ffffffffa02aa655>] aoecmd_sleepwork+0x25/0xa8 [aoe]
[<ffffffff8106186c>] worker_thread+0x1a9/0x237
[<ffffffffa02aa630>] ? aoecmd_sleepwork+0x0/0xa8 [aoe]
[<ffffffff81065827>] ? autoremove_wake_function+0x0/0x39
[<ffffffff810616c3>] ? worker_thread+0x0/0x237
[<ffffffff810653ad>] kthread+0x7f/0x87
[<ffffffff8100aa24>] kernel_thread_helper+0x4/0x10
[<ffffffff8106532e>] ? kthread+0x0/0x87
[<ffffffff8100aa20>] ? kernel_thread_helper+0x0/0x10

It's because there is no initialization code for a list_head contained in the struct backing_dev_info under CONFIG_HOTPLUG_CPU, and the bug comes up when block device drivers calling blk_alloc_queue() are used. In case of me, I got them by using aoe.

---
 lib/percpu_counter.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
lib/percpu_counter.c +1 -0
index aeaa6d7..9d94212 100644
@@ -76,6 +76,7 @@ int __percpu_counter_init(struct percpu_counter *fbc, s64 amount,
 	if (!fbc->counters)
 		return -ENOMEM;
 #ifdef CONFIG_HOTPLUG_CPU
+	INIT_LIST_HEAD(&fbc->list);
 	mutex_lock(&percpu_counters_lock);
 	list_add(&fbc->list, &percpu_counters);
 	mutex_unlock(&percpu_counters_lock);
Signature · 1 line
1.7.4.4
#33 lore raw

PATCH 33/209 um: remove PAGE_SIZE alignment in linker script causing kernel segfault.

In reply to Paul Gortmaker

From: Richard Weinberger <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 6915e04f8847bea16d0890f559694ad8eedd026c upstream.

The linker script cleanup that I did in commit 5d150a97f93 ("um: Clean up linker script using standard macros.") (2.6.32) accidentally introduced an ALIGN(PAGE_SIZE) when converting to use INIT_TEXT_SECTION; Richard Weinberger reported that this causes the kernel to segfault with CONFIG_STATIC_LINK=y.

I'm not certain why this extra alignment is a problem, but it seems likely it is because previously

__init_begin = _stext = _text = _sinittext

and with the extra ALIGN(PAGE_SIZE), _sinittext becomes different from the rest. So there is likely a bug here where something is assuming that _sinittext is the same as one of those other symbols. But reverting the accidental change fixes the regression, so it seems worth committing that now.

Tested by: Antoine Martin <[email protected]>

---
 arch/um/kernel/uml.lds.S |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
arch/um/kernel/uml.lds.S +1 -1
index e7a6cca..664f942 100644
@@ -22,7 +22,7 @@ SECTIONS
   _text = .;
   _stext = .;
   __init_begin = .;
-  INIT_TEXT_SECTION(PAGE_SIZE)
+  INIT_TEXT_SECTION(0)
   . = ALIGN(PAGE_SIZE);
 
   .text      :
Signature · 1 line
1.7.4.4
#34 lore raw

PATCH 34/209 um: fix global timer issue when using CONFIG_NO_HZ

In reply to Paul Gortmaker

From: Richard Weinberger <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 482db6df1746c4fa7d64a2441d4cb2610249c679 upstream.

This fixes a issue which was introduced by fe2cc53e ("uml: track and make up lost ticks").

timeval_to_ns() returns long long and not int. Due to that UML's timer did not work properlt and caused timer freezes.

---
 arch/um/os-Linux/time.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
arch/um/os-Linux/time.c +1 -1
index dec5678..6e3359d 100644
@@ -60,7 +60,7 @@ static inline long long timeval_to_ns(const struct timeval *tv)
 long long disable_timer(void)
 {
 	struct itimerval time = ((struct itimerval) { { 0, 0 }, { 0, 0 } });
-	int remain, max = UM_NSEC_PER_SEC / UM_HZ;
+	long long remain, max = UM_NSEC_PER_SEC / UM_HZ;
 
 	if (setitimer(ITIMER_VIRTUAL, &time, &time) < 0)
 		printk(UM_KERN_ERR "disable_timer - setitimer failed, "
Signature · 1 line
1.7.4.4
#35 lore raw

PATCH 35/209 numa: fix slab_node(MPOL_BIND)

In reply to Paul Gortmaker

From: Eric Dumazet <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 800416f799e0723635ac2d720ad4449917a1481c upstream.

When a node contains only HighMem memory, slab_node(MPOL_BIND) dereferences a NULL pointer.

[ This code seems to go back all the way to commit 19770b32609b: "mm:
filter based on a nodemask as well as a gfp_mask". Which was back in April 2008, and it got merged into 2.6.26. - Linus ]

Cc Mel Gorman <[email protected]>
Cc Christoph Lameter <[email protected]>
Cc Lee Schermerhorn <[email protected]>
Cc Andrew Morton <[email protected]>
---
 mm/mempolicy.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
mm/mempolicy.c +1 -1
index 08f40a2..c7f53b12 100644
@@ -1509,7 +1509,7 @@ unsigned slab_node(struct mempolicy *policy)
 		(void)first_zones_zonelist(zonelist, highest_zoneidx,
 							&policy->v.nodes,
 							&zone);
-		return zone->node;
+		return zone ? zone->node : numa_node_id();
 	}
 
 	default:
Signature · 1 line
1.7.4.4
#36 lore raw

PATCH 36/209 hwmon: (lm85) Fix ADT7468 frequency table

In reply to Paul Gortmaker

From: Jean Delvare <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit fa7a5797e57d2ed71f9a6fb44f0ae42c2d7b74b7 upstream.

The ADT7468 uses the same frequency table as the ADT7463.

---
 drivers/hwmon/lm85.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
drivers/hwmon/lm85.c +1 -0
index b3841a6..2e8f0c9 100644
@@ -1259,6 +1259,7 @@ static int lm85_probe(struct i2c_client *client,
 	switch (data->type) {
 	case adm1027:
 	case adt7463:
+	case adt7468:
 	case emc6d100:
 	case emc6d102:
 		data->freq_map = adm1027_freq_map;
Signature · 1 line
1.7.4.4
#37 lore raw

PATCH 37/209 mm: fix return value of scan_lru_pages in memory unplug

In reply to Paul Gortmaker

From: KAMEZAWA Hiroyuki <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit f8f72ad5396987e05a42cf7eff826fb2a15ff148 upstream.

scan_lru_pages returns pfn. So, it's type should be "unsigned long" not "int".

Note: I guess this has been work until now because memory hotplug tester's
machine has not very big memory....
physical address < 32bit << PAGE_SHIFT.

---
 mm/memory_hotplug.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
mm/memory_hotplug.c +1 -1
index 91f7c26..a577318 100644
@@ -633,7 +633,7 @@ static int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn)
  * Scanning pfn is much easier than scanning lru list.
  * Scan pfn from start to end and Find LRU page.
  */
-int scan_lru_pages(unsigned long start, unsigned long end)
+unsigned long scan_lru_pages(unsigned long start, unsigned long end)
 {
 	unsigned long pfn;
 	struct page *page;
Signature · 1 line
1.7.4.4
#38 lore raw

PATCH 38/209 mm: fix is_mem_section_removable() page_order BUG_ON check

In reply to Paul Gortmaker

From: KAMEZAWA Hiroyuki <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 572438f9b52236bd8938b1647cc15e027d27ef55 upstream.

page_order() is called by memory hotplug's user interface to check the section is removable or not. (is_mem_section_removable())

It calls page_order() withoug holding zone->lock.
So, even if the caller does

	if (PageBuddy(page))
		ret = page_order(page) ...

The caller may hit BUG_ON().

For fixing this, there are 2 choices.
1. add zone->lock.
2. remove BUG_ON().

is_mem_section_removable() is used for some "advice" and doesn't need to be 100% accurate. This is_removable() can be called via user program.. We don't want to take this important lock for long by user's request. So, this patch removes BUG_ON().

---
 mm/internal.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
mm/internal.h +1 -1
index 6a697bb..dedb0af 100644
@@ -62,7 +62,7 @@ extern bool is_free_buddy_page(struct page *page);
  */
 static inline unsigned long page_order(struct page *page)
 {
-	VM_BUG_ON(!PageBuddy(page));
+	/* PageBuddy() must be checked by the caller */
 	return page_private(page);
 }
 
Signature · 1 line
1.7.4.4
#39 lore raw

PATCH 39/209 ssb: b43-pci-bridge: Add new vendor for BCM4318

In reply to Paul Gortmaker

From: Daniel Klaffenbach <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 1d8638d4038eb8709edc80e37a0bbb77253d86e9 upstream.

Add new vendor for Broadcom 4318.

---
 drivers/ssb/b43_pci_bridge.c |    1 +
 include/linux/pci_ids.h      |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)
drivers/ssb/b43_pci_bridge.c +1 -0
index ef9c6a0..744d3f6 100644
@@ -24,6 +24,7 @@ static const struct pci_device_id b43_pci_bridge_tbl[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4312) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4315) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4318) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_BCM_GVC,  0x4318) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4319) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4320) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4321) },
include/linux/pci_ids.h +1 -0
index 829ac3f..32aa93d 100644
@@ -2038,6 +2038,7 @@
 #define PCI_DEVICE_ID_AFAVLAB_P030	0x2182
 #define PCI_SUBDEVICE_ID_AFAVLAB_P061		0x2150
 
+#define PCI_VENDOR_ID_BCM_GVC          0x14a4
 #define PCI_VENDOR_ID_BROADCOM		0x14e4
 #define PCI_DEVICE_ID_TIGON3_5752	0x1600
 #define PCI_DEVICE_ID_TIGON3_5752M	0x1601
Signature · 1 line
1.7.4.4
#40 lore raw

PATCH 40/209 sgi-xpc: XPC fails to discover partitions with all nasids above 128

In reply to Paul Gortmaker

From: [email protected] <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit c22c7aeff69796f46ae0fcec141538e28f50b24e upstream.

UV hardware defines 256 memory protection regions versus the baseline 64 with increasing size for the SN2 ia64. This was overlooked when XPC was modified to accomodate both UV and SN2.

Without this patch, a user could reconfigure their existing system and suddenly disable cross-partition communications with no indication of what has gone wrong. It also prevents larger configurations from using cross-partition communication.

---
 drivers/misc/sgi-xp/xpc_partition.c |   25 +++++++++++++++----------
 1 files changed, 15 insertions(+), 10 deletions(-)
drivers/misc/sgi-xp/xpc_partition.c +15 -10
index d551f09..6956f7e 100644
@@ -439,18 +439,23 @@ xpc_discovery(void)
 	 * nodes that can comprise an access protection grouping. The access
 	 * protection is in regards to memory, IOI and IPI.
 	 */
-	max_regions = 64;
 	region_size = xp_region_size;
 
-	switch (region_size) {
-	case 128:
-		max_regions *= 2;
-	case 64:
-		max_regions *= 2;
-	case 32:
-		max_regions *= 2;
-		region_size = 16;
-		DBUG_ON(!is_shub2());
+	if (is_uv())
+		max_regions = 256;
+	else {
+		max_regions = 64;
+
+		switch (region_size) {
+		case 128:
+			max_regions *= 2;
+		case 64:
+			max_regions *= 2;
+		case 32:
+			max_regions *= 2;
+			region_size = 16;
+			DBUG_ON(!is_shub2());
+		}
 	}
 
 	for (region = 0; region < max_regions; region++) {
Signature · 1 line
1.7.4.4
#41 lore raw

PATCH 41/209 xen: ensure that all event channels start off bound to VCPU 0

In reply to Paul Gortmaker

From: Ian Campbell <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit b0097adeec27e30223c989561ab0f7aa60d1fe93 upstream.

All event channels startbound to VCPU 0 so ensure that cpu_evtchn_mask is initialised to reflect this. Otherwise there is a race after registering an event channel but before the affinity is explicitly set where the event channel can be delivered. If this happens then the event channel remains pending in the L1 (evtchn_pending) array but is cleared in L2 (evtchn_pending_sel), this means the event channel cannot be reraised until another event channel happens to trigger the same L2 entry on that VCPU.

sizeof(cpu_evtchn_mask(0))==sizeof(unsigned long*) which is not correct, and causes only the first 32 or 64 event channels (depending on architecture) to be initially bound to VCPU0. Use sizeof(struct cpu_evtchn_s) instead.

---
 drivers/xen/events.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/xen/events.c +1 -1
index 6830a4d..0769108 100644
@@ -256,7 +256,7 @@ static void init_evtchn_cpu_bindings(void)
 	}
 #endif
 
-	memset(cpu_evtchn_mask(0), ~0, sizeof(cpu_evtchn_mask(0)));
+	memset(cpu_evtchn_mask(0), ~0, sizeof(struct cpu_evtchn_s));
 }
 
 static inline void clear_evtchn(int port)
Signature · 1 line
1.7.4.4
#42 lore raw

PATCH 42/209 xen: don't bother to stop other cpus on shutdown/reboot

In reply to Paul Gortmaker

From: Jeremy Fitzhardinge <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 31e323cca9d5c8afd372976c35a5d46192f540d1 upstream.

Xen will shoot all the VCPUs when we do a shutdown hypercall, so there's no need to do it manually.

In any case it will fail because all the IPI irqs have been pulled down by this point, so the cross-CPU calls will simply hang forever.

Until change 76fac077db6b34e2c6383a7b4f3f4f7b7d06d8ce the function calls were not synchronously waited for, so this wasn't apparent. However after that change the calls became synchronous leading to a hang on shutdown on multi-VCPU guests.

---
 arch/x86/xen/enlighten.c |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)
arch/x86/xen/enlighten.c +0 -4
index 4d32089..25d787c 100644
@@ -1000,10 +1000,6 @@ static void xen_reboot(int reason)
 {
 	struct sched_shutdown r = { .reason = reason };
 
-#ifdef CONFIG_SMP
-	stop_other_cpus();
-#endif
-
 	if (HYPERVISOR_sched_op(SCHEDOP_shutdown, &r))
 		BUG();
 }
Signature · 1 line
1.7.4.4
#43 lore raw

PATCH 43/209 ipc: initialize structure memory to zero for compat functions

In reply to Paul Gortmaker

From: Dan Rosenberg <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 03145beb455cf5c20a761e8451e30b8a74ba58d9 upstream.

This takes care of leaking uninitialized kernel stack memory to userspace from non-zeroed fields in structs in compat ipc functions.

---
 ipc/compat.c    |    6 ++++++
 ipc/compat_mq.c |    5 +++++
 2 files changed, 11 insertions(+), 0 deletions(-)
ipc/compat.c +6 -0
index 9dc2c7d..845a287 100644
@@ -241,6 +241,8 @@ long compat_sys_semctl(int first, int second, int third, void __user *uptr)
 	struct semid64_ds __user *up64;
 	int version = compat_ipc_parse_version(&third);
 
+	memset(&s64, 0, sizeof(s64));
+
 	if (!uptr)
 		return -EINVAL;
 	if (get_user(pad, (u32 __user *) uptr))
@@ -421,6 +423,8 @@ long compat_sys_msgctl(int first, int second, void __user *uptr)
 	int version = compat_ipc_parse_version(&second);
 	void __user *p;
 
+	memset(&m64, 0, sizeof(m64));
+
 	switch (second & (~IPC_64)) {
 	case IPC_INFO:
 	case IPC_RMID:
@@ -594,6 +598,8 @@ long compat_sys_shmctl(int first, int second, void __user *uptr)
 	int err, err2;
 	int version = compat_ipc_parse_version(&second);
 
+	memset(&s64, 0, sizeof(s64));
+
 	switch (second & (~IPC_64)) {
 	case IPC_RMID:
 	case SHM_LOCK:
ipc/compat_mq.c +5 -0
index d8d1e9f..380ea4f 100644
@@ -53,6 +53,9 @@ asmlinkage long compat_sys_mq_open(const char __user *u_name,
 	void __user *p = NULL;
 	if (u_attr && oflag & O_CREAT) {
 		struct mq_attr attr;
+
+		memset(&attr, 0, sizeof(attr));
+
 		p = compat_alloc_user_space(sizeof(attr));
 		if (get_compat_mq_attr(&attr, u_attr) ||
 		    copy_to_user(p, &attr, sizeof(attr)))
@@ -127,6 +130,8 @@ asmlinkage long compat_sys_mq_getsetattr(mqd_t mqdes,
 	struct mq_attr __user *p = compat_alloc_user_space(2 * sizeof(*p));
 	long ret;
 
+	memset(&mqstat, 0, sizeof(mqstat));
+
 	if (u_mqstat) {
 		if (get_compat_mq_attr(&mqstat, u_mqstat) ||
 		    copy_to_user(p, &mqstat, sizeof(mqstat)))
Signature · 1 line
1.7.4.4
#44 lore raw

PATCH 44/209 ipc: shm: fix information leak to userland

In reply to Paul Gortmaker

From: Vasiliy Kulikov <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 3af54c9bd9e6f14f896aac1bb0e8405ae0bc7a44 upstream.

The shmid_ds structure is copied to userland with shm_unused{,2,3} fields unitialized. It leads to leaking of contents of kernel stack memory.

---
 ipc/shm.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
ipc/shm.c +1 -0
index 1a314c8..2225a77 100644
@@ -476,6 +476,7 @@ static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_
 	    {
 		struct shmid_ds out;
 
+		memset(&out, 0, sizeof(out));
 		ipc64_perm_to_ipc_perm(&in->shm_perm, &out.shm_perm);
 		out.shm_segsz	= in->shm_segsz;
 		out.shm_atime	= in->shm_atime;
Signature · 1 line
1.7.4.4
#45 lore raw

PATCH 45/209 sys_semctl: fix kernel stack leakage

In reply to Paul Gortmaker

From: Dan Rosenberg <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 982f7c2b2e6a28f8f266e075d92e19c0dd4c6e56 upstream.

The semctl syscall has several code paths that lead to the leakage of uninitialized kernel stack memory (namely the IPC_INFO, SEM_INFO, IPC_STAT, and SEM_STAT commands) during the use of the older, obsolete version of the semid_ds struct.

The copy_semid_to_user() function declares a semid_ds struct on the stack and copies it back to the user without initializing or zeroing the "sem_base", "sem_pending", "sem_pending_last", and "undo" pointers, allowing the leakage of 16 bytes of kernel stack memory.

The code is still reachable on 32-bit systems - when calling semctl() newer glibc's automatically OR the IPC command with the IPC_64 flag, but invoking the syscall directly allows users to use the older versions of the struct.

---
 ipc/sem.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
ipc/sem.c +2 -0
index dbef95b..b4c1641 100644
@@ -608,6 +608,8 @@ static unsigned long copy_semid_to_user(void __user *buf, struct semid64_ds *in,
 	    {
 		struct semid_ds out;
 
+		memset(&out, 0, sizeof(out));
+
 		ipc64_perm_to_ipc_perm(&in->sem_perm, &out.sem_perm);
 
 		out.sem_otime	= in->sem_otime;
Signature · 1 line
1.7.4.4
#46 lore raw

PATCH 46/209 net: NETIF_F_HW_CSUM does not imply FCoE CRC offload

In reply to Paul Gortmaker

From: Ben Hutchings <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 66c68bcc489fadd4f5e8839e966e3a366e50d1d5 upstream.

NETIF_F_HW_CSUM indicates the ability to update an TCP/IP-style 16-bit checksum with the checksum of an arbitrary part of the packet data, whereas the FCoE CRC is something entirely different.

---
 net/core/dev.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)
net/core/dev.c +3 -3
index 740e71f..f664177 100644
@@ -1610,10 +1610,10 @@ EXPORT_SYMBOL(netif_device_attach);
 
 static bool can_checksum_protocol(unsigned long features, __be16 protocol)
 {
-	return ((features & NETIF_F_GEN_CSUM) ||
-		((features & NETIF_F_IP_CSUM) &&
+	return ((features & NETIF_F_NO_CSUM) ||
+		((features & NETIF_F_V4_CSUM) &&
 		 protocol == htons(ETH_P_IP)) ||
-		((features & NETIF_F_IPV6_CSUM) &&
+		((features & NETIF_F_V6_CSUM) &&
 		 protocol == htons(ETH_P_IPV6)) ||
 		((features & NETIF_F_FCOE_CRC) &&
 		 protocol == htons(ETH_P_FCOE)));
Signature · 1 line
1.7.4.4
#47 lore raw

PATCH 47/209 drivers/char/vt_ioctl.c: fix VT_OPENQRY error value

In reply to Paul Gortmaker

From: Graham Gower <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 1e0ad2881d50becaeea70ec696a80afeadf944d2 upstream.

When all VT's are in use, VT_OPENQRY casts -1 to unsigned char before returning it to userspace as an int. VT255 is not the next available console.

---
 drivers/char/vt_ioctl.c |   11 ++++++-----
 1 files changed, 6 insertions(+), 5 deletions(-)
drivers/char/vt_ioctl.c +6 -5
index 6aa1028..6351a26 100644
@@ -503,6 +503,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
 	struct kbd_struct * kbd;
 	unsigned int console;
 	unsigned char ucval;
+	unsigned int uival;
 	void __user *up = (void __user *)arg;
 	int i, perm;
 	int ret = 0;
@@ -657,7 +658,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
 		break;
 
 	case KDGETMODE:
-		ucval = vc->vc_mode;
+		uival = vc->vc_mode;
 		goto setint;
 
 	case KDMAPDISP:
@@ -695,7 +696,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
 		break;
 
 	case KDGKBMODE:
-		ucval = ((kbd->kbdmode == VC_RAW) ? K_RAW :
+		uival = ((kbd->kbdmode == VC_RAW) ? K_RAW :
 				 (kbd->kbdmode == VC_MEDIUMRAW) ? K_MEDIUMRAW :
 				 (kbd->kbdmode == VC_UNICODE) ? K_UNICODE :
 				 K_XLATE);
@@ -717,9 +718,9 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
 		break;
 
 	case KDGKBMETA:
-		ucval = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT);
+		uival = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT);
 	setint:
-		ret = put_user(ucval, (int __user *)arg);
+		ret = put_user(uival, (int __user *)arg);
 		break;
 
 	case KDGETKEYCODE:
@@ -949,7 +950,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
 		for (i = 0; i < MAX_NR_CONSOLES; ++i)
 			if (! VT_IS_IN_USE(i))
 				break;
-		ucval = i < MAX_NR_CONSOLES ? (i+1) : -1;
+		uival = i < MAX_NR_CONSOLES ? (i+1) : -1;
 		goto setint;		 
 
 	/*
Signature · 1 line
1.7.4.4
#48 lore raw

PATCH 48/209 viafb: use proper register for colour when doing fill ops

In reply to Paul Gortmaker

From: Florian Tobias Schandinat <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit efd4f6398dc92b5bf392670df862f42a19f34cf2 upstream.

The colour was written to a wrong register for fillrect operations. This sometimes caused empty console space (for example after 'clear') to have a different colour than desired. Fix this by writing to the correct register.
Many thanks to Daniel Drake and Jon Nettleton for pointing out this issue and pointing me in the right direction for the fix.

Fixes http://dev.laptop.org/ticket/9323

---
 drivers/video/via/accel.c |    7 ++++---
 1 files changed, 4 insertions(+), 3 deletions(-)
drivers/video/via/accel.c +4 -3
index d5077df..4400f91 100644
@@ -277,11 +277,12 @@ static int hw_bitblt_2(void __iomem *engine, u8 op, u32 width, u32 height,
 		writel(tmp, engine + 0x1C);
 	}
 
-	if (op != VIA_BITBLT_COLOR)
+	if (op == VIA_BITBLT_FILL) {
+		writel(fg_color, engine + 0x58);
+	} else if (op == VIA_BITBLT_MONO) {
 		writel(fg_color, engine + 0x4C);
-
-	if (op == VIA_BITBLT_MONO)
 		writel(bg_color, engine + 0x50);
+	}
 
 	if (op == VIA_BITBLT_FILL)
 		ge_cmd |= fill_rop << 24 | 0x00002000 | 0x00000001;
Signature · 1 line
1.7.4.4
#49 lore raw

PATCH 49/209 eCryptfs: Clear LOOKUP_OPEN flag when creating lower file

In reply to Paul Gortmaker

From: Tyler Hicks <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 2e21b3f124eceb6ab5a07c8a061adce14ac94e14 upstream.

eCryptfs was passing the LOOKUP_OPEN flag through to the lower file system, even though ecryptfs_create() doesn't support the flag. A valid filp for the lower filesystem could be returned in the nameidata if the lower file system's create() function supported LOOKUP_OPEN, possibly resulting in unencrypted writes to the lower file.

However, this is only a potential problem in filesystems (FUSE, NFS, CIFS, CEPH, 9p) that eCryptfs isn't known to support today.

https://bugs.launchpad.net/ecryptfs/+bug/641703

Reported-by Kevin Buhr
---
 fs/ecryptfs/inode.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)
fs/ecryptfs/inode.c +4 -0
index 21801ee..31c8b2f 100644
@@ -70,15 +70,19 @@ ecryptfs_create_underlying_file(struct inode *lower_dir_inode,
 	struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
 	struct dentry *dentry_save;
 	struct vfsmount *vfsmount_save;
+	unsigned int flags_save;
 	int rc;
 
 	dentry_save = nd->path.dentry;
 	vfsmount_save = nd->path.mnt;
+	flags_save = nd->flags;
 	nd->path.dentry = lower_dentry;
 	nd->path.mnt = lower_mnt;
+	nd->flags &= ~LOOKUP_OPEN;
 	rc = vfs_create(lower_dir_inode, lower_dentry, mode, nd);
 	nd->path.dentry = dentry_save;
 	nd->path.mnt = vfsmount_save;
+	nd->flags = flags_save;
 	return rc;
 }
 
Signature · 1 line
1.7.4.4
#50 lore raw

PATCH 50/209 md/raid1: really fix recovery looping when single good device fails.

In reply to Paul Gortmaker

From: NeilBrown <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 8f9e0ee38f75d4740daa9e42c8af628d33d19a02 upstream.

Commit 4044ba58dd15cb01797c4fd034f39ef4a75f7cc3 supposedly fixed a problem where if a raid1 with just one good device gets a read-error during recovery, the recovery would abort and immediately restart in an infinite loop.

However it depended on raid1_remove_disk removing the spare device from the array. But that does not happen in this case. So add a test so that in the 'recovery_disabled' case, the device will be removed.

This suitable for any kernel since 2.6.29 which is when recovery_disabled was introduced.

---
 drivers/md/raid1.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
drivers/md/raid1.c +1 -0
index 52c6b5f..aaa49f1 100644
@@ -1214,6 +1214,7 @@ static int raid1_remove_disk(mddev_t *mddev, int number)
 		 * is not possible.
 		 */
 		if (!test_bit(Faulty, &rdev->flags) &&
+		    !mddev->recovery_disabled &&
 		    mddev->degraded < conf->raid_disks) {
 			err = -EBUSY;
 			goto abort;
Signature · 1 line
1.7.4.4
#51 lore raw

PATCH 51/209 md: fix return value of rdev_size_change()

In reply to Paul Gortmaker

From: Justin Maggard <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit c26a44ed1e552aaa1d4ceb71842002d235fe98d7 upstream.

When trying to grow an array by enlarging component devices, rdev_size_store() expects the return value of rdev_size_change() to be in sectors, but the actual value is returned in KBs.

This functionality was broken by commit

     dd8ac336c13fd8afdb082ebacb1cddd5cf727889

so this patch is suitable for any kernel since 2.6.30.

---
 drivers/md/md.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
drivers/md/md.c +2 -2
index 81c0282..92dbef5 100644
@@ -1260,7 +1260,7 @@ super_90_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors)
 	md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size,
 		       rdev->sb_page);
 	md_super_wait(rdev->mddev);
-	return num_sectors / 2; /* kB for sysfs */
+	return num_sectors;
 }
 
 
@@ -1622,7 +1622,7 @@ super_1_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors)
 	md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size,
 		       rdev->sb_page);
 	md_super_wait(rdev->mddev);
-	return num_sectors / 2; /* kB for sysfs */
+	return num_sectors;
 }
 
 static struct super_type super_types[] = {
Signature · 1 line
1.7.4.4
#52 lore raw

PATCH 52/209 tty: prevent DOS in the flush_to_ldisc

In reply to Paul Gortmaker

From: Jiri Olsa <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit e045fec48970df84647a47930fcf7a22ff7229c0 upstream.

There's a small window inside the flush_to_ldisc function, where the tty is unlocked and calling ldisc's receive_buf function. If in this window new buffer is added to the tty, the processing might never leave the flush_to_ldisc function.

This scenario will hog the cpu, causing other tty processing starving, and making it impossible to interface the computer via tty.

I was able to exploit this via pty interface by sending only control characters to the master input, causing the flush_to_ldisc to be scheduled, but never actually generate any output.

To reproduce, please run multiple instances of following code.

- SNIP
#define _XOPEN_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char **argv)

{
        int i, slave, master = getpt();
        char buf[8192];

        sprintf(buf, "%s", ptsname(master));
        grantpt(master);
        unlockpt(master);

        slave = open(buf, O_RDWR);
        if (slave < 0) {
                perror("open slave failed");
                return 1;
        }

        for(i = 0; i < sizeof(buf); i++)
                buf[i] = rand() % 32;

        while(1) {
                write(master, buf, sizeof(buf));
        }

        return 0;
}

- SNIP

The attached patch (based on -next tree) fixes this by checking on the tty buffer tail. Once it's reached, the current work is rescheduled and another could run.

---
 drivers/char/tty_buffer.c |   14 ++++++++++++--
 1 files changed, 12 insertions(+), 2 deletions(-)
drivers/char/tty_buffer.c +12 -2
index 7ee5216..b370629 100644
@@ -413,7 +413,8 @@ static void flush_to_ldisc(struct work_struct *work)
 	spin_lock_irqsave(&tty->buf.lock, flags);
 
 	if (!test_and_set_bit(TTY_FLUSHING, &tty->flags)) {
-		struct tty_buffer *head;
+		struct tty_buffer *head, *tail = tty->buf.tail;
+		int seen_tail = 0;
 		while ((head = tty->buf.head) != NULL) {
 			int count;
 			char *char_buf;
@@ -423,6 +424,15 @@ static void flush_to_ldisc(struct work_struct *work)
 			if (!count) {
 				if (head->next == NULL)
 					break;
+				/*
+				  There's a possibility tty might get new buffer
+				  added during the unlock window below. We could
+				  end up spinning in here forever hogging the CPU
+				  completely. To avoid this let's have a rest each
+				  time we processed the tail buffer.
+				*/
+				if (tail == head)
+					seen_tail = 1;
 				tty->buf.head = head->next;
 				tty_buffer_free(tty, head);
 				continue;
@@ -432,7 +442,7 @@ static void flush_to_ldisc(struct work_struct *work)
 			   line discipline as we want to empty the queue */
 			if (test_bit(TTY_FLUSHPENDING, &tty->flags))
 				break;
-			if (!tty->receive_room) {
+			if (!tty->receive_room || seen_tail) {
 				schedule_delayed_work(&tty->buf.work, 1);
 				break;
 			}
Signature · 1 line
1.7.4.4
#53 lore raw

PATCH 53/209 TTY: restore tty_ldisc_wait_idle

In reply to Paul Gortmaker

From: Jiri Slaby <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 100eeae2c5ce23b4db93ff320ee330ef1d740151 upstream.

It was removed in 65b770468e98 (tty-ldisc: turn ldisc user count into a proper refcount), but we need to wait for last user to quit the ldisc before we close it in tty_set_ldisc.

Otherwise weird things start to happen. There might be processes waiting in tty_read->n_tty_read on tty->read_wait for input to appear and at that moment, a change of ldisc is fatal. n_tty_close is called, it frees read_buf and the waiting process is still in the middle of reading and goes nuts after it is woken.

Previously we prevented close to happen when others are in ldisc ops by tty_ldisc_wait_idle in tty_set_ldisc. But the commit above removed that. So revoke the change and test whether there is 1 user (=we), and allow the close then.

We can do that without ldisc/tty locks, because nobody else can open the device due to TTY_LDISC_CHANGING bit set, so we in fact wait for everybody to leave.

I don't understand why tty_ldisc_lock would be needed either when the counter is an atomic variable, so this is a lockless tty_ldisc_wait_idle.

On the other hand, if we fail to wait (timeout or signal), we have to reenable the halted ldiscs, so we take ldisc lock and reuse the setup path at the end of tty_set_ldisc.

LKML-Reference: <[email protected]>
LKML-Reference: <[email protected]>

---
 drivers/char/tty_ldisc.c |   29 +++++++++++++++++++++++++++++
 1 files changed, 29 insertions(+), 0 deletions(-)
drivers/char/tty_ldisc.c +29 -0
index 500e740..df5e7db 100644
@@ -47,6 +47,7 @@
 
 static DEFINE_SPINLOCK(tty_ldisc_lock);
 static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait);
+static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_idle);
 /* Line disc dispatch table */
 static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS];
 
@@ -83,6 +84,7 @@ static void put_ldisc(struct tty_ldisc *ld)
 		return;
 	}
 	local_irq_restore(flags);
+	wake_up(&tty_ldisc_idle);
 }
 
 /**
@@ -530,6 +532,23 @@ static int tty_ldisc_halt(struct tty_struct *tty)
 }
 
 /**
+ *	tty_ldisc_wait_idle	-	wait for the ldisc to become idle
+ *	@tty: tty to wait for
+ *
+ *	Wait for the line discipline to become idle. The discipline must
+ *	have been halted for this to guarantee it remains idle.
+ */
+static int tty_ldisc_wait_idle(struct tty_struct *tty)
+{
+	int ret;
+	ret = wait_event_interruptible_timeout(tty_ldisc_idle,
+			atomic_read(&tty->ldisc->users) == 1, 5 * HZ);
+	if (ret < 0)
+		return ret;
+	return ret > 0 ? 0 : -EBUSY;
+}
+
+/**
  *	tty_set_ldisc		-	set line discipline
  *	@tty: the terminal to set
  *	@ldisc: the line discipline
@@ -632,8 +651,17 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
 
 	flush_scheduled_work();
 
+	retval = tty_ldisc_wait_idle(tty);
+
 	mutex_lock(&tty->ldisc_mutex);
 	lock_kernel();
+
+	/* handle wait idle failure locked */
+	if (retval) {
+		tty_ldisc_put(new_ldisc);
+		goto enable;
+	}
+
 	if (test_bit(TTY_HUPPED, &tty->flags)) {
 		/* We were raced by the hangup method. It will have stomped
 		   the ldisc data and closed the ldisc down */
@@ -667,6 +695,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
 
 	tty_ldisc_put(o_ldisc);
 
+enable:
 	/*
 	 *	Allow ldisc referencing to occur again
 	 */
Signature · 1 line
1.7.4.4
#54 lore raw

PATCH 54/209 tty_ldisc: Fix BUG() on hangup

In reply to Paul Gortmaker

From: Philippe Rétornaz <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 1c95ba1e1de7edffc0c4e275e147f1a9eb1f81ae upstream.

A kernel BUG when bluetooth rfcomm connection drop while the associated serial port is open is sometime triggered.

It seems that the line discipline can disappear between the tty_ldisc_put and tty_ldisc_get. This patch fall back to the N_TTY line discipline if the previous discipline is not available anymore.

---
 drivers/char/tty_ldisc.c |   20 +++++++++++++-------
 1 files changed, 13 insertions(+), 7 deletions(-)
drivers/char/tty_ldisc.c +13 -7
index df5e7db..7af1a15 100644
@@ -741,9 +741,12 @@ static void tty_reset_termios(struct tty_struct *tty)
  *	state closed
  */
 
-static void tty_ldisc_reinit(struct tty_struct *tty, int ldisc)
+static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc)
 {
-	struct tty_ldisc *ld;
+	struct tty_ldisc *ld = tty_ldisc_get(ldisc);
+
+	if (IS_ERR(ld))
+		return -1;
 
 	tty_ldisc_close(tty, tty->ldisc);
 	tty_ldisc_put(tty->ldisc);
@@ -751,10 +754,10 @@ static void tty_ldisc_reinit(struct tty_struct *tty, int ldisc)
 	/*
 	 *	Switch the line discipline back
 	 */
-	ld = tty_ldisc_get(ldisc);
-	BUG_ON(IS_ERR(ld));
 	tty_ldisc_assign(tty, ld);
 	tty_set_termios_ldisc(tty, ldisc);
+
+	return 0;
 }
 
 /**
@@ -816,13 +819,16 @@ void tty_ldisc_hangup(struct tty_struct *tty)
 	   a FIXME */
 	if (tty->ldisc) {	/* Not yet closed */
 		if (reset == 0) {
-			tty_ldisc_reinit(tty, tty->termios->c_line);
-			err = tty_ldisc_open(tty, tty->ldisc);
+
+			if (!tty_ldisc_reinit(tty, tty->termios->c_line))
+				err = tty_ldisc_open(tty, tty->ldisc);
+			else
+				err = 1;
 		}
 		/* If the re-open fails or we reset then go to N_TTY. The
 		   N_TTY open cannot fail */
 		if (reset || err) {
-			tty_ldisc_reinit(tty, N_TTY);
+			BUG_ON(tty_ldisc_reinit(tty, N_TTY));
 			WARN_ON(tty_ldisc_open(tty, tty->ldisc));
 		}
 		tty_ldisc_enable(tty);
Signature · 1 line
1.7.4.4
#55 lore raw

PATCH 55/209 TTY: ldisc, fix open flag handling

In reply to Paul Gortmaker

From: Jiri Slaby <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 7f90cfc505d613f4faf096e0d84ffe99208057d9 upstream.

When a concrete ldisc open fails in tty_ldisc_open, we forget to clear TTY_LDISC_OPEN. This causes a false warning on the next ldisc open:

WARNING: at drivers/char/tty_ldisc.c:445 tty_ldisc_open+0x26/0x38()
Hardware name: System Product Name
Modules linked in: ...
Pid: 5251, comm: a.out Tainted: G        W  2.6.32-5-686 #1
Call Trace:
 [<c1030321>] ? warn_slowpath_common+0x5e/0x8a
 [<c1030357>] ? warn_slowpath_null+0xa/0xc
 [<c119311c>] ? tty_ldisc_open+0x26/0x38
 [<c11936c5>] ? tty_set_ldisc+0x218/0x304

...

So clear the bit when failing...

Introduced in c65c9bc3efa (tty: rewrite the ldisc locking) back in 2.6.31-rc1.

---
 drivers/char/tty_ldisc.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
drivers/char/tty_ldisc.c +2 -0
index 7af1a15..236628f 100644
@@ -452,6 +452,8 @@ static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld)
                 /* BKL here locks verus a hangup event */
 		lock_kernel();
 		ret = ld->ops->open(tty);
+		if (ret)
+			clear_bit(TTY_LDISC_OPEN, &tty->flags);
 		unlock_kernel();
 		return ret;
 	}
Signature · 1 line
1.7.4.4
#56 lore raw

PATCH 56/209 KVM: x86: fix information leak to userland

In reply to Paul Gortmaker

From: Vasiliy Kulikov <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 97e69aa62f8b5d338d6cff49be09e37cc1262838 upstream.

Structures kvm_vcpu_events, kvm_debugregs, kvm_pit_state2 and kvm_clock_data are copied to userland with some padding and reserved fields unitialized. It leads to leaking of contents of kernel stack memory. We have to initialize them to zero.

In patch v1 Jan Kiszka suggested to fill reserved fields with zeros instead of memset'ting the whole struct. It makes sense as these fields are explicitly marked as padding. No more fields need zeroing.

[PG: 34 doesn't have the dbgregs section to be memset, so drop that bit]

KVM-Stable-Tag.

---
 arch/x86/kvm/x86.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)
arch/x86/kvm/x86.c +5 -0
index 7ea2888..8ced130 100644
@@ -2115,6 +2115,7 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu,
 	events->exception.injected = vcpu->arch.exception.pending;
 	events->exception.nr = vcpu->arch.exception.nr;
 	events->exception.has_error_code = vcpu->arch.exception.has_error_code;
+	events->exception.pad = 0;
 	events->exception.error_code = vcpu->arch.exception.error_code;
 
 	events->interrupt.injected = vcpu->arch.interrupt.pending;
@@ -2124,11 +2125,13 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu,
 	events->nmi.injected = vcpu->arch.nmi_injected;
 	events->nmi.pending = vcpu->arch.nmi_pending;
 	events->nmi.masked = kvm_x86_ops->get_nmi_mask(vcpu);
+	events->nmi.pad = 0;
 
 	events->sipi_vector = vcpu->arch.sipi_vector;
 
 	events->flags = (KVM_VCPUEVENT_VALID_NMI_PENDING
 			 | KVM_VCPUEVENT_VALID_SIPI_VECTOR);
+	memset(&events->reserved, 0, sizeof(events->reserved));
 
 	vcpu_put(vcpu);
 }
@@ -2589,6 +2592,7 @@ static int kvm_vm_ioctl_get_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
 		sizeof(ps->channels));
 	ps->flags = kvm->arch.vpit->pit_state.flags;
 	mutex_unlock(&kvm->arch.vpit->pit_state.lock);
+	memset(&ps->reserved, 0, sizeof(ps->reserved));
 	return r;
 }
 
@@ -2983,6 +2987,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
 		now_ns = timespec_to_ns(&now);
 		user_ns.clock = kvm->arch.kvmclock_offset + now_ns;
 		user_ns.flags = 0;
+		memset(&user_ns.pad, 0, sizeof(user_ns.pad));
 
 		r = -EFAULT;
 		if (copy_to_user(argp, &user_ns, sizeof(user_ns)))
Signature · 1 line
1.7.4.4
#57 lore raw

PATCH 57/209 KVM: VMX: Fix host userspace gsbase corruption

In reply to Paul Gortmaker

From: Avi Kivity <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit c8770e7ba63bb5dd8fe5f9d251275a8fa717fb78 upstream.

We now use load_gs_index() to load gs safely; unfortunately this also changes MSR_KERNEL_GS_BASE, which we managed separately. This resulted in confusion and breakage running 32-bit host userspace on a 64-bit kernel.

Fix by
- saving guest MSR_KERNEL_GS_BASE before we we reload the host's gs
- doing the host save/load unconditionally, instead of only when in guest long mode

Things can be cleaned up further, but this is the minmal fix for now.

---
 arch/x86/kvm/vmx.c |   15 +++++++--------
 1 files changed, 7 insertions(+), 8 deletions(-)
arch/x86/kvm/vmx.c +7 -8
index 2cfa656..a25a345 100644
@@ -676,10 +676,9 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu)
 #endif
 
 #ifdef CONFIG_X86_64
-	if (is_long_mode(&vmx->vcpu)) {
-		rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
+	rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
+	if (is_long_mode(&vmx->vcpu))
 		wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base);
-	}
 #endif
 	for (i = 0; i < vmx->save_nmsrs; ++i)
 		kvm_set_shared_msr(vmx->guest_msrs[i].index,
@@ -694,23 +693,23 @@ static void __vmx_load_host_state(struct vcpu_vmx *vmx)
 
 	++vmx->vcpu.stat.host_state_reload;
 	vmx->host_state.loaded = 0;
+#ifdef CONFIG_X86_64
+	if (is_long_mode(&vmx->vcpu))
+		rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base);
+#endif
 	if (vmx->host_state.fs_reload_needed)
 		loadsegment(fs, vmx->host_state.fs_sel);
 	if (vmx->host_state.gs_ldt_reload_needed) {
 		kvm_load_ldt(vmx->host_state.ldt_sel);
 #ifdef CONFIG_X86_64
 		load_gs_index(vmx->host_state.gs_sel);
-		wrmsrl(MSR_KERNEL_GS_BASE, current->thread.gs);
 #else
 		loadsegment(gs, vmx->host_state.gs_sel);
 #endif
 	}
 	reload_tss();
 #ifdef CONFIG_X86_64
-	if (is_long_mode(&vmx->vcpu)) {
-		rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base);
-		wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
-	}
+	wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
 #endif
 	load_gdt(&__get_cpu_var(host_gdt));
 }
Signature · 1 line
1.7.4.4
#58 lore raw

PATCH 58/209 firewire: ohci: fix buffer overflow in AR split packet handling

In reply to Paul Gortmaker

From: Clemens Ladisch <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 85f7ffd5d2b320f73912b15fe8cef34bae297daf upstream.

When the controller had to split a received asynchronous packet into two buffers, the driver tries to reassemble it by copying both parts into the first page. However, if size + rest > PAGE_SIZE, i.e., if the yet unhandled packets before the split packet, the split packet itself, and any received packets after the split packet are together larger than one page, then the memory after the first page would get overwritten.

To fix this, do not try to copy the data of all unhandled packets at once, but copy the possibly needed data every time when handling a packet.

This gets rid of most of the infamous crashes and data corruptions when using firewire-net.

---
 drivers/firewire/ohci.c |   35 ++++++++++++++++++++++++++++++++---
 1 files changed, 32 insertions(+), 3 deletions(-)
drivers/firewire/ohci.c +32 -3
index 94b16e0..b1b0281 100644
@@ -636,7 +636,7 @@ static void ar_context_tasklet(unsigned long data)
 	d = &ab->descriptor;
 
 	if (d->res_count == 0) {
-		size_t size, rest, offset;
+		size_t size, size2, rest, pktsize, size3, offset;
 		dma_addr_t start_bus;
 		void *start;
 
@@ -653,12 +653,41 @@ static void ar_context_tasklet(unsigned long data)
 		ab = ab->next;
 		d = &ab->descriptor;
 		size = buffer + PAGE_SIZE - ctx->pointer;
+		/* valid buffer data in the next page */
 		rest = le16_to_cpu(d->req_count) - le16_to_cpu(d->res_count);
+		/* what actually fits in this page */
+		size2 = min(rest, (size_t)PAGE_SIZE - size);
 		memmove(buffer, ctx->pointer, size);
-		memcpy(buffer + size, ab->data, rest);
+		memcpy(buffer + size, ab->data, size2);
 		ctx->current_buffer = ab;
 		ctx->pointer = (void *) ab->data + rest;
-		end = buffer + size + rest;
+
+		while (size > 0) {
+			void *next = handle_ar_packet(ctx, buffer);
+			pktsize = next - buffer;
+			if (pktsize >= size) {
+				/*
+				 * We have handled all the data that was
+				 * originally in this page, so we can now
+				 * continue in the next page.
+				 */
+				buffer = next;
+				break;
+			}
+			/* move the next packet to the start of the buffer */
+			memmove(buffer, next, size + size2 - pktsize);
+			size -= pktsize;
+			/* fill up this page again */
+			size3 = min(rest - size2,
+				    (size_t)PAGE_SIZE - size - size2);
+			memcpy(buffer + size + size2,
+			       (void *) ab->data + size2, size3);
+			size2 += size3;
+		}
+
+		/* handle the packets that are fully in the next page */
+		buffer = (void *) ab->data + (buffer - (start + size));
+		end = (void *) ab->data + rest;
 
 		while (buffer < end)
 			buffer = handle_ar_packet(ctx, buffer);
Signature · 1 line
1.7.4.4
#59 lore raw

PATCH 59/209 firewire: ohci: fix race in AR split packet handling

In reply to Paul Gortmaker

From: Clemens Ladisch <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit a1f805e5e73a8fe166b71c6592d3837df0cd5e2e upstream.

When handling an AR buffer that has been completely filled, we assumed that its descriptor will not be read by the controller and can be overwritten. However, when the last received packet happens to end at the end of the buffer, the controller might not yet have moved on to the next buffer and might read the branch address later. If we overwrite and free the page before that, the DMA context will either go dead because of an invalid Z value, or go off into some random memory.

To fix this, ensure that the descriptor does not get overwritten by using only the actual buffer instead of the entire page for reassembling the split packet. Furthermore, to avoid freeing the page too early, move on to the next buffer only when some data in it guarantees that the controller has moved on.

This should eliminate the remaining firewire-net problems.

---
 drivers/firewire/ohci.c |   35 +++++++++++++++++++++--------------
 1 files changed, 21 insertions(+), 14 deletions(-)
drivers/firewire/ohci.c +21 -14
index b1b0281..3816889 100644
@@ -647,20 +647,19 @@ static void ar_context_tasklet(unsigned long data)
 		 */
 
 		offset = offsetof(struct ar_buffer, data);
-		start = buffer = ab;
+		start = ab;
 		start_bus = le32_to_cpu(ab->descriptor.data_address) - offset;
+		buffer = ab->data;
 
 		ab = ab->next;
 		d = &ab->descriptor;
-		size = buffer + PAGE_SIZE - ctx->pointer;
+		size = start + PAGE_SIZE - ctx->pointer;
 		/* valid buffer data in the next page */
 		rest = le16_to_cpu(d->req_count) - le16_to_cpu(d->res_count);
 		/* what actually fits in this page */
-		size2 = min(rest, (size_t)PAGE_SIZE - size);
+		size2 = min(rest, (size_t)PAGE_SIZE - offset - size);
 		memmove(buffer, ctx->pointer, size);
 		memcpy(buffer + size, ab->data, size2);
-		ctx->current_buffer = ab;
-		ctx->pointer = (void *) ab->data + rest;
 
 		while (size > 0) {
 			void *next = handle_ar_packet(ctx, buffer);
@@ -679,22 +678,30 @@ static void ar_context_tasklet(unsigned long data)
 			size -= pktsize;
 			/* fill up this page again */
 			size3 = min(rest - size2,
-				    (size_t)PAGE_SIZE - size - size2);
+				    (size_t)PAGE_SIZE - offset - size - size2);
 			memcpy(buffer + size + size2,
 			       (void *) ab->data + size2, size3);
 			size2 += size3;
 		}
 
-		/* handle the packets that are fully in the next page */
-		buffer = (void *) ab->data + (buffer - (start + size));
-		end = (void *) ab->data + rest;
+		if (rest > 0) {
+			/* handle the packets that are fully in the next page */
+			buffer = (void *) ab->data +
+					(buffer - (start + offset + size));
+			end = (void *) ab->data + rest;
 
-		while (buffer < end)
-			buffer = handle_ar_packet(ctx, buffer);
+			while (buffer < end)
+				buffer = handle_ar_packet(ctx, buffer);
 
-		dma_free_coherent(ohci->card.device, PAGE_SIZE,
-				  start, start_bus);
-		ar_context_add_page(ctx);
+			ctx->current_buffer = ab;
+			ctx->pointer = end;
+
+			dma_free_coherent(ohci->card.device, PAGE_SIZE,
+					  start, start_bus);
+			ar_context_add_page(ctx);
+		} else {
+			ctx->pointer = start + PAGE_SIZE;
+		}
 	} else {
 		buffer = ctx->pointer;
 		ctx->pointer = end =
Signature · 1 line
1.7.4.4
#60 lore raw

PATCH 60/209 ALSA: ac97: Apply quirk for Dell Latitude D610 binding Master and Headphone controls

In reply to Paul Gortmaker

From: Daniel T Chen <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 0613a59456980161d0cd468bae6c63d772743102 upstream.

The original reporter states: "The Master mixer does not change the volume from the headphone output (which is affected by the headphone mixer). Instead it only seems to control the on-board speaker volume. This confuses PulseAudio greatly as the Master channel is merged into the volume mix."

Fix this symptom by applying the hp_only quirk for the reporter's SSID. The fix is applicable to all stable kernels.

---
 sound/pci/intel8x0.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)
sound/pci/intel8x0.c +6 -0
index 4677492..ebfa1f8 100644
@@ -1866,6 +1866,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
 	},
 	{
 		.subvendor = 0x1028,
+		.subdevice = 0x0182,
+		.name = "Dell Latitude D610",	/* STAC9750/51 */
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
+		.subvendor = 0x1028,
 		.subdevice = 0x0186,
 		.name = "Dell Latitude D810", /* cf. Malone #41015 */
 		.type = AC97_TUNE_HP_MUTE_LED
Signature · 1 line
1.7.4.4
#61 lore raw

PATCH 61/209 ALSA: HDA: Add an extra DAC for Realtek ALC887-VD

In reply to Paul Gortmaker

From: David Henningsson <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit cc1c452e509aefc28f7ad2deed75bc69d4f915f7 upstream.

The patch enables ALC887-VD to use the DAC at nid 0x26, which makes it possible to use this DAC for e g Headphone volume.

---
 sound/pci/hda/patch_realtek.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)
sound/pci/hda/patch_realtek.c +3 -1
index 7b516f1..a1d30d3 100644
@@ -18198,6 +18198,8 @@ static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
 		return 0x02;
 	else if (nid >= 0x0c && nid <= 0x0e)
 		return nid - 0x0c + 0x02;
+	else if (nid == 0x26) /* ALC887-VD has this DAC too */
+		return 0x25;
 	else
 		return 0;
 }
@@ -18206,7 +18208,7 @@ static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
 static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
 				   hda_nid_t dac)
 {
-	hda_nid_t mix[4];
+	hda_nid_t mix[5];
 	int i, num;
 
 	num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
Signature · 1 line
1.7.4.4
#62 lore raw

PATCH 62/209 ALSA: hda: Use "alienware" model quirk for another SSID

In reply to Paul Gortmaker

From: Daniel T Chen <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 0defe09ca70daccdc83abd9c3c24cd89ae6a1141 upstream.

The original reporter states that headphone jacks do not appear to work. Upon inspecting his codec dump, and upon further testing, it is confirmed that the "alienware" model quirk is correct.

Reported-and-tested-by Cody Thierauf
---
 sound/pci/hda/patch_sigmatel.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
sound/pci/hda/patch_sigmatel.c +2 -0
index f1e7bab..6cf2dd4 100644
@@ -1616,6 +1616,8 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
 static struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = {
 	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a1,
 		      "Alienware M17x", STAC_ALIENWARE_M17X),
+	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a,
+		      "Alienware M17x", STAC_ALIENWARE_M17X),
 	{} /* terminator */
 };
 
Signature · 1 line
1.7.4.4
#63 lore raw

PATCH 63/209 netfilter: nf_conntrack: allow nf_ct_alloc_hashtable() to get highmem pages

In reply to Paul Gortmaker

From: Eric Dumazet <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 6b1686a71e3158d3c5f125260effce171cc7852b upstream.

commit ea781f197d6a8 (use SLAB_DESTROY_BY_RCU and get rid of call_rcu()) did a mistake in __vmalloc() call in nf_ct_alloc_hashtable().

I forgot to add __GFP_HIGHMEM, so pages were taken from LOWMEM only.

---
 net/netfilter/nf_conntrack_core.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
net/netfilter/nf_conntrack_core.c +2 -1
index 0c9bbe9..a1af890 100644
@@ -1240,7 +1240,8 @@ void *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced, int nulls)
 	if (!hash) {
 		*vmalloced = 1;
 		printk(KERN_WARNING "nf_conntrack: falling back to vmalloc.\n");
-		hash = __vmalloc(sz, GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL);
+		hash = __vmalloc(sz, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO,
+				 PAGE_KERNEL);
 	}
 
 	if (hash && nulls)
Signature · 1 line
1.7.4.4
#64 lore raw

PATCH 64/209 latencytop: fix per task accumulator

In reply to Paul Gortmaker

From: Ken Chen <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 38715258aa2e8cd94bd4aafadc544e5104efd551 upstream.

Per task latencytop accumulator prematurely terminates due to erroneous placement of latency_record_count. It should be incremented whenever a new record is allocated instead of increment on every latencytop event.

Also fix search iterator to only search known record events instead of blindly searching all pre-allocated space.

---
 kernel/latencytop.c |   17 ++++++++---------
 1 files changed, 8 insertions(+), 9 deletions(-)
kernel/latencytop.c +8 -9
index 877fb30..17110a4 100644
@@ -194,14 +194,7 @@ __account_scheduler_latency(struct task_struct *tsk, int usecs, int inter)
 
 	account_global_scheduler_latency(tsk, &lat);
 
-	/*
-	 * short term hack; if we're > 32 we stop; future we recycle:
-	 */
-	tsk->latency_record_count++;
-	if (tsk->latency_record_count >= LT_SAVECOUNT)
-		goto out_unlock;
-
-	for (i = 0; i < LT_SAVECOUNT; i++) {
+	for (i = 0; i < tsk->latency_record_count; i++) {
 		struct latency_record *mylat;
 		int same = 1;
 
@@ -227,8 +220,14 @@ __account_scheduler_latency(struct task_struct *tsk, int usecs, int inter)
 		}
 	}
 
+	/*
+	 * short term hack; if we're > 32 we stop; future we recycle:
+	 */
+	if (tsk->latency_record_count >= LT_SAVECOUNT)
+		goto out_unlock;
+
 	/* Allocated a new one: */
-	i = tsk->latency_record_count;
+	i = tsk->latency_record_count++;
 	memcpy(&tsk->latency_record[i], &lat, sizeof(struct latency_record));
 
 out_unlock:
Signature · 1 line
1.7.4.4
#65 lore raw

PATCH 65/209 mm/vfs: revalidate page->mapping in do_generic_file_read()

In reply to Paul Gortmaker

From: Dave Hansen <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 8d056cb965b8fb7c53c564abf28b1962d1061cd3 upstream.

70 hours into some stress tests of a 2.6.32-based enterprise kernel, we ran into a NULL dereference in here:

int block_is_partially_uptodate(struct page *page, read_descriptor_t *desc,
unsigned long from)
{
----> struct inode *inode = page->mapping->host;

It looks like page->mapping was the culprit. (xmon trace is below). After closer examination, I realized that do_generic_file_read() does a find_get_page(), and eventually locks the page before calling block_is_partially_uptodate(). However, it doesn't revalidate the page->mapping after the page is locked. So, there's a small window between the find_get_page() and ->is_partially_uptodate() where the page could get truncated and page->mapping cleared.

We _have_ a reference, so it can't get reclaimed, but it certainly can be truncated.

I think the correct thing is to check page->mapping after the trylock_page(), and jump out if it got truncated. This patch has been running in the test environment for a month or so now, and we have not seen this bug pop up again.

xmon info:

1f:mon> e
cpu 0x1f: Vector: 300 (Data Access) at [c0000002ae36f770]

      pc: c0000000001e7a6c: .block_is_partially_uptodate+0xc/0x100
      lr: c000000000142944: .generic_file_aio_read+0x1e4/0x770
      sp: c0000002ae36f9f0
     msr: 8000000000009032
     dar: 0
   dsisr: 40000000
    current = 0xc000000378f99e30
    paca    = 0xc000000000f66300
      pid   = 21946, comm = bash
  1f:mon> r
  R00 = 0025c0500000006d   R16 = 0000000000000000
  R01 = c0000002ae36f9f0   R17 = c000000362cd3af0
  R02 = c000000000e8cd80   R18 = ffffffffffffffff
  R03 = c0000000031d0f88   R19 = 0000000000000001
  R04 = c0000002ae36fa68   R20 = c0000003bb97b8a0
  R05 = 0000000000000000   R21 = c0000002ae36fa68
  R06 = 0000000000000000   R22 = 0000000000000000
  R07 = 0000000000000001   R23 = c0000002ae36fbb0
  R08 = 0000000000000002   R24 = 0000000000000000
  R09 = 0000000000000000   R25 = c000000362cd3a80
  R10 = 0000000000000000   R26 = 0000000000000002
  R11 = c0000000001e7b60   R27 = 0000000000000000
  R12 = 0000000042000484   R28 = 0000000000000001
  R13 = c000000000f66300   R29 = c0000003bb97b9b8
  R14 = 0000000000000001   R30 = c000000000e28a08
  R15 = 000000000000ffff   R31 = c0000000031d0f88
  pc  = c0000000001e7a6c .block_is_partially_uptodate+0xc/0x100
  lr  = c000000000142944 .generic_file_aio_read+0x1e4/0x770
  msr = 8000000000009032   cr  = 22000488
  ctr = c0000000001e7a60   xer = 0000000020000000   trap =  300
  dar = 0000000000000000   dsisr = 40000000
  1f:mon> t
  [link register   ] c000000000142944 .generic_file_aio_read+0x1e4/0x770
  [c0000002ae36f9f0] c000000000142a14 .generic_file_aio_read+0x2b4/0x770 (unreliable)
  [c0000002ae36fb40] c0000000001b03e4 .do_sync_read+0xd4/0x160
  [c0000002ae36fce0] c0000000001b153c .vfs_read+0xec/0x1f0
  [c0000002ae36fd80] c0000000001b1768 .SyS_read+0x58/0xb0
  [c0000002ae36fe30] c00000000000852c syscall_exit+0x0/0x40
  --- Exception: c00 (System Call) at 00000080a840bc54
  SP (fffca15df30) is in userspace
  1f:mon> di c0000000001e7a6c
  c0000000001e7a6c  e9290000      ld      r9,0(r9)
  c0000000001e7a70  418200c0      beq     c0000000001e7b30        # .block_is_partially_uptodate+0xd0/0x100
  c0000000001e7a74  e9440008      ld      r10,8(r4)
  c0000000001e7a78  78a80020      clrldi  r8,r5,32
  c0000000001e7a7c  3c000001      lis     r0,1
  c0000000001e7a80  812900a8      lwz     r9,168(r9)
  c0000000001e7a84  39600001      li      r11,1
  c0000000001e7a88  7c080050      subf    r0,r8,r0
  c0000000001e7a8c  7f805040      cmplw   cr7,r0,r10
  c0000000001e7a90  7d6b4830      slw     r11,r11,r9
  c0000000001e7a94  796b0020      clrldi  r11,r11,32
  c0000000001e7a98  419d00a8      bgt     cr7,c0000000001e7b40    # .block_is_partially_uptodate+0xe0/0x100
  c0000000001e7a9c  7fa55840      cmpld   cr7,r5,r11
  c0000000001e7aa0  7d004214      add     r8,r0,r8
  c0000000001e7aa4  79080020      clrldi  r8,r8,32
  c0000000001e7aa8  419c0078      blt     cr7,c0000000001e7b20    # .block_is_partially_uptodate+0xc0/0x100
---
 mm/filemap.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)
mm/filemap.c +3 -0
index 3760bdc..ffdae5c 100644
@@ -1009,6 +1009,9 @@ find_page:
 				goto page_not_up_to_date;
 			if (!trylock_page(page))
 				goto page_not_up_to_date;
+			/* Did it get truncated before we got the lock? */
+			if (!page->mapping)
+				goto page_not_up_to_date_locked;
 			if (!mapping->a_ops->is_partially_uptodate(page,
 								desc, offset))
 				goto page_not_up_to_date_locked;
Signature · 1 line
1.7.4.4
#66 lore raw

PATCH 66/209 bio: take care not overflow page count when mapping/copying user data

In reply to Paul Gortmaker

From: Jens Axboe <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit cb4644cac4a2797afc847e6c92736664d4b0ea34 upstream.

If the iovec is being set up in a way that causes uaddr + PAGE_SIZE to overflow, we could end up attempting to map a huge number of pages. Check for this invalid input type.

---
 fs/bio.c |   14 +++++++++++++-
 1 files changed, 13 insertions(+), 1 deletions(-)
fs/bio.c +13 -1
index 75ea4c3..b3e0174 100644
@@ -834,6 +834,12 @@ struct bio *bio_copy_user_iov(struct request_queue *q,
 		end = (uaddr + iov[i].iov_len + PAGE_SIZE - 1) >> PAGE_SHIFT;
 		start = uaddr >> PAGE_SHIFT;
 
+		/*
+		 * Overflow, abort
+		 */
+		if (end < start)
+			return ERR_PTR(-EINVAL);
+
 		nr_pages += end - start;
 		len += iov[i].iov_len;
 	}
@@ -961,6 +967,12 @@ static struct bio *__bio_map_user_iov(struct request_queue *q,
 		unsigned long end = (uaddr + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
 		unsigned long start = uaddr >> PAGE_SHIFT;
 
+		/*
+		 * Overflow, abort
+		 */
+		if (end < start)
+			return ERR_PTR(-EINVAL);
+
 		nr_pages += end - start;
 		/*
 		 * buffer must be aligned to at least hardsector size for now
@@ -988,7 +1000,7 @@ static struct bio *__bio_map_user_iov(struct request_queue *q,
 		unsigned long start = uaddr >> PAGE_SHIFT;
 		const int local_nr_pages = end - start;
 		const int page_limit = cur_page + local_nr_pages;
-		
+
 		ret = get_user_pages_fast(uaddr, local_nr_pages,
 				write_to_vm, &pages[cur_page]);
 		if (ret < local_nr_pages) {
Signature · 1 line
1.7.4.4
#67 lore raw

PATCH 67/209 drm/ttm: Clear the ghost cpu_writers flag on ttm_buffer_object_transfer.

In reply to Paul Gortmaker

From: Francisco Jerez <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 0fbecd400dd0a82d465b3086f209681e8c54cb0f upstream.

It makes sense for a BO to move after a process has requested exclusive RW access on it (e.g. because the BO used to be located in unmappable VRAM and we intercepted the CPU access from the fault handler).

If we let the ghost object inherit cpu_writers from the original object, ttm_bo_release_list() will raise a kernel BUG when the ghost object is destroyed. This can be reproduced with the nouveau driver on nv5x.

---
 drivers/gpu/drm/ttm/ttm_bo_util.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
drivers/gpu/drm/ttm/ttm_bo_util.c +1 -0
index d764e82..fe04f8c 100644
@@ -327,6 +327,7 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,
 	INIT_LIST_HEAD(&fbo->lru);
 	INIT_LIST_HEAD(&fbo->swap);
 	fbo->vm_node = NULL;
+	atomic_set(&fbo->cpu_writers, 0);
 
 	fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj);
 	if (fbo->mem.mm_node)
Signature · 1 line
1.7.4.4
#68 lore raw

PATCH 68/209 libata: fix NULL sdev dereference race in atapi_qc_complete()

In reply to Paul Gortmaker

From: Tejun Heo <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 2a5f07b5ec098edc69e05fdd2f35d3fbb1235723 upstream.

SCSI commands may be issued between __scsi_add_device() and dev->sdev assignment, so it's unsafe for ata_qc_complete() to dereference dev->sdev->locked without checking whether it's NULL or not. Fix it.

---
 drivers/ata/libata-scsi.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)
drivers/ata/libata-scsi.c +4 -1
index 0088cde..1d266e2 100644
@@ -2548,8 +2548,11 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
 		 *
 		 * If door lock fails, always clear sdev->locked to
 		 * avoid this infinite loop.
+		 *
+		 * This may happen before SCSI scan is complete.  Make
+		 * sure qc->dev->sdev isn't NULL before dereferencing.
 		 */
-		if (qc->cdb[0] == ALLOW_MEDIUM_REMOVAL)
+		if (qc->cdb[0] == ALLOW_MEDIUM_REMOVAL && qc->dev->sdev)
 			qc->dev->sdev->locked = 0;
 
 		qc->scsicmd->result = SAM_STAT_CHECK_CONDITION;
Signature · 1 line
1.7.4.4
#69 lore raw

PATCH 69/209 PCI: fix size checks for mmap() on /proc/bus/pci files

In reply to Paul Gortmaker

From: Martin Wilck <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 3b519e4ea618b6943a82931630872907f9ac2c2b upstream.

The checks for valid mmaps of PCI resources made through /proc/bus/pci files that were introduced in 9eff02e2042f96fb2aedd02e032eca1c5333d767 have several problems:

1. mmap() calls on /proc/bus/pci files are made with real file offsets > 0, whereas under /sys/bus/pci/devices, the start of the resource corresponds to offset 0. This may lead to false negatives in pci_mmap_fits(), which implicitly assumes the /sys/bus/pci/devices layout.

2. The loop in proc_bus_pci_mmap doesn't skip empty resouces. This leads to false positives, because pci_mmap_fits() doesn't treat empty resources correctly (the calculated size is 1 << (8*sizeof(resource_size_t)-PAGE_SHIFT) in this case!).

3. If a user maps resources with BAR > 0, pci_mmap_fits will emit bogus WARNINGS for the first resources that don't fit until the correct one is found.

On many controllers the first 2-4 BARs are used, and the others are empty. In this case, an mmap attempt will first fail on the non-empty BARs (including the "right" BAR because of 1.) and emit bogus WARNINGS because of 3., and finally succeed on the first empty BAR because of 2. This is certainly not the intended behaviour.

This patch addresses all 3 issues.
Updated with an enum type for the additional parameter for pci_mmap_fits().

---
 drivers/pci/pci-sysfs.c |   22 ++++++++++++++++------
 drivers/pci/pci.h       |    7 ++++++-
 drivers/pci/proc.c      |    2 +-
 3 files changed, 23 insertions(+), 8 deletions(-)
drivers/pci/pci-sysfs.c +16 -6
index fad9398..e3efd79 100644
@@ -692,17 +692,21 @@ void pci_remove_legacy_files(struct pci_bus *b)
 
 #ifdef HAVE_PCI_MMAP
 
-int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma)
+int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma,
+		  enum pci_mmap_api mmap_api)
 {
-	unsigned long nr, start, size;
+	unsigned long nr, start, size, pci_start;
 
+	if (pci_resource_len(pdev, resno) == 0)
+		return 0;
 	nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
 	start = vma->vm_pgoff;
 	size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1;
-	if (start < size && size - start >= nr)
+	pci_start = (mmap_api == PCI_MMAP_SYSFS) ?
+			pci_resource_start(pdev, resno) >> PAGE_SHIFT : 0;
+	if (start >= pci_start && start < pci_start + size &&
+			start + nr <= pci_start + size)
 		return 1;
-	WARN(1, "process \"%s\" tried to map 0x%08lx-0x%08lx on %s BAR %d (size 0x%08lx)\n",
-		current->comm, start, start+nr, pci_name(pdev), resno, size);
 	return 0;
 }
 
@@ -732,8 +736,14 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
 	if (i >= PCI_ROM_RESOURCE)
 		return -ENODEV;
 
-	if (!pci_mmap_fits(pdev, i, vma))
+	if (!pci_mmap_fits(pdev, i, vma, PCI_MMAP_SYSFS)) {
+		WARN(1, "process \"%s\" tried to map 0x%08lx bytes "
+			"at page 0x%08lx on %s BAR %d (start 0x%16Lx, size 0x%16Lx)\n",
+			current->comm, vma->vm_end-vma->vm_start, vma->vm_pgoff,
+			pci_name(pdev), i,
+			pci_resource_start(pdev, i), pci_resource_len(pdev, i));
 		return -EINVAL;
+	}
 
 	/* pci_mmap_page_range() expects the same kind of entry as coming
 	 * from /proc/bus/pci/ which is a "user visible" value. If this is
drivers/pci/pci.h +6 -1
index 4eb10f4..32b5820 100644
@@ -13,8 +13,13 @@ extern int pci_create_sysfs_dev_files(struct pci_dev *pdev);
 extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
 extern void pci_cleanup_rom(struct pci_dev *dev);
 #ifdef HAVE_PCI_MMAP
+enum pci_mmap_api {
+	PCI_MMAP_SYSFS,	/* mmap on /sys/bus/pci/devices/<BDF>/resource<N> */
+	PCI_MMAP_PROCFS	/* mmap on /proc/bus/pci/<BDF> */
+};
 extern int pci_mmap_fits(struct pci_dev *pdev, int resno,
-			 struct vm_area_struct *vma);
+			 struct vm_area_struct *vmai,
+			 enum pci_mmap_api mmap_api);
 #endif
 int pci_probe_reset_function(struct pci_dev *dev);
 
drivers/pci/proc.c +1 -1
index 449e890..64ac30b 100644
@@ -260,7 +260,7 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma)
 
 	/* Make sure the caller is mapping a real resource for this device */
 	for (i = 0; i < PCI_ROM_RESOURCE; i++) {
-		if (pci_mmap_fits(dev, i, vma))
+		if (pci_mmap_fits(dev, i, vma,  PCI_MMAP_PROCFS))
 			break;
 	}
 
Signature · 1 line
1.7.4.4
#70 lore raw

PATCH 70/209 PCI: sysfs: fix printk warnings

In reply to Paul Gortmaker

From: Randy Dunlap <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit e25cd062b16ed1d41a157aec5a108abd6ff2e9f9 upstream.

Cast pci_resource_start() and pci_resource_len() to u64 for printk.

drivers/pci/pci-sysfs.c:753: warning: format '%16Lx' expects type 'long long unsigned int', but argument 9 has type 'resource_size_t' drivers/pci/pci-sysfs.c:753: warning: format '%16Lx' expects type 'long long unsigned int', but argument 10 has type 'resource_size_t'

---
 drivers/pci/pci-sysfs.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
drivers/pci/pci-sysfs.c +2 -1
index e3efd79..627d067 100644
@@ -741,7 +741,8 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
 			"at page 0x%08lx on %s BAR %d (start 0x%16Lx, size 0x%16Lx)\n",
 			current->comm, vma->vm_end-vma->vm_start, vma->vm_pgoff,
 			pci_name(pdev), i,
-			pci_resource_start(pdev, i), pci_resource_len(pdev, i));
+			(u64)pci_resource_start(pdev, i),
+			(u64)pci_resource_len(pdev, i));
 		return -EINVAL;
 	}
 
Signature · 1 line
1.7.4.4
#71 lore raw

PATCH 71/209 PCI: fix offset check for sysfs mmapped files

In reply to Paul Gortmaker

From: Darrick J. Wong <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 8c05cd08a7504b855c265263e84af61aabafa329 upstream.

I just loaded 2.6.37-rc2 on my machines, and I noticed that X no longer starts. Running an strace of the X server shows that it's doing this:

open("/sys/bus/pci/devices/0000:07:00.0/resource0", O_RDWR) = 10
mmap(NULL, 16777216, PROT_READ|PROT_WRITE, MAP_SHARED, 10, 0) = -1 EINVAL (Invalid argument)

This code seems to be asking for a shared read/write mapping of 16MB worth of BAR0 starting at file offset 0, and letting the kernel assign a starting address. Unfortunately, this -EINVAL causes X not to start. Looking into dmesg, there's a complaint like so:

process "Xorg" tried to map 0x01000000 bytes at page 0x00000000 on 0000:07:00.0 BAR 0 (start 0x 96000000, size 0x 1000000)

...with the following code in pci_mmap_fits:

	pci_start = (mmap_api == PCI_MMAP_SYSFS) ?
		pci_resource_start(pdev, resno) >> PAGE_SHIFT : 0;
        if (start >= pci_start && start < pci_start + size &&
                        start + nr <= pci_start + size)

It looks like the logic here is set up such that when the mmap call comes via sysfs, the check in pci_mmap_fits wants vma->vm_pgoff to be between the resource's start and end address, and the end of the vma to be no farther than the end. However, the sysfs PCI resource files always start at offset zero, which means that this test always fails for programs that mmap the sysfs files. Given the comment in the original commit 3b519e4ea618b6943a82931630872907f9ac2c2b, I _think_ the old procfs files require that the file offset be equal to the resource's base address when mmapping.

I think what we want here is for pci_start to be 0 when mmap_api == PCI_MMAP_PROCFS. The following patch makes that change, after which the Matrox and Mach64 X drivers work again.

---
 drivers/pci/pci-sysfs.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/pci/pci-sysfs.c +1 -1
index 627d067..f5cd68c 100644
@@ -702,7 +702,7 @@ int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma,
 	nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
 	start = vma->vm_pgoff;
 	size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1;
-	pci_start = (mmap_api == PCI_MMAP_SYSFS) ?
+	pci_start = (mmap_api == PCI_MMAP_PROCFS) ?
 			pci_resource_start(pdev, resno) >> PAGE_SHIFT : 0;
 	if (start >= pci_start && start < pci_start + size &&
 			start + nr <= pci_start + size)
Signature · 1 line
1.7.4.4
#72 lore raw

PATCH 72/209 efifb: check that the base address is plausible on pci systems

In reply to Paul Gortmaker

From: Peter Jones <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 85a00d9bbfb4704fbf368944b1cb9fed8f1598c5 upstream.

Some Apple machines have identical DMI data but different memory configurations for the video. Given that, check that the address in our table is actually within the range of a PCI BAR on a VGA device in the machine.

This also fixes up the return value from set_system(), which has always been wrong, but never resulted in bad behavior since there's only ever been one matching entry in the dmi table.

The patch

1) stops people's machines from crashing when we get their display wrong, which seems to be unfortunately inevitable,

2) allows us to support identical dmi data with differing video memory configurations

This also adds me as the efifb maintainer, since I've effectively been acting as such for quite some time.

---
 MAINTAINERS           |    6 +++++
 drivers/video/efifb.c |   61 +++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 55 insertions(+), 12 deletions(-)
MAINTAINERS +6 -0
index d329b05..502b380 100644
@@ -2104,6 +2104,12 @@ W:	http://acpi4asus.sf.net
 S:	Maintained
 F:	drivers/platform/x86/eeepc-laptop.c
 
+EFIFB FRAMEBUFFER DRIVER
+L:	[email protected]
+M:	Peter Jones <[email protected]>
+S:	Maintained
+F:	drivers/video/efifb.c
+
 EFS FILESYSTEM
 W:	http://aeschi.ch.eu.org/efs/
 S:	Orphan
drivers/video/efifb.c +49 -12

81 lines not on this page · raw message

Signature · 1 line
1.7.4.4
#73 lore raw

PATCH 73/209 USB: ftdi_sio: add device IDs for Milkymist One JTAG/serial

In reply to Paul Gortmaker

From: Sebastien Bourdeauducq <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 7fea0f714ffb3f303d4b66933af2df2f5584c9bf upstream.

Add the USB IDs for the Milkymist One FTDI-based JTAG/serial adapter
(http://projects.qi-hardware.com/index.php/p/mmone-jtag-serial-cable/)
to the ftdi_sio driver and disable the first serial channel (used as JTAG from userspace).

---
 drivers/usb/serial/ftdi_sio.c     |    2 ++
 drivers/usb/serial/ftdi_sio_ids.h |    6 ++++++
 2 files changed, 8 insertions(+), 0 deletions(-)
drivers/usb/serial/ftdi_sio.c +2 -0
index 55ff244..6c7b6ba 100644
@@ -800,6 +800,8 @@ static struct usb_device_id id_table_combined [] = {
 	{ USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LOGBOOKML_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LS_LOGBOOK_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_HS_LOGBOOK_PID) },
+	{ USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID),
+		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 	{ },					/* Optional parameter entry */
 	{ }					/* Terminating entry */
 };
drivers/usb/serial/ftdi_sio_ids.h +6 -0
index 4addf78..9116449 100644
@@ -1107,3 +1107,9 @@
 #define FTDI_SCIENCESCOPE_LOGBOOKML_PID		0xFF18
 #define FTDI_SCIENCESCOPE_LS_LOGBOOK_PID	0xFF1C
 #define FTDI_SCIENCESCOPE_HS_LOGBOOK_PID	0xFF1D
+
+/*
+ * Milkymist One JTAG/Serial
+ */
+#define QIHARDWARE_VID			0x20B7
+#define MILKYMISTONE_JTAGSERIAL_PID	0x0713
Signature · 1 line
1.7.4.4
#74 lore raw

PATCH 74/209 USB: option: fix when the driver is loaded incorrectly for some Huawei devices.

In reply to Paul Gortmaker

From: ma rui <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 58c0d9d70109bd7e82bdb9517007311a48499960 upstream.

When huawei datacard with PID 0x14AC is insterted into Linux system, the present kernel will load the "option" driver to all the interfaces. But actually, some interfaces run as other function and do not need "option" driver.

In this path, we modify the id_tables, when the PID is 0x14ac ,VID is 0x12d1, Only when the interface's Class is 0xff,Subclass is 0xff, Pro is 0xff, it does need "option" driver.

---
 drivers/usb/serial/option.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/usb/serial/option.c +1 -1
index 0e94896..58100d9 100644
@@ -513,7 +513,7 @@ static const struct usb_device_id option_ids[] = {
 	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_9508) },
 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, /* Novatel Merlin V640/XV620 */
 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, /* Novatel Merlin V620/S620 */
Signature · 1 line
1.7.4.4
#75 lore raw

PATCH 75/209 usb: misc: sisusbvga: fix information leak to userland

In reply to Paul Gortmaker

From: Vasiliy Kulikov <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 5dc92cf1d0b4b0debbd2e333b83f9746c103533d upstream.

Structure sisusb_info is copied to userland with "sisusb_reserved" field uninitialized. It leads to leaking of contents of kernel stack memory.

---
 drivers/usb/misc/sisusbvga/sisusb.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
drivers/usb/misc/sisusbvga/sisusb.c +1 -0
index cf13923..ba0a0bb 100644
@@ -3018,6 +3018,7 @@ sisusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 #else
 			x.sisusb_conactive  = 0;
 #endif
+			memset(x.sisusb_reserved, 0, sizeof(x.sisusb_reserved));
 
 			if (copy_to_user((void __user *)arg, &x, sizeof(x)))
 				retval = -EFAULT;
Signature · 1 line
1.7.4.4
#76 lore raw

PATCH 76/209 usb: misc: iowarrior: fix information leak to userland

In reply to Paul Gortmaker

From: Vasiliy Kulikov <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit eca67aaeebd6e5d22b0d991af1dd0424dc703bfb upstream.

Structure iowarrior_info is copied to userland with padding byted between "serial" and "revision" fields uninitialized. It leads to leaking of contents of kernel stack memory.

---
 drivers/usb/misc/iowarrior.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
drivers/usb/misc/iowarrior.c +1 -0
index d3c8523..7c84321 100644
@@ -552,6 +552,7 @@ static long iowarrior_ioctl(struct file *file, unsigned int cmd,
 			/* needed for power consumption */
 			struct usb_config_descriptor *cfg_descriptor = &dev->udev->actconfig->desc;
 
+			memset(&info, 0, sizeof(info));
 			/* directly from the descriptor */
 			info.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
 			info.product = dev->product_id;
Signature · 1 line
1.7.4.4
#77 lore raw

PATCH 77/209 usb: core: fix information leak to userland

In reply to Paul Gortmaker

From: Vasiliy Kulikov <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 886ccd4520064408ce5876cfe00554ce52ecf4a7 upstream.

Structure usbdevfs_connectinfo is copied to userland with padding byted after "slow" field uninitialized. It leads to leaking of contents of kernel stack memory.

---
 drivers/usb/core/devio.c |    7 ++++---
 1 files changed, 4 insertions(+), 3 deletions(-)
drivers/usb/core/devio.c +4 -3
index 3466fdc..6088192 100644
@@ -966,10 +966,11 @@ static int proc_getdriver(struct dev_state *ps, void __user *arg)
 
 static int proc_connectinfo(struct dev_state *ps, void __user *arg)
 {
-	struct usbdevfs_connectinfo ci;
+	struct usbdevfs_connectinfo ci = {
+		.devnum = ps->dev->devnum,
+		.slow = ps->dev->speed == USB_SPEED_LOW
+	};
 
-	ci.devnum = ps->dev->devnum;
-	ci.slow = ps->dev->speed == USB_SPEED_LOW;
 	if (copy_to_user(arg, &ci, sizeof(ci)))
 		return -EFAULT;
 	return 0;
Signature · 1 line
1.7.4.4
#78 lore raw

PATCH 78/209 USB: EHCI: fix obscure race in ehci_endpoint_disable

In reply to Paul Gortmaker

From: Alan Stern <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 02e2c51ba3e80acde600721ea784c3ef84da5ea1 upstream.

This patch (as1435) fixes an obscure and unlikely race in ehci-hcd. When an async URB is unlinked, the corresponding QH is removed from the async list. If the QH's endpoint is then disabled while the URB is being given back, ehci_endpoint_disable() won't find the QH on the async list, causing it to believe that the QH has been lost. This will lead to a memory leak at best and quite possibly to an oops.

The solution is to trust usbcore not to lose track of endpoints. If the QH isn't on the async list then it doesn't need to be taken off the list, but the driver should still wait for the QH to become IDLE before disabling it.

In theory this fixes Bugzilla #20182. In fact the race is so rare that it's not possible to tell whether the bug is still present. However, adding delays and making other changes to force the race seems to show that the patch works.

---
 drivers/usb/host/ehci-hcd.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)
drivers/usb/host/ehci-hcd.c +5 -5
index 13ead00..d2dd6e1 100644
@@ -1010,10 +1010,11 @@ rescan:
 				tmp && tmp != qh;
 				tmp = tmp->qh_next.qh)
 			continue;
-		/* periodic qh self-unlinks on empty */
-		if (!tmp)
-			goto nogood;
-		unlink_async (ehci, qh);
+		/* periodic qh self-unlinks on empty, and a COMPLETING qh
+		 * may already be unlinked.
+		 */
+		if (tmp)
+			unlink_async(ehci, qh);
 		/* FALL THROUGH */
 	case QH_STATE_UNLINK:		/* wait for hw to finish? */
 	case QH_STATE_UNLINK_WAIT:
@@ -1030,7 +1031,6 @@ idle_timeout:
 		}
 		/* else FALL THROUGH */
 	default:
-nogood:
 		/* caller was supposed to have unlinked any requests;
 		 * that's not our job.  just leak this memory.
 		 */
Signature · 1 line
1.7.4.4
#79 lore raw

PATCH 79/209 USB: storage: sierra_ms: fix sysfs file attribute

In reply to Paul Gortmaker

From: Greg Kroah-Hartman <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit d9624e75f6ad94d8a0718c1fafa89186d271a78c upstream.

A non-writable sysfs file shouldn't have writable attributes.

---
 drivers/usb/storage/sierra_ms.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/usb/storage/sierra_ms.c +1 -1
index 57fc2f5..ceba512 100644
@@ -121,7 +121,7 @@ static ssize_t show_truinst(struct device *dev, struct device_attribute *attr,
 	}
 	return result;
 }
-static DEVICE_ATTR(truinst, S_IWUGO | S_IRUGO, show_truinst, NULL);
+static DEVICE_ATTR(truinst, S_IRUGO, show_truinst, NULL);
 
 int sierra_ms_init(struct us_data *us)
 {
Signature · 1 line
1.7.4.4
#80 lore raw

PATCH 80/209 USB: atm: ueagle-atm: fix up some permissions on the sysfs files

In reply to Paul Gortmaker

From: Greg Kroah-Hartman <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit e502ac5e1eca99d7dc3f12b2a6780ccbca674858 upstream.

Some of the sysfs files had the incorrect permissions. Some didn't make sense at all (writable for a file that you could not write to?)

---
 drivers/usb/atm/ueagle-atm.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)
drivers/usb/atm/ueagle-atm.c +3 -3
index 25f01b5..4c87b1b 100644
@@ -2261,7 +2261,7 @@ out:
 	return ret;
 }
 
-static DEVICE_ATTR(stat_status, S_IWUGO | S_IRUGO, read_status, reboot);
+static DEVICE_ATTR(stat_status, S_IWUSR | S_IRUGO, read_status, reboot);
 
 static ssize_t read_human_status(struct device *dev, struct device_attribute *attr,
 		char *buf)
@@ -2324,7 +2324,7 @@ out:
 	return ret;
 }
 
-static DEVICE_ATTR(stat_human_status, S_IWUGO | S_IRUGO, read_human_status, NULL);
+static DEVICE_ATTR(stat_human_status, S_IRUGO, read_human_status, NULL);
 
 static ssize_t read_delin(struct device *dev, struct device_attribute *attr,
 		char *buf)
@@ -2356,7 +2356,7 @@ out:
 	return ret;
 }
 
-static DEVICE_ATTR(stat_delin, S_IWUGO | S_IRUGO, read_delin, NULL);
+static DEVICE_ATTR(stat_delin, S_IRUGO, read_delin, NULL);
 
 #define UEA_ATTR(name, reset) 					\
 								\
Signature · 1 line
1.7.4.4
#81 lore raw

PATCH 81/209 USB: misc: cypress_cy7c63: fix up some sysfs attribute permissions

In reply to Paul Gortmaker

From: Greg Kroah-Hartman <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit c990600d340641150f7270470a64bd99a5c0b225 upstream.

They should not be writable by any user.

---
 drivers/usb/misc/cypress_cy7c63.c |    6 ++----
 1 files changed, 2 insertions(+), 4 deletions(-)
drivers/usb/misc/cypress_cy7c63.c +2 -4
index 2f43c57..9251773 100644
@@ -196,11 +196,9 @@ static ssize_t get_port1_handler(struct device *dev,
 	return read_port(dev, attr, buf, 1, CYPRESS_READ_PORT_ID1);
 }
 
-static DEVICE_ATTR(port0, S_IWUGO | S_IRUGO,
-		   get_port0_handler, set_port0_handler);
+static DEVICE_ATTR(port0, S_IRUGO | S_IWUSR, get_port0_handler, set_port0_handler);
 
-static DEVICE_ATTR(port1, S_IWUGO | S_IRUGO,
-		   get_port1_handler, set_port1_handler);
+static DEVICE_ATTR(port1, S_IRUGO | S_IWUSR, get_port1_handler, set_port1_handler);
 
 
 static int cypress_probe(struct usb_interface *interface,
Signature · 1 line
1.7.4.4
#82 lore raw

PATCH 82/209 USB: misc: usbled: fix up some sysfs attribute permissions

In reply to Paul Gortmaker

From: Greg Kroah-Hartman <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 48f115470e68d443436b76b22dad63ffbffd6b97 upstream.

They should not be writable by any user.

---
 drivers/usb/misc/usbled.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/usb/misc/usbled.c +1 -1
index 63da2c3..c96f51d 100644
@@ -94,7 +94,7 @@ static ssize_t set_##value(struct device *dev, struct device_attribute *attr, co
 	change_color(led);						\
 	return count;							\
 }									\
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
+static DEVICE_ATTR(value, S_IRUGO | S_IWUSR, show_##value, set_##value);
 show_set(blue);
 show_set(red);
 show_set(green);
Signature · 1 line
1.7.4.4
#83 lore raw

PATCH 83/209 USB: ftdi_sio: revert "USB: ftdi_sio: fix DTR/RTS line modes"

In reply to Paul Gortmaker

From: Johan Hovold <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 677aeafe19e88c282af74564048243ccabb1c590 upstream.

This reverts commit 6a1a82df91fa0eb1cc76069a9efe5714d087eccd.

RTS and DTR should not be modified based on CRTSCTS when calling set_termios.

Modem control lines are raised at port open by the tty layer and should stay raised regardless of whether hardware flow control is enabled or not.

This is in conformance with the way serial ports work today and many applications depend on this behaviour to be able to talk to hardware implementing hardware flow control (without the applications actually using it).

Hardware which expects different behaviour on these lines can always use TIOCMSET/TIOCMBI[SC] after port open to change them.

---
 drivers/usb/serial/ftdi_sio.c |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)
drivers/usb/serial/ftdi_sio.c +0 -4
index 6c7b6ba..a654281 100644
@@ -2348,8 +2348,6 @@ static void ftdi_set_termios(struct tty_struct *tty,
 				"urb failed to set to rts/cts flow control\n");
 		}
 
-		/* raise DTR/RTS */
-		set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
 	} else {
 		/*
 		 * Xon/Xoff code
@@ -2397,8 +2395,6 @@ static void ftdi_set_termios(struct tty_struct *tty,
 			}
 		}
 
-		/* lower DTR/RTS */
-		clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
 	}
 	return;
 }
Signature · 1 line
1.7.4.4
#84 lore raw

PATCH 84/209 USB: misc: trancevibrator: fix up a sysfs attribute permission

In reply to Paul Gortmaker

From: Greg Kroah-Hartman <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit d489a4b3926bad571d404ca6508f6744b9602776 upstream.

It should not be writable by any user.

---
 drivers/usb/misc/trancevibrator.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/usb/misc/trancevibrator.c +1 -1
index d77aba4..f63776a 100644
@@ -86,7 +86,7 @@ static ssize_t set_speed(struct device *dev, struct device_attribute *attr,
 	return count;
 }
 
-static DEVICE_ATTR(speed, S_IWUGO | S_IRUGO, show_speed, set_speed);
+static DEVICE_ATTR(speed, S_IRUGO | S_IWUSR, show_speed, set_speed);
 
 static int tv_probe(struct usb_interface *interface,
 		    const struct usb_device_id *id)
Signature · 1 line
1.7.4.4
#85 lore raw

PATCH 85/209 USB: misc: usbsevseg: fix up some sysfs attribute permissions

In reply to Paul Gortmaker

From: Greg Kroah-Hartman <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit e24d7ace4e822debcb78386bf279c9aba4d7fbd1 upstream.

They should not be writable by any user.

---
 drivers/usb/misc/usbsevseg.c |   10 ++++------
 1 files changed, 4 insertions(+), 6 deletions(-)
drivers/usb/misc/usbsevseg.c +4 -6
index de8ef94..417b8f2 100644
@@ -192,7 +192,7 @@ static ssize_t set_attr_##name(struct device *dev, 		\
 								\
 	return count;						\
 }								\
-static DEVICE_ATTR(name, S_IWUGO | S_IRUGO, show_attr_##name, set_attr_##name);
+static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_attr_##name, set_attr_##name);
 
 static ssize_t show_attr_text(struct device *dev,
 	struct device_attribute *attr, char *buf)
@@ -223,7 +223,7 @@ static ssize_t set_attr_text(struct device *dev,
 	return count;
 }
 
-static DEVICE_ATTR(text, S_IWUGO | S_IRUGO, show_attr_text, set_attr_text);
+static DEVICE_ATTR(text, S_IRUGO | S_IWUSR, show_attr_text, set_attr_text);
 
 static ssize_t show_attr_decimals(struct device *dev,
 	struct device_attribute *attr, char *buf)
@@ -272,8 +272,7 @@ static ssize_t set_attr_decimals(struct device *dev,
 	return count;
 }
 
-static DEVICE_ATTR(decimals, S_IWUGO | S_IRUGO,
-	show_attr_decimals, set_attr_decimals);
+static DEVICE_ATTR(decimals, S_IRUGO | S_IWUSR, show_attr_decimals, set_attr_decimals);
 
 static ssize_t show_attr_textmode(struct device *dev,
 	struct device_attribute *attr, char *buf)
@@ -319,8 +318,7 @@ static ssize_t set_attr_textmode(struct device *dev,
 	return -EINVAL;
 }
 
-static DEVICE_ATTR(textmode, S_IWUGO | S_IRUGO,
-	show_attr_textmode, set_attr_textmode);
+static DEVICE_ATTR(textmode, S_IRUGO | S_IWUSR, show_attr_textmode, set_attr_textmode);
 
 
 MYDEV_ATTR_SIMPLE_UNSIGNED(powered, update_display_powered);
Signature · 1 line
1.7.4.4
#86 lore raw

PATCH 86/209 USB: ftdi_sio: Add ID for RT Systems USB-29B radio cable

In reply to Paul Gortmaker

From: Michael Stuermer <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 28942bb6a9dd4e2ed793675e515cfb8297ed355b upstream.

Another variant of the RT Systems programming cable for ham radios.

---
 drivers/usb/serial/ftdi_sio.c     |    1 +
 drivers/usb/serial/ftdi_sio_ids.h |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)
drivers/usb/serial/ftdi_sio.c +1 -0
index a654281..513b5a6 100644
@@ -702,6 +702,7 @@ static struct usb_device_id id_table_combined [] = {
 		.driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
 	{ USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
 	{ USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_SERIAL_VX7_PID) },
+	{ USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_CT29B_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) },
 	{ USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) },
drivers/usb/serial/ftdi_sio_ids.h +1 -0
index 9116449..e06f014 100644
@@ -728,6 +728,7 @@
  */
 #define RTSYSTEMS_VID			0x2100	/* Vendor ID */
 #define RTSYSTEMS_SERIAL_VX7_PID	0x9e52	/* Serial converter for VX-7 Radios using FT232RL */
+#define RTSYSTEMS_CT29B_PID		0x9e54	/* CT29B Radio Cable */
 
 /*
  * Bayer Ascensia Contour blood glucose meter USB-converter cable.
Signature · 1 line
1.7.4.4
#87 lore raw

PATCH 87/209 USB: serial: ftdi_sio: Vardaan USB RS422/485 converter PID added

In reply to Paul Gortmaker

From: Jacques Viviers <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 6fdbad8021151a9e93af8159a6232c8f26415c09 upstream.

Add the PID for the Vardaan Enterprises VEUSB422R3 USB to RS422/485 converter. It uses the same chip as the FTDI_8U232AM_PID 0x6001.

This should also work with the stable branches for:
2.6.31, 2.6.32, 2.6.33, 2.6.34, 2.6.35, 2.6.36

---
 drivers/usb/serial/ftdi_sio.c     |    1 +
 drivers/usb/serial/ftdi_sio_ids.h |    3 +++
 2 files changed, 4 insertions(+), 0 deletions(-)
drivers/usb/serial/ftdi_sio.c +1 -0
index 513b5a6..fd8f96e 100644
@@ -206,6 +206,7 @@ static struct usb_device_id id_table_combined [] = {
 	{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_R2000KU_TRUE_RNG) },
+	{ USB_DEVICE(FTDI_VID, FTDI_VARDAAN_PID) },
 	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0100_PID) },
 	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) },
 	{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) },
drivers/usb/serial/ftdi_sio_ids.h +3 -0
index e06f014..e6d7af6 100644
@@ -114,6 +114,9 @@
 /* Lenz LI-USB Computer Interface. */
 #define FTDI_LENZ_LIUSB_PID	0xD780
 
+/* Vardaan Enterprises Serial Interface VEUSB422R3 */
+#define FTDI_VARDAAN_PID	0xF070
+
 /*
  * Xsens Technologies BV products (http://www.xsens.com).
  */
Signature · 1 line
1.7.4.4
#88 lore raw

PATCH 88/209 acpi-cpufreq: fix a memleak when unloading driver

In reply to Paul Gortmaker

From: Zhang Rui <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit dab5fff14df2cd16eb1ad4c02e83915e1063fece upstream.

We didn't free per_cpu(acfreq_data, cpu)->freq_table when acpi_freq driver is unloaded.

Resulting in the following messages in /sys/kernel/debug/kmemleak:

unreferenced object 0xf6450e80 (size 64):
comm "modprobe", pid 1066, jiffies 4294677317 (age 19290.453s) hex dump (first 32 bytes):

    00 00 00 00 e8 a2 24 00 01 00 00 00 00 9f 24 00  ......$.......$.
    02 00 00 00 00 6a 18 00 03 00 00 00 00 35 0c 00  .....j.......5..
  backtrace:
    [<c123ba97>] kmemleak_alloc+0x27/0x50
    [<c109f96f>] __kmalloc+0xcf/0x110
    [<f9da97ee>] acpi_cpufreq_cpu_init+0x1ee/0x4e4 [acpi_cpufreq]
    [<c11cd8d2>] cpufreq_add_dev+0x142/0x3a0
    [<c11920b7>] sysdev_driver_register+0x97/0x110
    [<c11cce56>] cpufreq_register_driver+0x86/0x140
    [<f9dad080>] 0xf9dad080
    [<c1001130>] do_one_initcall+0x30/0x160
    [<c10626e9>] sys_init_module+0x99/0x1e0
    [<c1002d97>] sysenter_do_call+0x12/0x26
    [<ffffffff>] 0xffffffff

https://bugzilla.kernel.org/show_bug.cgi?id=15807#c21

---
 arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +1 -0
index 4591680..59ca19f 100644
@@ -744,6 +744,7 @@ static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy)
 		per_cpu(acfreq_data, policy->cpu) = NULL;
 		acpi_processor_unregister_performance(data->acpi_data,
 						      policy->cpu);
+		kfree(data->freq_table);
 		kfree(data);
 	}
 
Signature · 1 line
1.7.4.4
#89 lore raw

PATCH 89/209 fuse: fix attributes after open(O_TRUNC)

In reply to Paul Gortmaker

From: Ken Sumrall <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit a0822c55779d9319939eac69f00bb729ea9d23da upstream.

The attribute cache for a file was not being cleared when a file is opened with O_TRUNC.

If the filesystem's open operation truncates the file ("atomic_o_trunc" feature flag is set) then the kernel should invalidate the cached st_mtime and st_ctime attributes.

Also i_size should be explicitly be set to zero as it is used sometimes without refreshing the cache.

---
 fs/fuse/file.c |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)
fs/fuse/file.c +10 -0
index a9f5e13..cbd2214 100644
@@ -134,6 +134,7 @@ EXPORT_SYMBOL_GPL(fuse_do_open);
 void fuse_finish_open(struct inode *inode, struct file *file)
 {
 	struct fuse_file *ff = file->private_data;
+	struct fuse_conn *fc = get_fuse_conn(inode);
 
 	if (ff->open_flags & FOPEN_DIRECT_IO)
 		file->f_op = &fuse_direct_io_file_operations;
@@ -141,6 +142,15 @@ void fuse_finish_open(struct inode *inode, struct file *file)
 		invalidate_inode_pages2(inode->i_mapping);
 	if (ff->open_flags & FOPEN_NONSEEKABLE)
 		nonseekable_open(inode, file);
+	if (fc->atomic_o_trunc && (file->f_flags & O_TRUNC)) {
+		struct fuse_inode *fi = get_fuse_inode(inode);
+
+		spin_lock(&fc->lock);
+		fi->attr_version = ++fc->attr_version;
+		i_size_write(inode, 0);
+		spin_unlock(&fc->lock);
+		fuse_invalidate_attr(inode);
+	}
 }
 
 int fuse_open_common(struct inode *inode, struct file *file, bool isdir)
Signature · 1 line
1.7.4.4
#90 lore raw

PATCH 90/209 do_exit(): make sure that we run with get_fs() == USER_DS

In reply to Paul Gortmaker

From: Nelson Elhage <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 33dd94ae1ccbfb7bf0fb6c692bc3d1c4269e6177 upstream.

If a user manages to trigger an oops with fs set to KERNEL_DS, fs is not otherwise reset before do_exit(). do_exit may later (via mm_release in fork.c) do a put_user to a user-controlled address, potentially allowing a user to leverage an oops into a controlled write into kernel memory.

This is only triggerable in the presence of another bug, but this potentially turns a lot of DoS bugs into privilege escalations, so it's worth fixing. I have proof-of-concept code which uses this bug along with CVE-2010-3849 to write a zero to an arbitrary kernel address, so I've tested that this is not theoretical.

A more logical place to put this fix might be when we know an oops has occurred, before we call do_exit(), but that would involve changing every architecture, in multiple places.

Let's just stick it in do_exit instead.

---
 kernel/exit.c |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)
kernel/exit.c +9 -0
index b0242b4..8eb207f 100644
@@ -911,6 +911,15 @@ NORET_TYPE void do_exit(long code)
 	if (unlikely(!tsk->pid))
 		panic("Attempted to kill the idle task!");
 
+	/*
+	 * If do_exit is called because this processes oopsed, it's possible
+	 * that get_fs() was left as KERNEL_DS, so reset it to USER_DS before
+	 * continuing. Amongst other possible reasons, this is to prevent
+	 * mm_release()->clear_child_tid() from writing to a user-controlled
+	 * kernel address.
+	 */
+	set_fs(USER_DS);
+
 	tracehook_report_exit(&code);
 
 	validate_creds_for_do_exit(tsk);
Signature · 1 line
1.7.4.4
#91 lore raw

PATCH 91/209 uml: disable winch irq before freeing handler data

In reply to Paul Gortmaker

From: Will Newton <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 69e83dad5207f8f03c9699e57e1febb114383cb8 upstream.

Disable the winch irq early to make sure we don't take an interrupt part way through the freeing of the handler data, resulting in a crash on shutdown:

winch_interrupt : read failed, errno = 9
fd 13 is losing SIGWINCH support

  ------------[ cut here ]------------
  WARNING: at lib/list_debug.c:48 list_del+0xc6/0x100()
  list_del corruption, next is LIST_POISON1 (00100100)
  082578c8:  [<081fd77f>] dump_stack+0x22/0x24
  082578e0:  [<0807a18a>] warn_slowpath_common+0x5a/0x80
  08257908:  [<0807a23e>] warn_slowpath_fmt+0x2e/0x30
  08257920:  [<08172196>] list_del+0xc6/0x100
  08257940:  [<08060244>] free_winch+0x14/0x80
  08257958:  [<080606fb>] winch_interrupt+0xdb/0xe0
  08257978:  [<080a65b5>] handle_IRQ_event+0x35/0xe0
  08257998:  [<080a8717>] handle_edge_irq+0xb7/0x170
  082579bc:  [<08059bc4>] do_IRQ+0x34/0x50
  082579d4:  [<08059e1b>] sigio_handler+0x5b/0x80
  082579ec:  [<0806a374>] sig_handler_common+0x44/0xb0
  08257a68:  [<0806a538>] sig_handler+0x38/0x50
  08257a78:  [<0806a77c>] handle_signal+0x5c/0xa0
  08257a9c:  [<0806be28>] hard_handler+0x18/0x20
  08257aac:  [<00c14400>] 0xc14400
---
 arch/um/drivers/line.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)
arch/um/drivers/line.c +3 -2
index 7a656bd..3aa33a7 100644
@@ -728,6 +728,9 @@ struct winch {
 
 static void free_winch(struct winch *winch, int free_irq_ok)
 {
+	if (free_irq_ok)
+		free_irq(WINCH_IRQ, winch);
+
 	list_del(&winch->list);
 
 	if (winch->pid != -1)
@@ -736,8 +739,6 @@ static void free_winch(struct winch *winch, int free_irq_ok)
 		os_close_file(winch->fd);
 	if (winch->stack != 0)
 		free_stack(winch->stack, 0);
-	if (free_irq_ok)
-		free_irq(WINCH_IRQ, winch);
 	kfree(winch);
 }
 
Signature · 1 line
1.7.4.4
#92 lore raw

PATCH 92/209 backlight: grab ops_lock before testing bd->ops

In reply to Paul Gortmaker

From: Uwe Kleine-König <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit d1d73578e053b981c3611e5a211534290d24a5eb upstream.

According to the comment describing ops_lock in the definition of struct backlight_device and when comparing with other functions in backlight.c the mutex must be hold when checking ops to be non-NULL.

Fixes a problem added by c835ee7f4154992e6 ("backlight: Add suspend/resume support to the backlight core") in Jan 2009.

---
 drivers/video/backlight/backlight.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)
drivers/video/backlight/backlight.c +6 -6
index e207810..0870329 100644
@@ -197,12 +197,12 @@ static int backlight_suspend(struct device *dev, pm_message_t state)
 {
 	struct backlight_device *bd = to_backlight_device(dev);
 
-	if (bd->ops->options & BL_CORE_SUSPENDRESUME) {
-		mutex_lock(&bd->ops_lock);
+	mutex_lock(&bd->ops_lock);
+	if (bd->ops && bd->ops->options & BL_CORE_SUSPENDRESUME) {
 		bd->props.state |= BL_CORE_SUSPENDED;
 		backlight_update_status(bd);
-		mutex_unlock(&bd->ops_lock);
 	}
+	mutex_unlock(&bd->ops_lock);
 
 	return 0;
 }
@@ -211,12 +211,12 @@ static int backlight_resume(struct device *dev)
 {
 	struct backlight_device *bd = to_backlight_device(dev);
 
-	if (bd->ops->options & BL_CORE_SUSPENDRESUME) {
-		mutex_lock(&bd->ops_lock);
+	mutex_lock(&bd->ops_lock);
+	if (bd->ops && bd->ops->options & BL_CORE_SUSPENDRESUME) {
 		bd->props.state &= ~BL_CORE_SUSPENDED;
 		backlight_update_status(bd);
-		mutex_unlock(&bd->ops_lock);
 	}
+	mutex_unlock(&bd->ops_lock);
 
 	return 0;
 }
Signature · 1 line
1.7.4.4
#93 lore raw

PATCH 93/209 nommu: yield CPU while disposing VM

In reply to Paul Gortmaker

From: Steven J. Magnani <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 04c3496152394d17e3bc2316f9731ee3e8a026bc upstream.

Depending on processor speed, page size, and the amount of memory a process is allowed to amass, cleanup of a large VM may freeze the system for many seconds. This can result in a watchdog timeout.

Make sure other tasks receive some service when cleaning up large VMs.

---
 mm/nommu.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
mm/nommu.c +1 -0
index 28994ee..1fc13c0 100644
@@ -1669,6 +1669,7 @@ void exit_mmap(struct mm_struct *mm)
 		mm->mmap = vma->vm_next;
 		delete_vma_from_mm(vma);
 		delete_vma(mm, vma);
+		cond_resched();
 	}
 
 	kleave("");
Signature · 1 line
1.7.4.4
#94 lore raw

PATCH 94/209 DECnet: don't leak uninitialized stack byte

In reply to Paul Gortmaker

From: Dan Rosenberg <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 3c6f27bf33052ea6ba9d82369fb460726fb779c0 upstream.

A single uninitialized padding byte is leaked to userspace.

---
 net/decnet/af_decnet.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
net/decnet/af_decnet.c +2 -0
index 2b494fa..7cc13e1 100644
@@ -1556,6 +1556,8 @@ static int __dn_getsockopt(struct socket *sock, int level,int optname, char __us
 			if (r_len > sizeof(struct linkinfo_dn))
 				r_len = sizeof(struct linkinfo_dn);
 
+			memset(&link, 0, sizeof(link));
+
 			switch(sock->state) {
 				case SS_CONNECTING:
 					link.idn_linkstate = LL_CONNECTING;
Signature · 1 line
1.7.4.4
#95 lore raw

PATCH 95/209 perf_events: Fix perf_counter_mmap() hook in mprotect()

In reply to Paul Gortmaker

From: Pekka Enberg <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 63bfd7384b119409685a17d5c58f0b56e5dc03da upstream.

As pointed out by Linus, commit dab5855 ("perf_counter: Add mmap event hooks to mprotect()") is fundamentally wrong as mprotect_fixup() can free 'vma' due to merging. Fix the problem by moving perf_event_mmap() hook to mprotect_fixup().

Note: there's another successful return path from mprotect_fixup() if old flags equal to new flags. We don't, however, need to call perf_event_mmap() there because 'perf' already knows the VMA is executable.

---
 mm/mprotect.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
mm/mprotect.c +1 -1
index 2d1bf7c..4c51338 100644
@@ -211,6 +211,7 @@ success:
 	mmu_notifier_invalidate_range_end(mm, start, end);
 	vm_stat_account(mm, oldflags, vma->vm_file, -nrpages);
 	vm_stat_account(mm, newflags, vma->vm_file, nrpages);
+	perf_event_mmap(vma);
 	return 0;
 
 fail:
@@ -299,7 +300,6 @@ SYSCALL_DEFINE3(mprotect, unsigned long, start, size_t, len,
 		error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
 		if (error)
 			goto out;
-		perf_event_mmap(vma);
 		nstart = tmp;
 
 		if (nstart < prev->vm_end)
Signature · 1 line
1.7.4.4
#96 lore raw

PATCH 96/209 ARM: 6489/1: thumb2: fix incorrect optimisation in usracc

In reply to Paul Gortmaker

From: Will Deacon <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 1142b71d85894dcff1466dd6c871ea3c89e0352c upstream.

Commit 8b592783 added a Thumb-2 variant of usracc which, when it is called with \rept=2, calls usraccoff once with an offset of 0 and secondly with a hard-coded offset of 4 in order to avoid incrementing the pointer again. If \inc != 4 then we will store the data to the wrong offset from \ptr. Luckily, the only caller that passes \rept=2 to this function is __clear_user so we haven't been actively corrupting user data.

This patch fixes usracc to pass \inc instead of #4 to usraccoff when it is called a second time.

---
 arch/arm/include/asm/assembler.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
arch/arm/include/asm/assembler.h +1 -1
index 6e8f05c..d757555 100644
@@ -215,7 +215,7 @@
 	@ Slightly optimised to avoid incrementing the pointer twice
 	usraccoff \instr, \reg, \ptr, \inc, 0, \cond, \abort
 	.if	\rept == 2
-	usraccoff \instr, \reg, \ptr, \inc, 4, \cond, \abort
+	usraccoff \instr, \reg, \ptr, \inc, \inc, \cond, \abort
 	.endif
 
 	add\cond \ptr, #\rept * \inc
Signature · 1 line
1.7.4.4
#97 lore raw

PATCH 97/209 ARM: 6482/2: Fix find_next_zero_bit and related assembly

In reply to Paul Gortmaker

From: James Jones <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 0e91ec0c06d2cd15071a6021c94840a50e6671aa upstream.

The find_next_bit, find_first_bit, find_next_zero_bit and find_first_zero_bit functions were not properly clamping to the maxbit argument at the bit level. They were instead only checking maxbit at the byte level. To fix this, add a compare and a conditional move instruction to the end of the common bit-within-the- byte code used by all the functions and be sure not to clobber the maxbit argument before it is used.

---
 arch/arm/lib/findbit.S |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)
arch/arm/lib/findbit.S +4 -2
index 1e4cbd4..64f6bc1 100644
@@ -174,8 +174,8 @@ ENDPROC(_find_next_bit_be)
  */
 .L_found:
 #if __LINUX_ARM_ARCH__ >= 5
-		rsb	r1, r3, #0
-		and	r3, r3, r1
+		rsb	r0, r3, #0
+		and	r3, r3, r0
 		clz	r3, r3
 		rsb	r3, r3, #31
 		add	r0, r2, r3
@@ -190,5 +190,7 @@ ENDPROC(_find_next_bit_be)
 		addeq	r2, r2, #1
 		mov	r0, r2
 #endif
+		cmp	r1, r0			@ Clamp to maxbit
+		movlo	r0, r1
 		mov	pc, lr
 
Signature · 1 line
1.7.4.4
#98 lore raw

PATCH 98/209 Staging: frontier: fix up some sysfs attribute permissions

In reply to Paul Gortmaker

From: Greg Kroah-Hartman <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 3bad28ec006ad6ab2bca4e5103860b75391e3c9d upstream.

They should not be writable by any user

---
 drivers/staging/frontier/tranzport.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/staging/frontier/tranzport.c +1 -1
index 2f03f43..7218334 100644
@@ -202,7 +202,7 @@ static void usb_tranzport_abort_transfers(struct usb_tranzport *dev)
     t->value = temp;							\
     return count;							\
   }									\
-  static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
+  static DEVICE_ATTR(value, S_IRUSR | S_IRUGO, show_##value, set_##value);
 
 show_int(enable);
 show_int(offline);
Signature · 1 line
1.7.4.4
#99 lore raw

PATCH 99/209 Staging: frontier: fix up my fixup for some sysfs attribute permissions

In reply to Paul Gortmaker

From: Greg Kroah-Hartman <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 2a767fda5d0d8dcff465724dfad6ee131489b3f2 upstream.

They should be writable by root, not readable. Doh, stupid me with the wrong flags.

---
 drivers/staging/frontier/tranzport.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/staging/frontier/tranzport.c +1 -1
index 7218334..9d60e92 100644
@@ -202,7 +202,7 @@ static void usb_tranzport_abort_transfers(struct usb_tranzport *dev)
     t->value = temp;							\
     return count;							\
   }									\
-  static DEVICE_ATTR(value, S_IRUSR | S_IRUGO, show_##value, set_##value);
+  static DEVICE_ATTR(value, S_IWUSR | S_IRUGO, show_##value, set_##value);
 
 show_int(enable);
 show_int(offline);
Signature · 1 line
1.7.4.4
#100 lore raw

PATCH 100/209 staging: rtl8187se: Change panic to warn when RF switch turned off

In reply to Paul Gortmaker

From: Larry Finger <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit f36d83a8cb7224f45fdfa1129a616dff56479a09 upstream.

This driver issues a kernel panic over conditions that do not justify such drastic action. Change these to log entries with a stack dump.

This patch fixes the system crash reported in
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/674285.

---
 drivers/staging/rtl8187se/r8185b_init.c |   30 ++++++++++++++++++++++--------
 1 files changed, 22 insertions(+), 8 deletions(-)
drivers/staging/rtl8187se/r8185b_init.c +22 -8
index a0ece1f..e7e8745 100644
@@ -268,8 +268,12 @@ HwHSSIThreeWire(
 			}
 			udelay(10);
 		}
-		if (TryCnt == TC_3W_POLL_MAX_TRY_CNT)
-			panic("HwThreeWire(): CmdReg: %#X RE|WE bits are not clear!!\n", u1bTmp);
+		if (TryCnt == TC_3W_POLL_MAX_TRY_CNT) {
+			printk(KERN_ERR "rtl8187se: HwThreeWire(): CmdReg:"
+			       " %#X RE|WE bits are not clear!!\n", u1bTmp);
+			dump_stack();
+			return 0;
+		}
 
 		// RTL8187S HSSI Read/Write Function
 		u1bTmp = read_nic_byte(dev, RF_SW_CONFIG);
@@ -309,13 +313,23 @@ HwHSSIThreeWire(
 				int idx;
 				int ByteCnt = nDataBufBitCnt / 8;
                                 //printk("%d\n",nDataBufBitCnt);
-				if ((nDataBufBitCnt % 8) != 0)
-				panic("HwThreeWire(): nDataBufBitCnt(%d) should be multiple of 8!!!\n",
-				nDataBufBitCnt);
+				if ((nDataBufBitCnt % 8) != 0) {
+					printk(KERN_ERR "rtl8187se: "
+					       "HwThreeWire(): nDataBufBitCnt(%d)"
+					       " should be multiple of 8!!!\n",
+					       nDataBufBitCnt);
+					dump_stack();
+					nDataBufBitCnt += 8;
+					nDataBufBitCnt &= ~7;
+				}
 
-			       if (nDataBufBitCnt > 64)
-				panic("HwThreeWire(): nDataBufBitCnt(%d) should <= 64!!!\n",
-				nDataBufBitCnt);
+			       if (nDataBufBitCnt > 64) {
+					printk(KERN_ERR "rtl8187se: HwThreeWire():"
+					       " nDataBufBitCnt(%d) should <= 64!!!\n",
+					       nDataBufBitCnt);
+					dump_stack();
+					nDataBufBitCnt = 64;
+				}
 
 				for(idx = 0; idx < ByteCnt; idx++)
 				{
Signature · 1 line
1.7.4.4
#101 lore raw

PATCH 101/209 net sched: fix kernel leak in act_police

In reply to Paul Gortmaker

From: Jeff Mahoney <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 0f04cfd098fb81fded74e78ea1a1b86cc6c6c31e upstream.

While reviewing commit 1c40be12f7d8ca1d387510d39787b12e512a7ce8, I
audited other users of tc_action_ops->dump for information leaks.

That commit covered almost all of them but act_police still had a leak.

opt.limit and opt.capab aren't zeroed out before the structure is passed out.

This patch uses the C99 initializers to zero everything unused out.

---
 net/sched/act_police.c |   21 +++++++++------------
 1 files changed, 9 insertions(+), 12 deletions(-)
net/sched/act_police.c +9 -12
index 654f73d..bf93162 100644
@@ -341,22 +341,19 @@ tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
 {
 	unsigned char *b = skb_tail_pointer(skb);
 	struct tcf_police *police = a->priv;
-	struct tc_police opt;
-
-	opt.index = police->tcf_index;
-	opt.action = police->tcf_action;
-	opt.mtu = police->tcfp_mtu;
-	opt.burst = police->tcfp_burst;
-	opt.refcnt = police->tcf_refcnt - ref;
-	opt.bindcnt = police->tcf_bindcnt - bind;
+	struct tc_police opt = {
+		.index = police->tcf_index,
+		.action = police->tcf_action,
+		.mtu = police->tcfp_mtu,
+		.burst = police->tcfp_burst,
+		.refcnt = police->tcf_refcnt - ref,
+		.bindcnt = police->tcf_bindcnt - bind,
+	};
+
 	if (police->tcfp_R_tab)
 		opt.rate = police->tcfp_R_tab->rate;
-	else
-		memset(&opt.rate, 0, sizeof(opt.rate));
 	if (police->tcfp_P_tab)
 		opt.peakrate = police->tcfp_P_tab->rate;
-	else
-		memset(&opt.peakrate, 0, sizeof(opt.peakrate));
 	NLA_PUT(skb, TCA_POLICE_TBF, sizeof(opt), &opt);
 	if (police->tcfp_result)
 		NLA_PUT_U32(skb, TCA_POLICE_RESULT, police->tcfp_result);
Signature · 1 line
1.7.4.4
#102 lore raw

PATCH 102/209 HID: hidraw, fix a NULL pointer dereference in hidraw_ioctl

In reply to Paul Gortmaker

From: Antonio Ospite <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit d20d5ffab92f00188f360c44c791a5ffb988247c upstream.

BUG: unable to handle kernel NULL pointer dereference at 0000000000000028
IP: [<ffffffffa02c66b4>] hidraw_ioctl+0xfc/0x32c [hid]

[...]

This is reproducible by disconnecting the device while userspace does ioctl in a loop and doesn't check return values in order to exit the loop.

[PG: slightly/trivially reworked for backport to 34]

---
 drivers/hid/hidraw.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)
drivers/hid/hidraw.c +6 -0
index 6eadf1a..0db1a0f 100644
@@ -243,6 +243,11 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd,
 	void __user *user_arg = (void __user*) arg;
 
 	lock_kernel();
+	if (!dev) {
+		ret = -ENODEV;
+		goto out;
+	}
+
 	switch (cmd) {
 		case HIDIOCGRDESCSIZE:
 			if (put_user(dev->hid->rsize, (int __user *)arg))
@@ -315,6 +320,7 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd,
 
 		ret = -ENOTTY;
 	}
+out:
 	unlock_kernel();
 	return ret;
 }
Signature · 1 line
1.7.4.4
#103 lore raw

PATCH 103/209 HID: hidraw, fix a NULL pointer dereference in hidraw_write

In reply to Paul Gortmaker

From: Antonio Ospite <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit e42dee9a99a3ecd32b5c027e8f7411fb5bc11eb6 upstream.

BUG: unable to handle kernel NULL pointer dereference at 0000000000000028
IP: [<ffffffffa0f0a625>] hidraw_write+0x3b/0x116 [hid]

[...]

This is reproducible by disconnecting the device while userspace writes to dev node in a loop and doesn't check return values in order to exit the loop.

[PG: slightly/trivially reworked for backport to 34]

---
 drivers/hid/hidraw.c |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)
drivers/hid/hidraw.c +6 -2
index 0db1a0f..9d3c663 100644
@@ -106,11 +106,15 @@ out:
 static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
 {
 	unsigned int minor = iminor(file->f_path.dentry->d_inode);
-	/* FIXME: What stops hidraw_table going NULL */
-	struct hid_device *dev = hidraw_table[minor]->hid;
+	struct hid_device *dev;
 	__u8 *buf;
 	int ret = 0;
 
+	if (!hidraw_table[minor])
+		return -ENODEV;
+
+	dev = hidraw_table[minor]->hid;
+
 	if (!dev->hid_output_raw_report)
 		return -ENODEV;
 
Signature · 1 line
1.7.4.4
#104 lore raw

PATCH 104/209 gianfar: Fix crashes on RX path (Was Re: [Bugme-new] [Bug 19692] New: linux-2.6.36-rc5 crash with gianfar ethernet at full line rate traffic)

In reply to Paul Gortmaker

From: Jarek Poplawski <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit cd0ea2419544cfc4ccbf8ee0087d0d9f109852d2 upstream.

The rx_recycle queue is global per device but can be accesed by many napi handlers at the same time, so it needs full skb_queue primitives (with locking). Otherwise, various crashes caused by broken skbs are possible.

This patch resolves, at least partly, bugzilla bug 19692. (Because of some doubts that there could be still something around which is hard to reproduce my proposal is to leave this bug opened for a month.)

Fixes commit: 0fd56bb5be6455d0d42241e65aed057244665e5e ("gianfar: Add support for skb recycling")

---
 drivers/net/gianfar.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)
drivers/net/gianfar.c +3 -3
index 5d3763f..58496d3 100644
@@ -2303,7 +2303,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
 		if (skb_queue_len(&priv->rx_recycle) < rx_queue->rx_ring_size &&
 				skb_recycle_check(skb, priv->rx_buffer_size +
 					RXBUF_ALIGNMENT))
-			__skb_queue_head(&priv->rx_recycle, skb);
+			skb_queue_head(&priv->rx_recycle, skb);
 		else
 			dev_kfree_skb_any(skb);
 
@@ -2374,7 +2374,7 @@ struct sk_buff * gfar_new_skb(struct net_device *dev)
 	struct gfar_private *priv = netdev_priv(dev);
 	struct sk_buff *skb = NULL;
 
-	skb = __skb_dequeue(&priv->rx_recycle);
+	skb = skb_dequeue(&priv->rx_recycle);
 	if (!skb)
 		skb = netdev_alloc_skb(dev,
 				priv->rx_buffer_size + RXBUF_ALIGNMENT);
@@ -2537,7 +2537,7 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit)
 				 * recycle list.
 				 */
 				skb_reserve(skb, -GFAR_CB(skb)->alignamount);
-				__skb_queue_head(&priv->rx_recycle, skb);
+				skb_queue_head(&priv->rx_recycle, skb);
 			}
 		} else {
 			/* Increment the number of packets */
Signature · 1 line
1.7.4.4
#105 lore raw

PATCH 105/209 net: avoid limits overflow

In reply to Paul Gortmaker

From: Eric Dumazet <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 8d987e5c75107ca7515fa19e857cfa24aab6ec8f upstream.

Robin Holt tried to boot a 16TB machine and found some limits were reached : sysctl_tcp_mem[2], sysctl_udp_mem[2]

We can switch infrastructure to use long "instead" of "int", now atomic_long_t primitives are available for free.

---
 include/net/dn.h               |    2 +-
 include/net/sock.h             |    4 ++--
 include/net/tcp.h              |    6 +++---
 include/net/udp.h              |    4 ++--
 net/core/sock.c                |   14 +++++++-------
 net/decnet/af_decnet.c         |    2 +-
 net/decnet/sysctl_net_decnet.c |    4 ++--
 net/ipv4/proc.c                |    8 ++++----
 net/ipv4/sysctl_net_ipv4.c     |    5 ++---
 net/ipv4/tcp.c                 |    4 ++--
 net/ipv4/tcp_input.c           |   11 +++++++----
 net/ipv4/udp.c                 |    4 ++--
 net/sctp/protocol.c            |    2 +-
 net/sctp/socket.c              |    4 ++--
 net/sctp/sysctl.c              |    4 ++--
 15 files changed, 40 insertions(+), 38 deletions(-)
include/net/dn.h +1 -1
index e5469f7..a514a3c 100644
@@ -225,7 +225,7 @@ extern int decnet_di_count;
 extern int decnet_dr_count;
 extern int decnet_no_fc_max_cwnd;
 
-extern int sysctl_decnet_mem[3];
+extern long sysctl_decnet_mem[3];
 extern int sysctl_decnet_wmem[3];
 extern int sysctl_decnet_rmem[3];
 
include/net/sock.h +2 -2
index efb5730..dc251e0 100644
@@ -707,7 +707,7 @@ struct proto {
 
 	/* Memory pressure */
 	void			(*enter_memory_pressure)(struct sock *sk);
-	atomic_t		*memory_allocated;	/* Current allocated memory. */
+	atomic_long_t		*memory_allocated;	/* Current allocated memory. */
 	struct percpu_counter	*sockets_allocated;	/* Current number of sockets. */
 	/*
 	 * Pressure flag: try to collapse.
@@ -716,7 +716,7 @@ struct proto {
 	 * is strict, actions are advisory and have some latency.
 	 */
 	int			*memory_pressure;
-	int			*sysctl_mem;
+	long			*sysctl_mem;
 	int			*sysctl_wmem;
 	int			*sysctl_rmem;
 	int			max_header;
include/net/tcp.h +3 -3
index 91cdffd..77502b4 100644
@@ -224,7 +224,7 @@ extern int sysctl_tcp_fack;
 extern int sysctl_tcp_reordering;
 extern int sysctl_tcp_ecn;
 extern int sysctl_tcp_dsack;
-extern int sysctl_tcp_mem[3];
+extern long sysctl_tcp_mem[3];
 extern int sysctl_tcp_wmem[3];
 extern int sysctl_tcp_rmem[3];
 extern int sysctl_tcp_app_win;
@@ -247,7 +247,7 @@ extern int sysctl_tcp_cookie_size;
 extern int sysctl_tcp_thin_linear_timeouts;
 extern int sysctl_tcp_thin_dupack;
 
-extern atomic_t tcp_memory_allocated;
+extern atomic_long_t tcp_memory_allocated;
 extern struct percpu_counter tcp_sockets_allocated;
 extern int tcp_memory_pressure;
 
@@ -280,7 +280,7 @@ static inline bool tcp_too_many_orphans(struct sock *sk, int shift)
 	}
 
 	if (sk->sk_wmem_queued > SOCK_MIN_SNDBUF &&
-	    atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2])
+	    atomic_long_read(&tcp_memory_allocated) > sysctl_tcp_mem[2])
 		return true;
 	return false;
 }
include/net/udp.h +2 -2
index 4201dc8..b02f5d9 100644
@@ -105,10 +105,10 @@ static inline struct udp_hslot *udp_hashslot2(struct udp_table *table,
 
 extern struct proto udp_prot;
 
-extern atomic_t udp_memory_allocated;
+extern atomic_long_t udp_memory_allocated;
 
 /* sysctl variables for udp */
-extern int sysctl_udp_mem[3];
+extern long sysctl_udp_mem[3];
 extern int sysctl_udp_rmem_min;
 extern int sysctl_udp_wmem_min;
 
net/core/sock.c +7 -7
index c5812bb..cf3b9aa 100644
@@ -1593,10 +1593,10 @@ int __sk_mem_schedule(struct sock *sk, int size, int kind)
 {
 	struct proto *prot = sk->sk_prot;
 	int amt = sk_mem_pages(size);
-	int allocated;
+	long allocated;
 
 	sk->sk_forward_alloc += amt * SK_MEM_QUANTUM;
-	allocated = atomic_add_return(amt, prot->memory_allocated);
+	allocated = atomic_long_add_return(amt, prot->memory_allocated);
 
 	/* Under limit. */
 	if (allocated <= prot->sysctl_mem[0]) {
@@ -1654,7 +1654,7 @@ suppress_allocation:
 
 	/* Alas. Undo changes. */
 	sk->sk_forward_alloc -= amt * SK_MEM_QUANTUM;
-	atomic_sub(amt, prot->memory_allocated);
+	atomic_long_sub(amt, prot->memory_allocated);
 	return 0;
 }
 EXPORT_SYMBOL(__sk_mem_schedule);
@@ -1667,12 +1667,12 @@ void __sk_mem_reclaim(struct sock *sk)
 {
 	struct proto *prot = sk->sk_prot;
 
-	atomic_sub(sk->sk_forward_alloc >> SK_MEM_QUANTUM_SHIFT,
+	atomic_long_sub(sk->sk_forward_alloc >> SK_MEM_QUANTUM_SHIFT,
 		   prot->memory_allocated);
 	sk->sk_forward_alloc &= SK_MEM_QUANTUM - 1;
 
 	if (prot->memory_pressure && *prot->memory_pressure &&
-	    (atomic_read(prot->memory_allocated) < prot->sysctl_mem[0]))
+	    (atomic_long_read(prot->memory_allocated) < prot->sysctl_mem[0]))
 		*prot->memory_pressure = 0;
 }
 EXPORT_SYMBOL(__sk_mem_reclaim);
@@ -2350,12 +2350,12 @@ static char proto_method_implemented(const void *method)
 
 static void proto_seq_printf(struct seq_file *seq, struct proto *proto)
 {
-	seq_printf(seq, "%-9s %4u %6d  %6d   %-3s %6u   %-3s  %-10s "
+	seq_printf(seq, "%-9s %4u %6d  %6ld   %-3s %6u   %-3s  %-10s "
 			"%2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c\n",
 		   proto->name,
 		   proto->obj_size,
 		   sock_prot_inuse_get(seq_file_net(seq), proto),
-		   proto->memory_allocated != NULL ? atomic_read(proto->memory_allocated) : -1,
+		   proto->memory_allocated != NULL ? atomic_long_read(proto->memory_allocated) : -1L,
 		   proto->memory_pressure != NULL ? *proto->memory_pressure ? "yes" : "no" : "NI",
 		   proto->max_header,
 		   proto->slab == NULL ? "no" : "yes",
net/decnet/af_decnet.c +1 -1
index 7cc13e1..057f40e 100644
@@ -155,7 +155,7 @@ static const struct proto_ops dn_proto_ops;
 static DEFINE_RWLOCK(dn_hash_lock);
 static struct hlist_head dn_sk_hash[DN_SK_HASH_SIZE];
 static struct hlist_head dn_wild_sk;
-static atomic_t decnet_memory_allocated;
+static atomic_long_t decnet_memory_allocated;
 
 static int __dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen, int flags);
 static int __dn_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen, int flags);
net/decnet/sysctl_net_decnet.c +2 -2
index be3eb8e..28f8b5e 100644
@@ -38,7 +38,7 @@ int decnet_log_martians = 1;
 int decnet_no_fc_max_cwnd = NSP_MIN_WINDOW;
 
 /* Reasonable defaults, I hope, based on tcp's defaults */
-int sysctl_decnet_mem[3] = { 768 << 3, 1024 << 3, 1536 << 3 };
+long sysctl_decnet_mem[3] = { 768 << 3, 1024 << 3, 1536 << 3 };
 int sysctl_decnet_wmem[3] = { 4 * 1024, 16 * 1024, 128 * 1024 };
 int sysctl_decnet_rmem[3] = { 4 * 1024, 87380, 87380 * 2 };
 
@@ -324,7 +324,7 @@ static ctl_table dn_table[] = {
 		.data = &sysctl_decnet_mem,
 		.maxlen = sizeof(sysctl_decnet_mem),
 		.mode = 0644,
-		.proc_handler = proc_dointvec,
+		.proc_handler = proc_doulongvec_minmax
 	},
 	{
 		.procname = "decnet_rmem",
net/ipv4/proc.c +4 -4
index 4f1f337..5a07771 100644
@@ -59,13 +59,13 @@ static int sockstat_seq_show(struct seq_file *seq, void *v)
 	local_bh_enable();
 
 	socket_seq_show(seq);
-	seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %d\n",
+	seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %ld\n",
 		   sock_prot_inuse_get(net, &tcp_prot), orphans,
 		   tcp_death_row.tw_count, sockets,
-		   atomic_read(&tcp_memory_allocated));
-	seq_printf(seq, "UDP: inuse %d mem %d\n",
+		   atomic_long_read(&tcp_memory_allocated));
+	seq_printf(seq, "UDP: inuse %d mem %ld\n",
 		   sock_prot_inuse_get(net, &udp_prot),
-		   atomic_read(&udp_memory_allocated));
+		   atomic_long_read(&udp_memory_allocated));
 	seq_printf(seq, "UDPLITE: inuse %d\n",
 		   sock_prot_inuse_get(net, &udplite_prot));
 	seq_printf(seq, "RAW: inuse %d\n",
net/ipv4/sysctl_net_ipv4.c +2 -3
index 1cd5c15..ea4a508 100644
@@ -391,7 +391,7 @@ static struct ctl_table ipv4_table[] = {
 		.data		= &sysctl_tcp_mem,
 		.maxlen		= sizeof(sysctl_tcp_mem),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler	= proc_doulongvec_minmax
 	},
 	{
 		.procname	= "tcp_wmem",
@@ -595,8 +595,7 @@ static struct ctl_table ipv4_table[] = {
 		.data		= &sysctl_udp_mem,
 		.maxlen		= sizeof(sysctl_udp_mem),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &zero
+		.proc_handler	= proc_doulongvec_minmax,
 	},
 	{
 		.procname	= "udp_rmem_min",
net/ipv4/tcp.c +2 -2
index 3fa16d9..68cd299 100644
@@ -282,7 +282,7 @@ int sysctl_tcp_fin_timeout __read_mostly = TCP_FIN_TIMEOUT;
 struct percpu_counter tcp_orphan_count;
 EXPORT_SYMBOL_GPL(tcp_orphan_count);
 
-int sysctl_tcp_mem[3] __read_mostly;
+long sysctl_tcp_mem[3] __read_mostly;
 int sysctl_tcp_wmem[3] __read_mostly;
 int sysctl_tcp_rmem[3] __read_mostly;
 
@@ -290,7 +290,7 @@ EXPORT_SYMBOL(sysctl_tcp_mem);
 EXPORT_SYMBOL(sysctl_tcp_rmem);
 EXPORT_SYMBOL(sysctl_tcp_wmem);
 
-atomic_t tcp_memory_allocated;	/* Current allocated memory. */
+atomic_long_t tcp_memory_allocated;	/* Current allocated memory. */
 EXPORT_SYMBOL(tcp_memory_allocated);
 
 /*
net/ipv4/tcp_input.c +7 -4
index dd0c9af..add69a1 100644
@@ -256,8 +256,11 @@ static void tcp_fixup_sndbuf(struct sock *sk)
 	int sndmem = tcp_sk(sk)->rx_opt.mss_clamp + MAX_TCP_HEADER + 16 +
 		     sizeof(struct sk_buff);
 
-	if (sk->sk_sndbuf < 3 * sndmem)
-		sk->sk_sndbuf = min(3 * sndmem, sysctl_tcp_wmem[2]);
+	if (sk->sk_sndbuf < 3 * sndmem) {
+		sk->sk_sndbuf = 3 * sndmem;
+		if (sk->sk_sndbuf > sysctl_tcp_wmem[2])
+			sk->sk_sndbuf = sysctl_tcp_wmem[2];
+	}
 }
 
 /* 2. Tuning advertised window (window_clamp, rcv_ssthresh)
@@ -393,7 +396,7 @@ static void tcp_clamp_window(struct sock *sk)
 	if (sk->sk_rcvbuf < sysctl_tcp_rmem[2] &&
 	    !(sk->sk_userlocks & SOCK_RCVBUF_LOCK) &&
 	    !tcp_memory_pressure &&
-	    atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) {
+	    atomic_long_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) {
 		sk->sk_rcvbuf = min(atomic_read(&sk->sk_rmem_alloc),
 				    sysctl_tcp_rmem[2]);
 	}
@@ -4860,7 +4863,7 @@ static int tcp_should_expand_sndbuf(struct sock *sk)
 		return 0;
 
 	/* If we are under soft global TCP memory pressure, do not expand.  */
-	if (atomic_read(&tcp_memory_allocated) >= sysctl_tcp_mem[0])
+	if (atomic_long_read(&tcp_memory_allocated) >= sysctl_tcp_mem[0])
 		return 0;
 
 	/* If we filled the congestion window, do not expand.  */
net/ipv4/udp.c +2 -2
index a4e2dee..fd510bc 100644
@@ -110,7 +110,7 @@
 struct udp_table udp_table __read_mostly;
 EXPORT_SYMBOL(udp_table);
 
-int sysctl_udp_mem[3] __read_mostly;
+long sysctl_udp_mem[3] __read_mostly;
 EXPORT_SYMBOL(sysctl_udp_mem);
 
 int sysctl_udp_rmem_min __read_mostly;
@@ -119,7 +119,7 @@ EXPORT_SYMBOL(sysctl_udp_rmem_min);
 int sysctl_udp_wmem_min __read_mostly;
 EXPORT_SYMBOL(sysctl_udp_wmem_min);
 
-atomic_t udp_memory_allocated;
+atomic_long_t udp_memory_allocated;
 EXPORT_SYMBOL(udp_memory_allocated);
 
 #define MAX_UDP_PORTS 65536
net/sctp/protocol.c +1 -1
index a56f98e..051b271 100644
@@ -90,7 +90,7 @@ static struct sctp_af *sctp_af_v6_specific;
 struct kmem_cache *sctp_chunk_cachep __read_mostly;
 struct kmem_cache *sctp_bucket_cachep __read_mostly;
 
-int sysctl_sctp_mem[3];
+long sysctl_sctp_mem[3];
 int sysctl_sctp_rmem[3];
 int sysctl_sctp_wmem[3];
 
net/sctp/socket.c +2 -2
index 44a1ab0..7f28df5 100644
@@ -109,12 +109,12 @@ static void sctp_sock_migrate(struct sock *, struct sock *,
 static char *sctp_hmac_alg = SCTP_COOKIE_HMAC_ALG;
 
 extern struct kmem_cache *sctp_bucket_cachep;
-extern int sysctl_sctp_mem[3];
+extern long sysctl_sctp_mem[3];
 extern int sysctl_sctp_rmem[3];
 extern int sysctl_sctp_wmem[3];
 
 static int sctp_memory_pressure;
-static atomic_t sctp_memory_allocated;
+static atomic_long_t sctp_memory_allocated;
 struct percpu_counter sctp_sockets_allocated;
 
 static void sctp_enter_memory_pressure(struct sock *sk)
net/sctp/sysctl.c +2 -2
index 832590b..50cb57f 100644
@@ -54,7 +54,7 @@ static int sack_timer_max = 500;
 static int addr_scope_max = 3; /* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */
 static int rwnd_scale_max = 16;
 
-extern int sysctl_sctp_mem[3];
+extern long sysctl_sctp_mem[3];
 extern int sysctl_sctp_rmem[3];
 extern int sysctl_sctp_wmem[3];
 
@@ -203,7 +203,7 @@ static ctl_table sctp_table[] = {
 		.data		= &sysctl_sctp_mem,
 		.maxlen		= sizeof(sysctl_sctp_mem),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler	= proc_doulongvec_minmax
 	},
 	{
 		.procname	= "sctp_rmem",
Signature · 1 line
1.7.4.4
#106 lore raw

PATCH 106/209 sysctl: min/max bounds are optional

In reply to Paul Gortmaker

From: Eric Dumazet <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit a9febbb4bd1302b6f01aa1203b0a804e4e5c9e25 upstream

sysctl check complains with a WARN() when proc_doulongvec_minmax() or proc_doulongvec_ms_jiffies_minmax() are used by a vector of longs (with more than one element), with no min or max value specified.

This is unexpected, given we had a bug on this min/max handling :)

---
 kernel/sysctl_check.c |    9 ---------
 1 files changed, 0 insertions(+), 9 deletions(-)
kernel/sysctl_check.c +0 -9
index 04cdcf7..10b90d8 100644
@@ -143,15 +143,6 @@ int sysctl_check_table(struct nsproxy *namespaces, struct ctl_table *table)
 				if (!table->maxlen)
 					set_fail(&fail, table, "No maxlen");
 			}
-			if ((table->proc_handler == proc_doulongvec_minmax) ||
-			    (table->proc_handler == proc_doulongvec_ms_jiffies_minmax)) {
-				if (table->maxlen > sizeof (unsigned long)) {
-					if (!table->extra1)
-						set_fail(&fail, table, "No min");
-					if (!table->extra2)
-						set_fail(&fail, table, "No max");
-				}
-			}
 #ifdef CONFIG_PROC_SYSCTL
 			if (table->procname && !table->proc_handler)
 				set_fail(&fail, table, "No proc_handler");
Signature · 1 line
1.7.4.4
#107 lore raw

PATCH 107/209 sysctl: fix min/max handling in __do_proc_doulongvec_minmax()

In reply to Paul Gortmaker

From: Eric Dumazet <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 27b3d80a7b6adcf069b5e869e4efcc3a79f88a91 upstream.

When proc_doulongvec_minmax() is used with an array of longs, and no min/max check requested (.extra1 or .extra2 being NULL), we dereference a NULL pointer for the second element of the array.

Noticed while doing some changes in network stack for the "16TB problem"

Fix is to not change min & max pointers in __do_proc_doulongvec_minmax(), so that all elements of the vector share an unique min/max limit, like proc_dointvec_minmax().

---
 kernel/sysctl.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
kernel/sysctl.c +1 -1
index 8686b0f..d2ceded 100644
@@ -2314,7 +2314,7 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int
 	vleft = table->maxlen / sizeof(unsigned long);
 	left = *lenp;
 	
-	for (; left && vleft--; i++, min++, max++, first=0) {
+	for (; left && vleft--; i++, first = 0) {
 		if (write) {
 			while (left) {
 				char c;
Signature · 1 line
1.7.4.4
#108 lore raw

PATCH 108/209 sparc64: Fix race in signal instruction flushing.

In reply to Paul Gortmaker

From: David S. Miller <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 05c5e7698bdc54b3079a3517d86077f49ebcc788 upstream.

If another cpu does a very wide munmap() on the signal frame area, it can tear down the page table hierarchy from underneath us.

Borrow an idea from the 64-bit fault path's get_user_insn(), and disable cross call interrupts during the page table traversal to lock them in place while we operate.

---
 arch/sparc/kernel/signal32.c |  102 ++++++++++++++++++++++++-----------------
 1 files changed, 60 insertions(+), 42 deletions(-)
arch/sparc/kernel/signal32.c +60 -42
index ea22cd3..76b67c4 100644
@@ -453,6 +453,64 @@ static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
 	return err;
 }
 
+/* The I-cache flush instruction only works in the primary ASI, which
+ * right now is the nucleus, aka. kernel space.
+ *
+ * Therefore we have to kick the instructions out using the kernel
+ * side linear mapping of the physical address backing the user
+ * instructions.
+ */
+static void flush_signal_insns(unsigned long address)
+{
+	unsigned long pstate, paddr;
+	pte_t *ptep, pte;
+	pgd_t *pgdp;
+	pud_t *pudp;
+	pmd_t *pmdp;
+
+	/* Commit all stores of the instructions we are about to flush.  */
+	wmb();
+
+	/* Disable cross-call reception.  In this way even a very wide
+	 * munmap() on another cpu can't tear down the page table
+	 * hierarchy from underneath us, since that can't complete
+	 * until the IPI tlb flush returns.
+	 */
+
+	__asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));
+	__asm__ __volatile__("wrpr %0, %1, %%pstate"
+				: : "r" (pstate), "i" (PSTATE_IE));
+
+	pgdp = pgd_offset(current->mm, address);
+	if (pgd_none(*pgdp))
+		goto out_irqs_on;
+	pudp = pud_offset(pgdp, address);
+	if (pud_none(*pudp))
+		goto out_irqs_on;
+	pmdp = pmd_offset(pudp, address);
+	if (pmd_none(*pmdp))
+		goto out_irqs_on;
+
+	ptep = pte_offset_map(pmdp, address);
+	pte = *ptep;
+	if (!pte_present(pte))
+		goto out_unmap;
+
+	paddr = (unsigned long) page_address(pte_page(pte));
+
+	__asm__ __volatile__("flush	%0 + %1"
+			     : /* no outputs */
+			     : "r" (paddr),
+			       "r" (address & (PAGE_SIZE - 1))
+			     : "memory");
+
+out_unmap:
+	pte_unmap(ptep);
+out_irqs_on:
+	__asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate));
+
+}
+
 static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
 			  int signo, sigset_t *oldset)
 {
@@ -547,13 +605,7 @@ static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
 	if (ka->ka_restorer) {
 		regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
 	} else {
-		/* Flush instruction space. */
 		unsigned long address = ((unsigned long)&(sf->insns[0]));
-		pgd_t *pgdp = pgd_offset(current->mm, address);
-		pud_t *pudp = pud_offset(pgdp, address);
-		pmd_t *pmdp = pmd_offset(pudp, address);
-		pte_t *ptep;
-		pte_t pte;
 
 		regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
 	
@@ -562,22 +614,7 @@ static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
 		if (err)
 			goto sigsegv;
 
-		preempt_disable();
-		ptep = pte_offset_map(pmdp, address);
-		pte = *ptep;
-		if (pte_present(pte)) {
-			unsigned long page = (unsigned long)
-				page_address(pte_page(pte));
-
-			wmb();
-			__asm__ __volatile__("flush	%0 + %1"
-					     : /* no outputs */
-					     : "r" (page),
-					       "r" (address & (PAGE_SIZE - 1))
-					     : "memory");
-		}
-		pte_unmap(ptep);
-		preempt_enable();
+		flush_signal_insns(address);
 	}
 	return;
 
@@ -687,12 +724,7 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
 	if (ka->ka_restorer)
 		regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
 	else {
-		/* Flush instruction space. */
 		unsigned long address = ((unsigned long)&(sf->insns[0]));
-		pgd_t *pgdp = pgd_offset(current->mm, address);
-		pud_t *pudp = pud_offset(pgdp, address);
-		pmd_t *pmdp = pmd_offset(pudp, address);
-		pte_t *ptep;
 
 		regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
 	
@@ -704,21 +736,7 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
 		if (err)
 			goto sigsegv;
 
-		preempt_disable();
-		ptep = pte_offset_map(pmdp, address);
-		if (pte_present(*ptep)) {
-			unsigned long page = (unsigned long)
-				page_address(pte_page(*ptep));
-
-			wmb();
-			__asm__ __volatile__("flush	%0 + %1"
-					     : /* no outputs */
-					     : "r" (page),
-					       "r" (address & (PAGE_SIZE - 1))
-					     : "memory");
-		}
-		pte_unmap(ptep);
-		preempt_enable();
+		flush_signal_insns(address);
 	}
 	return;
 
Signature · 1 line
1.7.4.4
#109 lore raw

PATCH 109/209 sparc: Don't mask signal when we can't setup signal frame.

In reply to Paul Gortmaker

From: David S. Miller <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 392c21802ee3aa85cee0e703105f797a8a7b9416 upstream.

Don't invoke the signal handler tracehook in that situation either.

---
 arch/sparc/kernel/signal32.c  |   55 +++++++++++++++++++++++++---------------
 arch/sparc/kernel/signal_32.c |   53 ++++++++++++++++++++++++---------------
 arch/sparc/kernel/signal_64.c |   43 +++++++++++++++++++------------
 3 files changed, 93 insertions(+), 58 deletions(-)
arch/sparc/kernel/signal32.c +34 -21
index 76b67c4..643a354 100644
@@ -511,8 +511,8 @@ out_irqs_on:
 
 }
 
-static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
-			  int signo, sigset_t *oldset)
+static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
+			 int signo, sigset_t *oldset)
 {
 	struct signal_frame32 __user *sf;
 	int sigframe_size;
@@ -620,13 +620,16 @@ static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
 
 sigill:
 	do_exit(SIGILL);
+	return -EINVAL;
+
 sigsegv:
 	force_sigsegv(signo, current);
+	return -EFAULT;
 }
 
-static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
-			     unsigned long signr, sigset_t *oldset,
-			     siginfo_t *info)
+static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
+			    unsigned long signr, sigset_t *oldset,
+			    siginfo_t *info)
 {
 	struct rt_signal_frame32 __user *sf;
 	int sigframe_size;
@@ -738,22 +741,30 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
 
 		flush_signal_insns(address);
 	}
-	return;
+	return 0;
 
 sigill:
 	do_exit(SIGILL);
+	return -EINVAL;
+
 sigsegv:
 	force_sigsegv(signr, current);
+	return -EFAULT;
 }
 
-static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
-				   siginfo_t *info,
-				   sigset_t *oldset, struct pt_regs *regs)
+static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka,
+				  siginfo_t *info,
+				  sigset_t *oldset, struct pt_regs *regs)
 {
+	int err;
+
 	if (ka->sa.sa_flags & SA_SIGINFO)
-		setup_rt_frame32(ka, regs, signr, oldset, info);
+		err = setup_rt_frame32(ka, regs, signr, oldset, info);
 	else
-		setup_frame32(ka, regs, signr, oldset);
+		err = setup_frame32(ka, regs, signr, oldset);
+
+	if (err)
+		return err;
 
 	spin_lock_irq(&current->sighand->siglock);
 	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
@@ -761,6 +772,10 @@ static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
 		sigaddset(&current->blocked,signr);
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
+
+	tracehook_signal_handler(signr, info, ka, regs, 0);
+
+	return 0;
 }
 
 static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs,
@@ -807,16 +822,14 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs,
 	if (signr > 0) {
 		if (restart_syscall)
 			syscall_restart32(orig_i0, regs, &ka.sa);
-		handle_signal32(signr, &ka, &info, oldset, regs);
-
-		/* A signal was successfully delivered; the saved
-		 * sigmask will have been stored in the signal frame,
-		 * and will be restored by sigreturn, so we can simply
-		 * clear the TS_RESTORE_SIGMASK flag.
-		 */
-		current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
-
-		tracehook_signal_handler(signr, &info, &ka, regs, 0);
+		if (handle_signal32(signr, &ka, &info, oldset, regs) == 0) {
+			/* A signal was successfully delivered; the saved
+			 * sigmask will have been stored in the signal frame,
+			 * and will be restored by sigreturn, so we can simply
+			 * clear the TS_RESTORE_SIGMASK flag.
+			 */
+			current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
+		}
 		return;
 	}
 	if (restart_syscall &&
arch/sparc/kernel/signal_32.c +33 -20

102 lines not on this page · raw message

arch/sparc/kernel/signal_64.c +26 -17

75 lines not on this page · raw message

Signature · 1 line
1.7.4.4
#110 lore raw

PATCH 110/209 sparc: Prevent no-handler signal syscall restart recursion.

In reply to Paul Gortmaker

From: David S. Miller <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit c27852597829128a9c9d96d79ec454a83c6b0da5 upstream.

Explicitly clear the "in-syscall" bit when we have no signal handler and back up the program counters to back up the system call.

---
 arch/sparc/kernel/signal32.c  |    4 +++-
 arch/sparc/kernel/signal_32.c |    2 ++
 arch/sparc/kernel/signal_64.c |    2 ++
 3 files changed, 7 insertions(+), 1 deletions(-)
arch/sparc/kernel/signal32.c +3 -1
index 643a354..75fad42 100644
@@ -616,7 +616,7 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
 
 		flush_signal_insns(address);
 	}
-	return;
+	return 0;
 
 sigill:
 	do_exit(SIGILL);
@@ -840,12 +840,14 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs,
 		regs->u_regs[UREG_I0] = orig_i0;
 		regs->tpc -= 4;
 		regs->tnpc -= 4;
+		pt_regs_clear_syscall(regs);
 	}
 	if (restart_syscall &&
 	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
 		regs->u_regs[UREG_G1] = __NR_restart_syscall;
 		regs->tpc -= 4;
 		regs->tnpc -= 4;
+		pt_regs_clear_syscall(regs);
 	}
 
 	/* If there's no signal to deliver, we just put the saved sigmask
arch/sparc/kernel/signal_32.c +2 -0
index 99c85e9..5e5c5fd 100644
@@ -580,12 +580,14 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
 		regs->u_regs[UREG_I0] = orig_i0;
 		regs->pc -= 4;
 		regs->npc -= 4;
+		pt_regs_clear_syscall(regs);
 	}
 	if (restart_syscall &&
 	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
 		regs->u_regs[UREG_G1] = __NR_restart_syscall;
 		regs->pc -= 4;
 		regs->npc -= 4;
+		pt_regs_clear_syscall(regs);
 	}
 
 	/* if there's no signal to deliver, we just put the saved sigmask
arch/sparc/kernel/signal_64.c +2 -0
index 3f19e67..006fe45 100644
@@ -600,12 +600,14 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
 		regs->u_regs[UREG_I0] = orig_i0;
 		regs->tpc -= 4;
 		regs->tnpc -= 4;
+		pt_regs_clear_syscall(regs);
 	}
 	if (restart_syscall &&
 	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
 		regs->u_regs[UREG_G1] = __NR_restart_syscall;
 		regs->tpc -= 4;
 		regs->tnpc -= 4;
+		pt_regs_clear_syscall(regs);
 	}
 
 	/* If there's no signal to deliver, we just put the saved sigmask
Signature · 1 line
1.7.4.4
#111 lore raw

PATCH 111/209 x86, UV: Delete unneeded boot messages

In reply to Paul Gortmaker

From: Jack Steiner <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 2acebe9ecb2b77876e87a1480729cfb2db4570dd upstream.

SGI:UV: Delete extra boot messages that describe the system topology. These messages are no longer useful.

LKML-Reference: <[email protected]>

---
 arch/x86/kernel/apic/x2apic_uv_x.c |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)
arch/x86/kernel/apic/x2apic_uv_x.c +0 -3
index c085d52..e46f98f 100644
@@ -735,9 +735,6 @@ void __init uv_system_init(void)
 		uv_node_to_blade[nid] = blade;
 		uv_cpu_to_blade[cpu] = blade;
 		max_pnode = max(pnode, max_pnode);
-
-		printk(KERN_DEBUG "UV: cpu %d, apicid 0x%x, pnode %d, nid %d, lcpu %d, blade %d\n",
-			cpu, apicid, pnode, nid, lcpu, blade);
 	}
 
 	/* Add blade/pnode info for nodes without cpus */
Signature · 1 line
1.7.4.4
#112 lore raw

PATCH 112/209 x86, UV: Fix initialization of max_pnode

In reply to Paul Gortmaker

From: Jack Steiner <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 36ac4b987bea9a95217e1af552252f275ca7fc44 upstream.

Fix calculation of "max_pnode" for systems where the the highest blade has neither cpus or memory. (And, yes, although rare this does occur).

LKML-Reference: <[email protected]>

---
 arch/x86/kernel/apic/x2apic_uv_x.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)
arch/x86/kernel/apic/x2apic_uv_x.c +3 -3
index e46f98f..25a1b3c 100644
@@ -694,9 +694,11 @@ void __init uv_system_init(void)
 		for (j = 0; j < 64; j++) {
 			if (!test_bit(j, &present))
 				continue;
-			uv_blade_info[blade].pnode = (i * 64 + j);
+			pnode = (i * 64 + j);
+			uv_blade_info[blade].pnode = pnode;
 			uv_blade_info[blade].nr_possible_cpus = 0;
 			uv_blade_info[blade].nr_online_cpus = 0;
+			max_pnode = max(pnode, max_pnode);
 			blade++;
 		}
 	}
@@ -734,7 +736,6 @@ void __init uv_system_init(void)
 		uv_cpu_hub_info(cpu)->scir.offset = uv_scir_offset(apicid);
 		uv_node_to_blade[nid] = blade;
 		uv_cpu_to_blade[cpu] = blade;
-		max_pnode = max(pnode, max_pnode);
 	}
 
 	/* Add blade/pnode info for nodes without cpus */
@@ -746,7 +747,6 @@ void __init uv_system_init(void)
 		pnode = (paddr >> m_val) & pnode_mask;
 		blade = boot_pnode_to_blade(pnode);
 		uv_node_to_blade[nid] = blade;
-		max_pnode = max(pnode, max_pnode);
 	}
 
 	map_gru_high(max_pnode);
Signature · 1 line
1.7.4.4
#113 lore raw

PATCH 113/209 efifb: support the EFI framebuffer on more Apple hardware

In reply to Paul Gortmaker

From: Luke Macken <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit a5757c2a474a15f87e5baa9a4caacc31cde2bae6 upstream.

Enable the EFI framebuffer on 14 more Macs, including the iMac11,1 iMac10,1 iMac8,1 Macmini3,1 Macmini4,1 MacBook5,1 MacBook6,1 MacBook7,1 MacBookPro2,2 MacBookPro5,2 MacBookPro5,3 MacBookPro6,1 MacBookPro6,2 and MacBookPro7,1

Information gathered from various user submissions.

    https://bugzilla.redhat.com/show_bug.cgi?id=528232
    http://ubuntuforums.org/showthread.php?t=1557326
---
 drivers/video/efifb.c |   42 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 42 insertions(+), 0 deletions(-)
drivers/video/efifb.c +42 -0
index e090f8e..709eae1 100644
@@ -39,17 +39,31 @@ enum {
 	M_I20,		/* 20-Inch iMac */
 	M_I20_SR,	/* 20-Inch iMac (Santa Rosa) */
 	M_I24,		/* 24-Inch iMac */
+	M_I24_8_1,	/* 24-Inch iMac, 8,1th gen */
+	M_I24_10_1,	/* 24-Inch iMac, 10,1th gen */
+	M_I27_11_1,	/* 27-Inch iMac, 11,1th gen */
 	M_MINI,		/* Mac Mini */
+	M_MINI_3_1,	/* Mac Mini, 3,1th gen */
+	M_MINI_4_1,	/* Mac Mini, 4,1th gen */
 	M_MB,		/* MacBook */
 	M_MB_2,		/* MacBook, 2nd rev. */
 	M_MB_3,		/* MacBook, 3rd rev. */
+	M_MB_5_1,	/* MacBook, 5th rev. */
+	M_MB_6_1,	/* MacBook, 6th rev. */
+	M_MB_7_1,	/* MacBook, 7th rev. */
 	M_MB_SR,	/* MacBook, 2nd gen, (Santa Rosa) */
 	M_MBA,		/* MacBook Air */
 	M_MBP,		/* MacBook Pro */
 	M_MBP_2,	/* MacBook Pro 2nd gen */
+	M_MBP_2_2,	/* MacBook Pro 2,2nd gen */
 	M_MBP_SR,	/* MacBook Pro (Santa Rosa) */
 	M_MBP_4,	/* MacBook Pro, 4th gen */
 	M_MBP_5_1,    /* MacBook Pro, 5,1th gen */
+	M_MBP_5_2,	/* MacBook Pro, 5,2th gen */
+	M_MBP_5_3,	/* MacBook Pro, 5,3rd gen */
+	M_MBP_6_1,	/* MacBook Pro, 6,1th gen */
+	M_MBP_6_2,	/* MacBook Pro, 6,2th gen */
+	M_MBP_7_1,	/* MacBook Pro, 7,1th gen */
 	M_UNKNOWN	/* placeholder */
 };
 
@@ -64,14 +78,28 @@ static struct efifb_dmi_info {
 	[M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050 }, /* guess */
 	[M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050 },
 	[M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200 }, /* guess */
+	[M_I24_8_1] = { "imac8", 0xc0060000, 2048 * 4, 1920, 1200 },
+	[M_I24_10_1] = { "imac10", 0xc0010000, 2048 * 4, 1920, 1080 },
+	[M_I27_11_1] = { "imac11", 0xc0010000, 2560 * 4, 2560, 1440 },
 	[M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768 },
+	[M_MINI_3_1] = { "mini31", 0x40010000, 1024 * 4, 1024, 768 },
+	[M_MINI_4_1] = { "mini41", 0xc0010000, 2048 * 4, 1920, 1200 },
 	[M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800 },
+	[M_MB_5_1] = { "macbook51", 0x80010000, 2048 * 4, 1280, 800 },
+	[M_MB_6_1] = { "macbook61", 0x80010000, 2048 * 4, 1280, 800 },
+	[M_MB_7_1] = { "macbook71", 0x80010000, 2048 * 4, 1280, 800 },
 	[M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800 },
 	[M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900 },
 	[M_MBP_2] = { "mbp2", 0, 0, 0, 0 }, /* placeholder */
+	[M_MBP_2_2] = { "mbp22", 0x80010000, 1472 * 4, 1440, 900 },
 	[M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900 },
 	[M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200 },
 	[M_MBP_5_1] = { "mbp51", 0xc0010000, 2048 * 4, 1440, 900 },
+	[M_MBP_5_2] = { "mbp52", 0xc0010000, 2048 * 4, 1920, 1200 },
+	[M_MBP_5_3] = { "mbp53", 0xd0010000, 2048 * 4, 1440, 900 },
+	[M_MBP_6_1] = { "mbp61", 0x90030000, 2048 * 4, 1920, 1200 },
+	[M_MBP_6_2] = { "mbp62", 0x90030000, 2048 * 4, 1680, 1050 },
+	[M_MBP_7_1] = { "mbp71", 0xc0010000, 2048 * 4, 1280, 800 },
 	[M_UNKNOWN] = { NULL, 0, 0, 0, 0 }
 };
 
@@ -92,7 +120,12 @@ static struct dmi_system_id __initdata dmi_system_table[] = {
 	EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac6,1", M_I24),
 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac6,1", M_I24),
 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac7,1", M_I20_SR),
+	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac8,1", M_I24_8_1),
+	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac10,1", M_I24_10_1),
+	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac11,1", M_I27_11_1),
 	EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "Macmini1,1", M_MINI),
+	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini3,1", M_MINI_3_1),
+	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini4,1", M_MINI_4_1),
 	EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook1,1", M_MB),
 	/* At least one of these two will be right; maybe both? */
 	EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook2,1", M_MB),
@@ -101,14 +134,23 @@ static struct dmi_system_id __initdata dmi_system_table[] = {
 	EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook3,1", M_MB),
 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook3,1", M_MB),
 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook4,1", M_MB),
+	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook5,1", M_MB_5_1),
+	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook6,1", M_MB_6_1),
+	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook7,1", M_MB_7_1),
 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir1,1", M_MBA),
 	EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro1,1", M_MBP),
 	EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,1", M_MBP_2),
+	EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,2", M_MBP_2_2),
 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro2,1", M_MBP_2),
 	EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro3,1", M_MBP_SR),
 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro3,1", M_MBP_SR),
 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro4,1", M_MBP_4),
 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,1", M_MBP_5_1),
+	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,2", M_MBP_5_2),
+	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,3", M_MBP_5_3),
+	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,1", M_MBP_6_1),
+	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,2", M_MBP_6_2),
+	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro7,1", M_MBP_7_1),
 	{},
 };
 
Signature · 1 line
1.7.4.4
#114 lore raw

PATCH 114/209 Input: i8042 - add Sony VAIO VPCZ122GX to nomux list

In reply to Paul Gortmaker

From: Dmitry Torokhov <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

[Note that the mainline will not have this particular fix but rather will blacklist entire VAIO line based off DMI board name. For stable I am being a bit more cautious and blacklist one particular product.]

Trying to query/activate active multiplexing mode on this VAIO makes both keyboard and touchpad inoperable. Futher kernels will blacklist entire VAIO line, however here we blacklist just one particular model.

[PG: mainline commit for blacklist is 73b14484fb686252aaf4aac4fa65b4]

---
 drivers/input/serio/i8042-x86ia64io.h |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)
drivers/input/serio/i8042-x86ia64io.h +7 -0
index c452504..8f46380 100644
@@ -329,6 +329,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
 		},
 	},
 	{
+		/* Sony Vaio VPCZ122GX */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "VPCZ122GX"),
+		},
+	},
+	{
 		/* Sony Vaio FS-115b */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
Signature · 1 line
1.7.4.4
#115 lore raw

PATCH 115/209 memory corruption in X.25 facilities parsing

From: andrew hendry <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit a6331d6f9a4298173b413cf99a40cc86a9d92c37 upstream.

---
 net/x25/x25_facilities.c |    8 ++++----
 net/x25/x25_in.c         |    2 ++
 2 files changed, 6 insertions(+), 4 deletions(-)
net/x25/x25_facilities.c +4 -4
index 771bab0..3a8c4c4 100644
@@ -134,15 +134,15 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
 		case X25_FAC_CLASS_D:
 			switch (*p) {
 			case X25_FAC_CALLING_AE:
-				if (p[1] > X25_MAX_DTE_FACIL_LEN)
-					break;
+				if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1)
+					return 0;
 				dte_facs->calling_len = p[2];
 				memcpy(dte_facs->calling_ae, &p[3], p[1] - 1);
 				*vc_fac_mask |= X25_MASK_CALLING_AE;
 				break;
 			case X25_FAC_CALLED_AE:
-				if (p[1] > X25_MAX_DTE_FACIL_LEN)
-					break;
+				if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1)
+					return 0;
 				dte_facs->called_len = p[2];
 				memcpy(dte_facs->called_ae, &p[3], p[1] - 1);
 				*vc_fac_mask |= X25_MASK_CALLED_AE;
net/x25/x25_in.c +2 -0
index 372ac22..3b67027 100644
@@ -119,6 +119,8 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp
 						&x25->vc_facil_mask);
 			if (len > 0)
 				skb_pull(skb, len);
+			else
+				return -1;
 			/*
 			 *	Copy any Call User Data.
 			 */
Signature · 1 line
1.7.4.4
#116 lore raw

PATCH 116/209 can-bcm: fix minor heap overflow

In reply to Paul Gortmaker

From: Oliver Hartkopp <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 0597d1b99fcfc2c0eada09a698f85ed413d4ba84 upstream.

On 64-bit platforms the ASCII representation of a pointer may be up to 17 bytes long. This patch increases the length of the buffer accordingly.

http://marc.info/?l=linux-netdev&m=128872251418192&w=2

---
 net/can/bcm.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
net/can/bcm.c +1 -1
index e10ee05..b8f7a2f 100644
@@ -125,7 +125,7 @@ struct bcm_sock {
 	struct list_head tx_ops;
 	unsigned long dropped_usr_msgs;
 	struct proc_dir_entry *bcm_proc_read;
-	char procname [9]; /* pointer printed in ASCII with \0 */
+	char procname [20]; /* pointer printed in ASCII with \0 */
 };
 
 static inline struct bcm_sock *bcm_sk(const struct sock *sk)
Signature · 1 line
1.7.4.4
#117 lore raw

PATCH 117/209 V4L/DVB: ivtvfb: prevent reading uninitialized stack memory

In reply to Paul Gortmaker

From: Dan Rosenberg <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 405707985594169cfd0b1d97d29fcb4b4c6f2ac9 upstream.

The FBIOGET_VBLANK device ioctl allows unprivileged users to read 16 bytes of uninitialized stack memory, because the "reserved" member of the fb_vblank struct declared on the stack is not altered or zeroed before being copied back to the user. This patch takes care of it.

---
 drivers/media/video/ivtv/ivtvfb.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
drivers/media/video/ivtv/ivtvfb.c +2 -0
index de2ff1c..e320b7e 100644
@@ -458,6 +458,8 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar
 			struct fb_vblank vblank;
 			u32 trace;
 
+			memset(&vblank, 0, sizeof(struct fb_vblank));
+
 			vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT |
 					FB_VBLANK_HAVE_VSYNC;
 			trace = read_reg(0x028c0) >> 16;
Signature · 1 line
1.7.4.4
#118 lore raw

PATCH 118/209 x25: Prevent crashing when parsing bad X.25 facilities

In reply to Paul Gortmaker

From: Dan Rosenberg <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 5ef41308f94dcbb3b7afc56cdef1c2ba53fa5d2f upstream.

Now with improved comma support.

On parsing malformed X.25 facilities, decrementing the remaining length may cause it to underflow. Since the length is an unsigned integer, this will result in the loop continuing until the kernel crashes.

This patch adds checks to ensure decrementing the remaining length does not cause it to wrap around.

---
 net/x25/x25_facilities.c |   12 +++++++++---
 1 files changed, 9 insertions(+), 3 deletions(-)
net/x25/x25_facilities.c +9 -3
index 3a8c4c4..55187c8 100644
@@ -61,6 +61,8 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
 	while (len > 0) {
 		switch (*p & X25_FAC_CLASS_MASK) {
 		case X25_FAC_CLASS_A:
+			if (len < 2)
+				return 0;
 			switch (*p) {
 			case X25_FAC_REVERSE:
 				if((p[1] & 0x81) == 0x81) {
@@ -104,6 +106,8 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
 			len -= 2;
 			break;
 		case X25_FAC_CLASS_B:
+			if (len < 3)
+				return 0;
 			switch (*p) {
 			case X25_FAC_PACKET_SIZE:
 				facilities->pacsize_in  = p[1];
@@ -125,6 +129,8 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
 			len -= 3;
 			break;
 		case X25_FAC_CLASS_C:
+			if (len < 4)
+				return 0;
 			printk(KERN_DEBUG "X.25: unknown facility %02X, "
 			       "values %02X, %02X, %02X\n",
 			       p[0], p[1], p[2], p[3]);
@@ -132,6 +138,8 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
 			len -= 4;
 			break;
 		case X25_FAC_CLASS_D:
+			if (len < p[1] + 2)
+				return 0;
 			switch (*p) {
 			case X25_FAC_CALLING_AE:
 				if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1)
@@ -149,9 +157,7 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
 				break;
 			default:
 				printk(KERN_DEBUG "X.25: unknown facility %02X,"
-					"length %d, values %02X, %02X, "
-					"%02X, %02X\n",
-					p[0], p[1], p[2], p[3], p[4], p[5]);
+					"length %d\n", p[0], p[1]);
 				break;
 			}
 			len -= p[1] + 2;
Signature · 1 line
1.7.4.4
#119 lore raw

PATCH 119/209 crypto: padlock - Fix AES-CBC handling on odd-block-sized input

In reply to Paul Gortmaker

From: Herbert Xu <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit c054a076a1bd4731820a9c4d638b13d5c9bf5935 upstream.

On certain VIA chipsets AES-CBC requires the input/output to be a multiple of 64 bytes. We had a workaround for this but it was buggy as it sent the whole input for processing when it is meant to only send the initial number of blocks which makes the rest a multiple of 64 bytes.

As expected this causes memory corruption whenever the workaround kicks in.

---
 drivers/crypto/padlock-aes.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/crypto/padlock-aes.c +1 -1
index 2e992bc..8a515ba 100644
@@ -286,7 +286,7 @@ static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key,
 	if (initial)
 		asm volatile (".byte 0xf3,0x0f,0xa7,0xd0"	/* rep xcryptcbc */
 			      : "+S" (input), "+D" (output), "+a" (iv)
-			      : "d" (control_word), "b" (key), "c" (count));
+			      : "d" (control_word), "b" (key), "c" (initial));
 
 	asm volatile (".byte 0xf3,0x0f,0xa7,0xd0"	/* rep xcryptcbc */
 		      : "+S" (input), "+D" (output), "+a" (iv)
Signature · 1 line
1.7.4.4
#120 lore raw

PATCH 120/209 x86-32: Separate 1:1 pagetables from swapper_pg_dir

In reply to Paul Gortmaker

From: Joerg Roedel <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit fd89a137924e0710078c3ae855e7cec1c43cb845 upstream.

This patch fixes machine crashes which occur when heavily exercising the CPU hotplug codepaths on a 32-bit kernel. These crashes are caused by AMD Erratum 383 and result in a fatal machine check exception. Here's the scenario:

1. On 32-bit, the swapper_pg_dir page table is used as the initial page table for booting a secondary CPU.

2. To make this work, swapper_pg_dir needs a direct mapping of physical memory in it (the low mappings). By adding those low, large page (2M) mappings (PAE kernel), we create the necessary conditions for Erratum 383 to occur.

3. Other CPUs which do not participate in the off- and onlining game may use swapper_pg_dir while the low mappings are present (when leave_mm is called). For all steps below, the CPU referred to is a CPU that is using swapper_pg_dir, and not the CPU which is being onlined.

4. The presence of the low mappings in swapper_pg_dir can result in TLB entries for addresses below __PAGE_OFFSET to be established speculatively. These TLB entries are marked global and large.

5. When the CPU with such TLB entry switches to another page table, this TLB entry remains because it is global.

6. The process then generates an access to an address covered by the above TLB entry but there is a permission mismatch - the TLB entry covers a large global page not accessible to userspace.

7. Due to this permission mismatch a new 4kb, user TLB entry gets established. Further, Erratum 383 provides for a small window of time where both TLB entries are present. This results in an uncorrectable machine check exception signalling a TLB multimatch which panics the machine.

There are two ways to fix this issue:

1. Always do a global TLB flush when a new cr3 is loaded and the old page table was swapper_pg_dir. I consider this a hack hard to understand and with performance implications

2. Do not use swapper_pg_dir to boot secondary CPUs like 64-bit does.

This patch implements solution 2. It introduces a trampoline_pg_dir which has the same layout as swapper_pg_dir with low_mappings. This page table is used as the initial page table of the booting CPU. Later in the bringup process, it switches to swapper_pg_dir and does a global TLB flush. This fixes the crashes in our test cases.

-v2: switch to swapper_pg_dir right after entering start_secondary() so that we are able to access percpu data which might not be mapped in the trampoline page table.

LKML-Reference: <20100816123833.GB28147@aftab>

---
 arch/x86/include/asm/pgtable_32.h |    1 +
 arch/x86/include/asm/trampoline.h |    3 +++
 arch/x86/kernel/head_32.S         |    8 +++++++-
 arch/x86/kernel/setup.c           |    2 ++
 arch/x86/kernel/smpboot.c         |   32 +++++++++++++-------------------
 arch/x86/kernel/trampoline.c      |   18 ++++++++++++++++++
 6 files changed, 44 insertions(+), 20 deletions(-)
arch/x86/include/asm/pgtable_32.h +1 -0
index 2984a25..f686f49 100644
@@ -26,6 +26,7 @@ struct mm_struct;
 struct vm_area_struct;
 
 extern pgd_t swapper_pg_dir[1024];
+extern pgd_t trampoline_pg_dir[1024];
 
 static inline void pgtable_cache_init(void) { }
 static inline void check_pgt_cache(void) { }
arch/x86/include/asm/trampoline.h +3 -0
index cb507bb..8f78fdf 100644
@@ -13,14 +13,17 @@ extern unsigned char *trampoline_base;
 
 extern unsigned long init_rsp;
 extern unsigned long initial_code;
+extern unsigned long initial_page_table;
 extern unsigned long initial_gs;
 
 #define TRAMPOLINE_SIZE roundup(trampoline_end - trampoline_data, PAGE_SIZE)
 
 extern unsigned long setup_trampoline(void);
+extern void __init setup_trampoline_page_table(void);
 extern void __init reserve_trampoline_memory(void);
 #else
 static inline void reserve_trampoline_memory(void) {};
+extern void __init setup_trampoline_page_table(void) {};
 #endif /* CONFIG_X86_TRAMPOLINE */
 
 #endif /* __ASSEMBLY__ */
arch/x86/kernel/head_32.S +7 -1
index 37c3d4b..75e3981 100644
@@ -328,7 +328,7 @@ ENTRY(startup_32_smp)
 /*
  * Enable paging
  */
-	movl $pa(swapper_pg_dir),%eax
+	movl pa(initial_page_table), %eax
 	movl %eax,%cr3		/* set the page table pointer.. */
 	movl %cr0,%eax
 	orl  $X86_CR0_PG,%eax
@@ -608,6 +608,8 @@ ignore_int:
 .align 4
 ENTRY(initial_code)
 	.long i386_start_kernel
+ENTRY(initial_page_table)
+	.long pa(swapper_pg_dir)
 
 /*
  * BSS section
@@ -623,6 +625,10 @@ ENTRY(swapper_pg_dir)
 #endif
 swapper_pg_fixmap:
 	.fill 1024,4,0
+#ifdef CONFIG_X86_TRAMPOLINE
+ENTRY(trampoline_pg_dir)
+	.fill 1024,4,0
+#endif
 ENTRY(empty_zero_page)
 	.fill 4096,1,0
 
arch/x86/kernel/setup.c +2 -0
index 47ae912..7e201cc 100644
@@ -1007,6 +1007,8 @@ void __init setup_arch(char **cmdline_p)
 	paging_init();
 	x86_init.paging.pagetable_setup_done(swapper_pg_dir);
 
+	setup_trampoline_page_table();
+
 	tboot_probe();
 
 #ifdef CONFIG_X86_64
arch/x86/kernel/smpboot.c +13 -19
index 8931d05..4ea2f50 100644
@@ -73,7 +73,6 @@
 
 #ifdef CONFIG_X86_32
 u8 apicid_2_node[MAX_APICID];
-static int low_mappings;
 #endif
 
 /* State of each CPU */
@@ -300,6 +299,18 @@ notrace static void __cpuinit start_secondary(void *unused)
 	 * fragile that we want to limit the things done here to the
 	 * most necessary things.
 	 */
+
+#ifdef CONFIG_X86_32
+	/*
+	 * Switch away from the trampoline page-table
+	 *
+	 * Do this before cpu_init() because it needs to access per-cpu
+	 * data which may not be mapped in the trampoline page-table.
+	 */
+	load_cr3(swapper_pg_dir);
+	__flush_tlb_all();
+#endif
+
 	vmi_bringup();
 	cpu_init();
 	preempt_disable();
@@ -318,12 +329,6 @@ notrace static void __cpuinit start_secondary(void *unused)
 		legacy_pic->chip->unmask(0);
 	}
 
-#ifdef CONFIG_X86_32
-	while (low_mappings)
-		cpu_relax();
-	__flush_tlb_all();
-#endif
-
 	/* This must be done before setting cpu_online_mask */
 	set_cpu_sibling_map(raw_smp_processor_id());
 	wmb();
@@ -773,6 +778,7 @@ do_rest:
 #ifdef CONFIG_X86_32
 	/* Stack for startup_32 can be just as for start_secondary onwards */
 	irq_ctx_init(cpu);
+	initial_page_table = __pa(&trampoline_pg_dir);
 #else
 	clear_tsk_thread_flag(c_idle.idle, TIF_FORK);
 	initial_gs = per_cpu_offset(cpu);
@@ -913,20 +919,8 @@ int __cpuinit native_cpu_up(unsigned int cpu)
 
 	per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
 
-#ifdef CONFIG_X86_32
-	/* init low mem mapping */
-	clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
-		min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
-	flush_tlb_all();
-	low_mappings = 1;
-
 	err = do_boot_cpu(apicid, cpu);
 
-	zap_low_mappings(false);
-	low_mappings = 0;
-#else
-	err = do_boot_cpu(apicid, cpu);
-#endif
 	if (err) {
 		pr_debug("do_boot_cpu failed %d\n", err);
 		return -EIO;
arch/x86/kernel/trampoline.c +18 -0
index c652ef6..a874495 100644
@@ -1,6 +1,7 @@
 #include <linux/io.h>
 
 #include <asm/trampoline.h>
+#include <asm/pgtable.h>
 #include <asm/e820.h>
 
 #if defined(CONFIG_X86_64) && defined(CONFIG_ACPI_SLEEP)
@@ -37,3 +38,20 @@ unsigned long __trampinit setup_trampoline(void)
 	memcpy(trampoline_base, trampoline_data, TRAMPOLINE_SIZE);
 	return virt_to_phys(trampoline_base);
 }
+
+void __init setup_trampoline_page_table(void)
+{
+#ifdef CONFIG_X86_32
+	/* Copy kernel address range */
+	clone_pgd_range(trampoline_pg_dir + KERNEL_PGD_BOUNDARY,
+			swapper_pg_dir + KERNEL_PGD_BOUNDARY,
+			min_t(unsigned long, KERNEL_PGD_PTRS,
+			      KERNEL_PGD_BOUNDARY));
+
+	/* Initialize low mappings */
+	clone_pgd_range(trampoline_pg_dir,
+			swapper_pg_dir + KERNEL_PGD_BOUNDARY,
+			min_t(unsigned long, KERNEL_PGD_PTRS,
+			      KERNEL_PGD_BOUNDARY));
+#endif
+}
Signature · 1 line
1.7.4.4
#121 lore raw

PATCH 121/209 x86, mm: Fix CONFIG_VMSPLIT_1G and 2G_OPT trampoline

In reply to Paul Gortmaker

From: Hugh Dickins <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit b7d460897739e02f186425b7276e3fdb1595cea7 upstream.

rc2 kernel crashes when booting second cpu on this CONFIG_VMSPLIT_2G_OPT
laptop: whereas cloning from kernel to low mappings pgd range does need to limit by both KERNEL_PGD_PTRS and KERNEL_PGD_BOUNDARY, cloning kernel pgd range itself must not be limited by the smaller KERNEL_PGD_BOUNDARY.

LKML-Reference: <[email protected]>

---
 arch/x86/kernel/trampoline.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)
arch/x86/kernel/trampoline.c +1 -2
index a874495..e2a5952 100644
@@ -45,8 +45,7 @@ void __init setup_trampoline_page_table(void)
 	/* Copy kernel address range */
 	clone_pgd_range(trampoline_pg_dir + KERNEL_PGD_BOUNDARY,
 			swapper_pg_dir + KERNEL_PGD_BOUNDARY,
-			min_t(unsigned long, KERNEL_PGD_PTRS,
-			      KERNEL_PGD_BOUNDARY));
+			KERNEL_PGD_PTRS);
 
 	/* Initialize low mappings */
 	clone_pgd_range(trampoline_pg_dir,
Signature · 1 line
1.7.4.4
#122 lore raw

PATCH 122/209 x86-32: Fix dummy trampoline-related inline stubs

In reply to Paul Gortmaker

From: H. Peter Anvin <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 8848a91068c018bc91f597038a0f41462a0f88a4 upstream.

Fix dummy inline stubs for trampoline-related functions when no trampolines exist (until we get rid of the no-trampoline case entirely.)

Cc Joerg Roedel <[email protected]>
Cc Borislav Petkov <[email protected]>

LKML-Reference: <[email protected]>

---
 arch/x86/include/asm/trampoline.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
arch/x86/include/asm/trampoline.h +2 -2
index 8f78fdf..4dde797 100644
@@ -22,8 +22,8 @@ extern unsigned long setup_trampoline(void);
 extern void __init setup_trampoline_page_table(void);
 extern void __init reserve_trampoline_memory(void);
 #else
-static inline void reserve_trampoline_memory(void) {};
-extern void __init setup_trampoline_page_table(void) {};
+static inline void setup_trampoline_page_table(void) {}
+static inline void reserve_trampoline_memory(void) {}
 #endif /* CONFIG_X86_TRAMPOLINE */
 
 #endif /* __ASSEMBLY__ */
Signature · 1 line
1.7.4.4
#123 lore raw

PATCH 123/209 econet: disallow NULL remote addr for sendmsg(), fixes CVE-2010-3849

In reply to Paul Gortmaker

From: Phil Blundell <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit fa0e846494792e722d817b9d3d625a4ef4896c96 upstream.

Later parts of econet_sendmsg() rely on saddr != NULL, so return early with EINVAL if NULL was passed otherwise an oops may occur.

---
 net/econet/af_econet.c |   26 ++++++++------------------
 1 files changed, 8 insertions(+), 18 deletions(-)
net/econet/af_econet.c +8 -18
index 2a5a805..8170acb 100644
@@ -297,23 +297,14 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
 
 	mutex_lock(&econet_mutex);
 
-	if (saddr == NULL) {
-		struct econet_sock *eo = ec_sk(sk);
-
-		addr.station = eo->station;
-		addr.net     = eo->net;
-		port	     = eo->port;
-		cb	     = eo->cb;
-	} else {
-		if (msg->msg_namelen < sizeof(struct sockaddr_ec)) {
-			mutex_unlock(&econet_mutex);
-			return -EINVAL;
-		}
-		addr.station = saddr->addr.station;
-		addr.net = saddr->addr.net;
-		port = saddr->port;
-		cb = saddr->cb;
-	}
+        if (saddr == NULL || msg->msg_namelen < sizeof(struct sockaddr_ec)) {
+                mutex_unlock(&econet_mutex);
+                return -EINVAL;
+        }
+        addr.station = saddr->addr.station;
+        addr.net = saddr->addr.net;
+        port = saddr->port;
+        cb = saddr->cb;
 
 	/* Look for a device with the right network number. */
 	dev = net2dev_map[addr.net];
@@ -351,7 +342,6 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
 
 		eb = (struct ec_cb *)&skb->cb;
 
-		/* BUG: saddr may be NULL */
 		eb->cookie = saddr->cookie;
 		eb->sec = *saddr;
 		eb->sent = ec_tx_done;
Signature · 1 line
1.7.4.4
#124 lore raw

PATCH 124/209 econet: fix CVE-2010-3850

In reply to Paul Gortmaker

From: Phil Blundell <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 16c41745c7b92a243d0874f534c1655196c64b74 upstream.

Add missing check for capable(CAP_NET_ADMIN) in SIOCSIFADDR operation.

---
 net/econet/af_econet.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)
net/econet/af_econet.c +3 -0
index 8170acb..cd62e27 100644
@@ -661,6 +661,9 @@ static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg)
 	err = 0;
 	switch (cmd) {
 	case SIOCSIFADDR:
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+
 		edev = dev->ec_ptr;
 		if (edev == NULL) {
 			/* Magic up a new one. */
Signature · 1 line
1.7.4.4
#125 lore raw

PATCH 125/209 rds: Integer overflow in RDS cmsg handling

In reply to Paul Gortmaker

From: Dan Rosenberg <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 218854af84038d828a32f061858b1902ed2beec6 upstream.

In rds_cmsg_rdma_args(), the user-provided args->nr_local value is restricted to less than UINT_MAX. This seems to need a tighter upper bound, since the calculation of total iov_size can overflow, resulting in a small sock_kmalloc() allocation. This would probably just result in walking off the heap and crashing when calling rds_rdma_pages() with a high count value. If it somehow doesn't crash here, then memory corruption could occur soon after.

---
 net/rds/rdma.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
net/rds/rdma.c +1 -1
index 5ce9437..cf0dfa7 100644
@@ -472,7 +472,7 @@ static struct rds_rdma_op *rds_rdma_prepare(struct rds_sock *rs,
 		goto out;
 	}
 
-	if (args->nr_local > (u64)UINT_MAX) {
+	if (args->nr_local > UIO_MAXIOV) {
 		ret = -EMSGSIZE;
 		goto out;
 	}
Signature · 1 line
1.7.4.4
#126 lore raw

PATCH 126/209 net: Truncate recvfrom and sendto length to INT_MAX.

In reply to Paul Gortmaker

From: Linus Torvalds <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 253eacc070b114c2ec1f81b067d2fed7305467b0 upstream.

---
 net/socket.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)
net/socket.c +4 -0
index 5e8d0af..c63ebf4 100644
@@ -1672,6 +1672,8 @@ SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len,
 	struct iovec iov;
 	int fput_needed;
 
+	if (len > INT_MAX)
+		len = INT_MAX;
 	sock = sockfd_lookup_light(fd, &err, &fput_needed);
 	if (!sock)
 		goto out;
@@ -1729,6 +1731,8 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
 	int err, err2;
 	int fput_needed;
 
+	if (size > INT_MAX)
+		size = INT_MAX;
 	sock = sockfd_lookup_light(fd, &err, &fput_needed);
 	if (!sock)
 		goto out;
Signature · 1 line
1.7.4.4
#127 lore raw

PATCH 127/209 net: Limit socket I/O iovec total length to INT_MAX.

In reply to Paul Gortmaker

From: David S. Miller <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 8acfe468b0384e834a303f08ebc4953d72fb690a upstream.

This helps protect us from overflow issues down in the individual protocol sendmsg/recvmsg handlers. Once we hit INT_MAX we truncate out the rest of the iovec by setting the iov_len members to zero.

This works because:

1) For SOCK_STREAM and SOCK_SEQPACKET sockets, partial writes are allowed and the application will just continue with another write to send the rest of the data.

2) For datagram oriented sockets, where there must be a one-to-one correspondance between write() calls and packets on the wire, INT_MAX is going to be far larger than the packet size limit the protocol is going to check for and signal with -EMSGSIZE.

Based upon a patch by Linus Torvalds.

---
 include/linux/socket.h |    2 +-
 net/compat.c           |   10 ++++++----
 net/core/iovec.c       |   20 +++++++++-----------
 3 files changed, 16 insertions(+), 16 deletions(-)
include/linux/socket.h +1 -1
index 1b5034a..354cc56 100644
@@ -314,7 +314,7 @@ extern int csum_partial_copy_fromiovecend(unsigned char *kdata,
 					  int offset, 
 					  unsigned int len, __wsum *csump);
 
-extern long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode);
+extern int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode);
 extern int memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len);
 extern int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata,
 			     int offset, int len);
net/compat.c +6 -4
index ec24d9e..b869534 100644
@@ -41,10 +41,12 @@ static inline int iov_from_user_compat_to_kern(struct iovec *kiov,
 		compat_size_t len;
 
 		if (get_user(len, &uiov32->iov_len) ||
-		   get_user(buf, &uiov32->iov_base)) {
-			tot_len = -EFAULT;
-			break;
-		}
+		    get_user(buf, &uiov32->iov_base))
+			return -EFAULT;
+
+		if (len > INT_MAX - tot_len)
+			len = INT_MAX - tot_len;
+
 		tot_len += len;
 		kiov->iov_base = compat_ptr(buf);
 		kiov->iov_len = (__kernel_size_t) len;
net/core/iovec.c +9 -11
index b5b28f0..16ed584 100644
@@ -35,10 +35,9 @@
  *	in any case.
  */
 
-long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode)
+int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode)
 {
-	int size, ct;
-	long err;
+	int size, ct, err;
 
 	if (m->msg_namelen) {
 		if (mode == VERIFY_READ) {
@@ -60,14 +59,13 @@ long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address,
 	err = 0;
 
 	for (ct = 0; ct < m->msg_iovlen; ct++) {
-		err += iov[ct].iov_len;
-		/*
-		 * Goal is not to verify user data, but to prevent returning
-		 * negative value, which is interpreted as errno.
-		 * Overflow is still possible, but it is harmless.
-		 */
-		if (err < 0)
-			return -EMSGSIZE;
+		size_t len = iov[ct].iov_len;
+
+		if (len > INT_MAX - err) {
+			len = INT_MAX - err;
+			iov[ct].iov_len = len;
+		}
+		err += len;
 	}
 
 	return err;
Signature · 1 line
1.7.4.4
#128 lore raw

PATCH 128/209 nmi: fix clock comparator revalidation

In reply to Paul Gortmaker

From: Heiko Carstens <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit e8129c642155616d9e2160a75f103e127c8c3708 upstream.

On each machine check all registers are revalidated. The save area for the clock comparator however only contains the upper most seven bytes of the former contents, if valid.
Therefore the machine check handler uses a store clock instruction to get the current time and writes that to the clock comparator register which in turn will generate an immediate timer interrupt. However within the lowcore the expected time of the next timer interrupt is stored. If the interrupt happens before that time the handler won't be called. In turn the clock comparator won't be reprogrammed and therefore the interrupt condition stays pending which causes an interrupt loop until the expected time is reached.

On NOHZ machines this can result in unresponsive machines since the time of the next expected interrupted can be a couple of days in the future.

To fix this just revalidate the clock comparator register with the expected value.
In addition the special handling for udelay must be changed as well.

---
 arch/s390/kernel/nmi.c |   10 ++++------
 arch/s390/lib/delay.c  |   14 +++++++++-----
 2 files changed, 13 insertions(+), 11 deletions(-)
arch/s390/kernel/nmi.c +4 -6
index 015e27d..31bc708 100644
@@ -95,7 +95,6 @@ EXPORT_SYMBOL_GPL(s390_handle_mcck);
 static int notrace s390_revalidate_registers(struct mci *mci)
 {
 	int kill_task;
-	u64 tmpclock;
 	u64 zero;
 	void *fpt_save_area, *fpt_creg_save_area;
 
@@ -214,11 +213,10 @@ static int notrace s390_revalidate_registers(struct mci *mci)
 			: "0", "cc");
 #endif
 	/* Revalidate clock comparator register */
-	asm volatile(
-		"	stck	0(%1)\n"
-		"	sckc	0(%1)"
-		: "=m" (tmpclock) : "a" (&(tmpclock)) : "cc", "memory");
-
+	if (S390_lowcore.clock_comparator == -1)
+		set_clock_comparator(S390_lowcore.mcck_clock);
+	else
+		set_clock_comparator(S390_lowcore.clock_comparator);
 	/* Check if old PSW is valid */
 	if (!mci->wp)
 		/*
arch/s390/lib/delay.c +9 -5
index 752b362..7c37ec3 100644
@@ -29,17 +29,21 @@ static void __udelay_disabled(unsigned long long usecs)
 {
 	unsigned long mask, cr0, cr0_saved;
 	u64 clock_saved;
+	u64 end;
 
+	mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT;
+	end = get_clock() + (usecs << 12);
 	clock_saved = local_tick_disable();
-	set_clock_comparator(get_clock() + (usecs << 12));
 	__ctl_store(cr0_saved, 0, 0);
 	cr0 = (cr0_saved & 0xffff00e0) | 0x00000800;
 	__ctl_load(cr0 , 0, 0);
-	mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT;
 	lockdep_off();
-	trace_hardirqs_on();
-	__load_psw_mask(mask);
-	local_irq_disable();
+	do {
+		set_clock_comparator(end);
+		trace_hardirqs_on();
+		__load_psw_mask(mask);
+		local_irq_disable();
+	} while (get_clock() < end);
 	lockdep_on();
 	__ctl_load(cr0_saved, 0, 0);
 	local_tick_enable(clock_saved);
Signature · 1 line
1.7.4.4
#129 lore raw

PATCH 129/209 act_nat: use stack variable

In reply to Paul Gortmaker

From: Changli Gao <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 504f85c9d05f7c605306e808f0d835fe11bfd18d upstream.

act_nat: use stack variable

structure tc_nat isn't too big for stack, so we can put it in stack.

---
 net/sched/act_nat.c |   31 ++++++++++---------------------
 1 files changed, 10 insertions(+), 21 deletions(-)
net/sched/act_nat.c +10 -21
index 37e198c..3e593a8 100644
@@ -261,40 +261,29 @@ static int tcf_nat_dump(struct sk_buff *skb, struct tc_action *a,
 {
 	unsigned char *b = skb_tail_pointer(skb);
 	struct tcf_nat *p = a->priv;
-	struct tc_nat *opt;
+	struct tc_nat opt;
 	struct tcf_t t;
-	int s;
 
-	s = sizeof(*opt);
+	opt.old_addr = p->old_addr;
+	opt.new_addr = p->new_addr;
+	opt.mask = p->mask;
+	opt.flags = p->flags;
 
-	/* netlink spinlocks held above us - must use ATOMIC */
-	opt = kzalloc(s, GFP_ATOMIC);
-	if (unlikely(!opt))
-		return -ENOBUFS;
+	opt.index = p->tcf_index;
+	opt.action = p->tcf_action;
+	opt.refcnt = p->tcf_refcnt - ref;
+	opt.bindcnt = p->tcf_bindcnt - bind;
 
-	opt->old_addr = p->old_addr;
-	opt->new_addr = p->new_addr;
-	opt->mask = p->mask;
-	opt->flags = p->flags;
-
-	opt->index = p->tcf_index;
-	opt->action = p->tcf_action;
-	opt->refcnt = p->tcf_refcnt - ref;
-	opt->bindcnt = p->tcf_bindcnt - bind;
-
-	NLA_PUT(skb, TCA_NAT_PARMS, s, opt);
+	NLA_PUT(skb, TCA_NAT_PARMS, sizeof(opt), &opt);
 	t.install = jiffies_to_clock_t(jiffies - p->tcf_tm.install);
 	t.lastuse = jiffies_to_clock_t(jiffies - p->tcf_tm.lastuse);
 	t.expires = jiffies_to_clock_t(p->tcf_tm.expires);
 	NLA_PUT(skb, TCA_NAT_TM, sizeof(t), &t);
 
-	kfree(opt);
-
 	return skb->len;
 
 nla_put_failure:
 	nlmsg_trim(skb, b);
-	kfree(opt);
 	return -1;
 }
 
Signature · 1 line
1.7.4.4
#130 lore raw

PATCH 130/209 net sched: fix some kernel memory leaks

In reply to Paul Gortmaker

From: Eric Dumazet <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 1c40be12f7d8ca1d387510d39787b12e512a7ce8 upstream.

We leak at least 32bits of kernel memory to user land in tc dump, because we dont init all fields (capab ?) of the dumped structure.

Use C99 initializers so that holes and non explicit fields are zeroed.

---
 net/sched/act_gact.c    |   21 ++++++++++++---------
 net/sched/act_mirred.c  |   15 ++++++++-------
 net/sched/act_nat.c     |   22 +++++++++++-----------
 net/sched/act_simple.c  |   11 ++++++-----
 net/sched/act_skbedit.c |   11 ++++++-----
 5 files changed, 43 insertions(+), 37 deletions(-)
net/sched/act_gact.c +12 -9
index e7f796a..f9fc6ec 100644
@@ -152,21 +152,24 @@ static int tcf_gact(struct sk_buff *skb, struct tc_action *a, struct tcf_result
 static int tcf_gact_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
 {
 	unsigned char *b = skb_tail_pointer(skb);
-	struct tc_gact opt;
 	struct tcf_gact *gact = a->priv;
+	struct tc_gact opt = {
+		.index   = gact->tcf_index,
+		.refcnt  = gact->tcf_refcnt - ref,
+		.bindcnt = gact->tcf_bindcnt - bind,
+		.action  = gact->tcf_action,
+	};
 	struct tcf_t t;
 
-	opt.index = gact->tcf_index;
-	opt.refcnt = gact->tcf_refcnt - ref;
-	opt.bindcnt = gact->tcf_bindcnt - bind;
-	opt.action = gact->tcf_action;
 	NLA_PUT(skb, TCA_GACT_PARMS, sizeof(opt), &opt);
 #ifdef CONFIG_GACT_PROB
 	if (gact->tcfg_ptype) {
-		struct tc_gact_p p_opt;
-		p_opt.paction = gact->tcfg_paction;
-		p_opt.pval = gact->tcfg_pval;
-		p_opt.ptype = gact->tcfg_ptype;
+		struct tc_gact_p p_opt = {
+			.paction = gact->tcfg_paction,
+			.pval    = gact->tcfg_pval,
+			.ptype   = gact->tcfg_ptype,
+		};
+
 		NLA_PUT(skb, TCA_GACT_PROB, sizeof(p_opt), &p_opt);
 	}
 #endif
net/sched/act_mirred.c +8 -7
index c046682..7f9c54f 100644
@@ -211,15 +211,16 @@ static int tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind, i
 {
 	unsigned char *b = skb_tail_pointer(skb);
 	struct tcf_mirred *m = a->priv;
-	struct tc_mirred opt;
+	struct tc_mirred opt = {
+		.index   = m->tcf_index,
+		.action  = m->tcf_action,
+		.refcnt  = m->tcf_refcnt - ref,
+		.bindcnt = m->tcf_bindcnt - bind,
+		.eaction = m->tcfm_eaction,
+		.ifindex = m->tcfm_ifindex,
+	};
 	struct tcf_t t;
 
-	opt.index = m->tcf_index;
-	opt.action = m->tcf_action;
-	opt.refcnt = m->tcf_refcnt - ref;
-	opt.bindcnt = m->tcf_bindcnt - bind;
-	opt.eaction = m->tcfm_eaction;
-	opt.ifindex = m->tcfm_ifindex;
 	NLA_PUT(skb, TCA_MIRRED_PARMS, sizeof(opt), &opt);
 	t.install = jiffies_to_clock_t(jiffies - m->tcf_tm.install);
 	t.lastuse = jiffies_to_clock_t(jiffies - m->tcf_tm.lastuse);
net/sched/act_nat.c +11 -11
index 3e593a8..047c234 100644
@@ -261,19 +261,19 @@ static int tcf_nat_dump(struct sk_buff *skb, struct tc_action *a,
 {
 	unsigned char *b = skb_tail_pointer(skb);
 	struct tcf_nat *p = a->priv;
-	struct tc_nat opt;
+	struct tc_nat opt = {
+		.old_addr = p->old_addr,
+		.new_addr = p->new_addr,
+		.mask     = p->mask,
+		.flags    = p->flags,
+
+		.index    = p->tcf_index,
+		.action   = p->tcf_action,
+		.refcnt   = p->tcf_refcnt - ref,
+		.bindcnt  = p->tcf_bindcnt - bind,
+	};
 	struct tcf_t t;
 
-	opt.old_addr = p->old_addr;
-	opt.new_addr = p->new_addr;
-	opt.mask = p->mask;
-	opt.flags = p->flags;
-
-	opt.index = p->tcf_index;
-	opt.action = p->tcf_action;
-	opt.refcnt = p->tcf_refcnt - ref;
-	opt.bindcnt = p->tcf_bindcnt - bind;
-
 	NLA_PUT(skb, TCA_NAT_PARMS, sizeof(opt), &opt);
 	t.install = jiffies_to_clock_t(jiffies - p->tcf_tm.install);
 	t.lastuse = jiffies_to_clock_t(jiffies - p->tcf_tm.lastuse);
net/sched/act_simple.c +6 -5
index 622ca80..a697576 100644
@@ -164,13 +164,14 @@ static inline int tcf_simp_dump(struct sk_buff *skb, struct tc_action *a,
 {
 	unsigned char *b = skb_tail_pointer(skb);
 	struct tcf_defact *d = a->priv;
-	struct tc_defact opt;
+	struct tc_defact opt = {
+		.index   = d->tcf_index,
+		.refcnt  = d->tcf_refcnt - ref,
+		.bindcnt = d->tcf_bindcnt - bind,
+		.action  = d->tcf_action,
+	};
 	struct tcf_t t;
 
-	opt.index = d->tcf_index;
-	opt.refcnt = d->tcf_refcnt - ref;
-	opt.bindcnt = d->tcf_bindcnt - bind;
-	opt.action = d->tcf_action;
 	NLA_PUT(skb, TCA_DEF_PARMS, sizeof(opt), &opt);
 	NLA_PUT_STRING(skb, TCA_DEF_DATA, d->tcfd_defdata);
 	t.install = jiffies_to_clock_t(jiffies - d->tcf_tm.install);
net/sched/act_skbedit.c +6 -5
index e9607fe..66cbf4e 100644
@@ -159,13 +159,14 @@ static inline int tcf_skbedit_dump(struct sk_buff *skb, struct tc_action *a,
 {
 	unsigned char *b = skb_tail_pointer(skb);
 	struct tcf_skbedit *d = a->priv;
-	struct tc_skbedit opt;
+	struct tc_skbedit opt = {
+		.index   = d->tcf_index,
+		.refcnt  = d->tcf_refcnt - ref,
+		.bindcnt = d->tcf_bindcnt - bind,
+		.action  = d->tcf_action,
+	};
 	struct tcf_t t;
 
-	opt.index = d->tcf_index;
-	opt.refcnt = d->tcf_refcnt - ref;
-	opt.bindcnt = d->tcf_bindcnt - bind;
-	opt.action = d->tcf_action;
 	NLA_PUT(skb, TCA_SKBEDIT_PARMS, sizeof(opt), &opt);
 	if (d->flags & SKBEDIT_F_PRIORITY)
 		NLA_PUT(skb, TCA_SKBEDIT_PRIORITY, sizeof(d->priority),
Signature · 1 line
1.7.4.4
#131 lore raw

PATCH 131/209 Fix pktcdvd ioctl dev_minor range check

In reply to Paul Gortmaker

From: Dan Rosenberg <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 252a52aa4fa22a668f019e55b3aac3ff71ec1c29 upstream

The PKT_CTRL_CMD_STATUS device ioctl retrieves a pointer to a pktcdvd_device from the global pkt_devs array. The index into this array is provided directly by the user and is a signed integer, so the comparison to ensure that it falls within the bounds of this array will fail when provided with a negative index.

This can be used to read arbitrary kernel memory or cause a crash due to an invalid pointer dereference. This can be exploited by users with permission to open /dev/pktcdvd/control (on many distributions, this is readable by group "cdrom").

[ Rather than add a cast, just make the function take the right type -Linus ]
---
 drivers/block/pktcdvd.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/block/pktcdvd.c +1 -1
index 8a549db..8403fd5 100644
@@ -2368,7 +2368,7 @@ static void pkt_release_dev(struct pktcdvd_device *pd, int flush)
 	pkt_shrink_pktlist(pd);
 }
 
-static struct pktcdvd_device *pkt_find_dev_from_minor(int dev_minor)
+static struct pktcdvd_device *pkt_find_dev_from_minor(unsigned int dev_minor)
 {
 	if (dev_minor >= MAX_WRITERS)
 		return NULL;
Signature · 1 line
1.7.4.4
#132 lore raw

PATCH 132/209 TTY: don't allow reopen when ldisc is changing

In reply to Paul Gortmaker

From: Jiri Slaby <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit e2efafbf139d2bfdfe96f2901f03189fecd172e4 upstream

There are many WARNINGs like the following reported nowadays:

WARNING: at drivers/tty/tty_io.c:1331 tty_open+0x2a2/0x49a()
Hardware name: Latitude E6500
Modules linked in:
Pid: 1207, comm: plymouthd Not tainted 2.6.37-rc3-mmotm1123 #3
Call Trace:
 [<ffffffff8103b189>] warn_slowpath_common+0x80/0x98
 [<ffffffff8103b1b6>] warn_slowpath_null+0x15/0x17
 [<ffffffff8128a3ab>] tty_open+0x2a2/0x49a
 [<ffffffff810fd53f>] chrdev_open+0x11d/0x146

...

This means tty_reopen is called without TTY_LDISC set. For further considerations, note tty_lock is held in tty_open. TTY_LDISC is cleared in:
1) __tty_hangup from tty_ldisc_hangup to tty_ldisc_enable. During this section tty_lock is held. However tty_lock is temporarily dropped in the middle of the function by tty_ldisc_hangup.

2) tty_release via tty_ldisc_release till the end of tty existence. If tty->count <= 1, tty_lock is taken, TTY_CLOSING bit set and then tty_ldisc_release called. tty_reopen checks TTY_CLOSING before checking TTY_LDISC.

3) tty_set_ldisc from tty_ldisc_halt to tty_ldisc_enable. We:
* take tty_lock, set TTY_LDISC_CHANGING, put tty_lock
* call tty_ldisc_halt (clear TTY_LDISC), tty_lock is _not_ held
* do some other work
* take tty_lock, call tty_ldisc_enable (set TTY_LDISC), put tty_lock

I cannot see how 2) can be a problem, as there I see no race. OTOH, 1) and 3) can happen without problems. This patch the case 3) by checking TTY_LDISC_CHANGING along with TTY_CLOSING in tty_reopen. 1) will be fixed in the following patch.

Nicely reproducible with two processes:

while (1) {
	fd = open("/dev/ttyS1", O_RDWR);
	if (fd < 0) {
		warn("open");
		continue;
	}
	close(fd);
}
--------
while (1) {
        fd = open("/dev/ttyS1", O_RDWR);
        ld1 = 0; ld2 = 2;
        while (1) {
                ioctl(fd, TIOCSETD, &ld1);
                ioctl(fd, TIOCSETD, &ld2);
        }
        close(fd);
}
---
 drivers/char/tty_io.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
drivers/char/tty_io.c +2 -1
index d71f0fc..bc4f45d 100644
@@ -1257,7 +1257,8 @@ static int tty_reopen(struct tty_struct *tty)
 {
 	struct tty_driver *driver = tty->driver;
 
-	if (test_bit(TTY_CLOSING, &tty->flags))
+	if (test_bit(TTY_CLOSING, &tty->flags) ||
+			test_bit(TTY_LDISC_CHANGING, &tty->flags))
 		return -EIO;
 
 	if (driver->type == TTY_DRIVER_TYPE_PTY &&
Signature · 1 line
1.7.4.4
#133 lore raw

PATCH 133/209 econet: fix CVE-2010-3848

In reply to Paul Gortmaker

From: Phil Blundell <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit a27e13d370415add3487949c60810e36069a23a6 upstream

Don't declare variable sized array of iovecs on the stack since this could cause stack overflow if msg->msgiovlen is large. Instead, coalesce the user-supplied data into a new buffer and use a single iovec for it.

---
 net/econet/af_econet.c |   62 ++++++++++++++++++++++++------------------------
 1 files changed, 31 insertions(+), 31 deletions(-)
net/econet/af_econet.c +31 -31
index cd62e27..2e41c76 100644
@@ -31,6 +31,7 @@
 #include <linux/skbuff.h>
 #include <linux/udp.h>
 #include <linux/slab.h>
+#include <linux/vmalloc.h>
 #include <net/sock.h>
 #include <net/inet_common.h>
 #include <linux/stat.h>
@@ -276,12 +277,12 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
 #endif
 #ifdef CONFIG_ECONET_AUNUDP
 	struct msghdr udpmsg;
-	struct iovec iov[msg->msg_iovlen+1];
+	struct iovec iov[2];
 	struct aunhdr ah;
 	struct sockaddr_in udpdest;
 	__kernel_size_t size;
-	int i;
 	mm_segment_t oldfs;
+	char *userbuf;
 #endif
 
 	/*
@@ -319,17 +320,17 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
 		}
 	}
 
-	if (len + 15 > dev->mtu) {
-		mutex_unlock(&econet_mutex);
-		return -EMSGSIZE;
-	}
-
 	if (dev->type == ARPHRD_ECONET) {
 		/* Real hardware Econet.  We're not worthy etc. */
 #ifdef CONFIG_ECONET_NATIVE
 		unsigned short proto = 0;
 		int res;
 
+		if (len + 15 > dev->mtu) {
+			mutex_unlock(&econet_mutex);
+			return -EMSGSIZE;
+		}
+
 		dev_hold(dev);
 
 		skb = sock_alloc_send_skb(sk, len+LL_ALLOCATED_SPACE(dev),
@@ -405,6 +406,11 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
 		return -ENETDOWN;		/* No socket - can't send */
 	}
 
+	if (len > 32768) {
+		err = -E2BIG;
+		goto error;
+	}
+
 	/* Make up a UDP datagram and hand it off to some higher intellect. */
 
 	memset(&udpdest, 0, sizeof(udpdest));
@@ -436,36 +442,26 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
 
 	/* tack our header on the front of the iovec */
 	size = sizeof(struct aunhdr);
-	/*
-	 * XXX: that is b0rken.  We can't mix userland and kernel pointers
-	 * in iovec, since on a lot of platforms copy_from_user() will
-	 * *not* work with the kernel and userland ones at the same time,
-	 * regardless of what we do with set_fs().  And we are talking about
-	 * econet-over-ethernet here, so "it's only ARM anyway" doesn't
-	 * apply.  Any suggestions on fixing that code?		-- AV
-	 */
 	iov[0].iov_base = (void *)&ah;
 	iov[0].iov_len = size;
-	for (i = 0; i < msg->msg_iovlen; i++) {
-		void __user *base = msg->msg_iov[i].iov_base;
-		size_t iov_len = msg->msg_iov[i].iov_len;
-		/* Check it now since we switch to KERNEL_DS later. */
-		if (!access_ok(VERIFY_READ, base, iov_len)) {
-			mutex_unlock(&econet_mutex);
-			return -EFAULT;
-		}
-		iov[i+1].iov_base = base;
-		iov[i+1].iov_len = iov_len;
-		size += iov_len;
+
+	userbuf = vmalloc(len);
+	if (userbuf == NULL) {
+		err = -ENOMEM;
+		goto error;
 	}
 
+	iov[1].iov_base = userbuf;
+	iov[1].iov_len = len;
+	err = memcpy_fromiovec(userbuf, msg->msg_iov, len);
+	if (err)
+		goto error_free_buf;
+
 	/* Get a skbuff (no data, just holds our cb information) */
 	if ((skb = sock_alloc_send_skb(sk, 0,
 				       msg->msg_flags & MSG_DONTWAIT,
-				       &err)) == NULL) {
-		mutex_unlock(&econet_mutex);
-		return err;
-	}
+				       &err)) == NULL)
+		goto error_free_buf;
 
 	eb = (struct ec_cb *)&skb->cb;
 
@@ -481,7 +477,7 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
 	udpmsg.msg_name = (void *)&udpdest;
 	udpmsg.msg_namelen = sizeof(udpdest);
 	udpmsg.msg_iov = &iov[0];
-	udpmsg.msg_iovlen = msg->msg_iovlen + 1;
+	udpmsg.msg_iovlen = 2;
 	udpmsg.msg_control = NULL;
 	udpmsg.msg_controllen = 0;
 	udpmsg.msg_flags=0;
@@ -489,9 +485,13 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
 	oldfs = get_fs(); set_fs(KERNEL_DS);	/* More privs :-) */
 	err = sock_sendmsg(udpsock, &udpmsg, size);
 	set_fs(oldfs);
+
+error_free_buf:
+	vfree(userbuf);
 #else
 	err = -EPROTOTYPE;
 #endif
+	error:
 	mutex_unlock(&econet_mutex);
 
 	return err;
Signature · 1 line
1.7.4.4
#134 lore raw

PATCH 134/209 ACPI: debugfs custom_method open to non-root

In reply to Paul Gortmaker

From: Dave Jones <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit ed3aada1bf34c5a9e98af167f125f8a740fc726a upstream

Currently we have:

--w--w--w-. 1 root root 0 2010-11-11 14:56 /sys/kernel/debug/acpi/custom_method

which is just crazy. Change this to --w-------.

[PG: back in 2.6.34, the file was called debug.c, not debugfs.c]

---
 drivers/acpi/debug.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/acpi/debug.c +1 -1
index 146135e..469f049 100644
@@ -258,7 +258,7 @@ static int acpi_debugfs_init(void)
 	if (!acpi_dir)
 		goto err;
 
-	cm_dentry = debugfs_create_file("custom_method", S_IWUGO,
+	cm_dentry = debugfs_create_file("custom_method", S_IWUSR,
 					acpi_dir, NULL, &cm_fops);
 	if (!cm_dentry)
 		goto err;
Signature · 1 line
1.7.4.4
#135 lore raw

PATCH 135/209 filter: make sure filters dont read uninitialized memory

In reply to Paul Gortmaker

From: David S. Miller <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 57fe93b374a6b8711995c2d466c502af9f3a08bb upstream

There is a possibility malicious users can get limited information about uninitialized stack mem array. Even if sk_run_filter() result is bound to packet length (0 .. 65535), we could imagine this can be used by hostile user.

Initializing mem[] array, like Dan Rosenberg suggested in his patch is expensive since most filters dont even use this array.

Its hard to make the filter validation in sk_chk_filter(), because of the jumps. This might be done later.

In this patch, I use a bitmap (a single long var) so that only filters using mem[] loads/stores pay the price of added security checks.

For other filters, additional cost is a single instruction.

[ Since we access fentry->k a lot now, cache it in a local variable
and mark filter entry pointer as const. -DaveM ]

---
 net/core/filter.c |   64 +++++++++++++++++++++++++++++------------------------
 1 files changed, 35 insertions(+), 29 deletions(-)
net/core/filter.c +35 -29
index ff943be..3462e9d 100644
@@ -112,39 +112,41 @@ EXPORT_SYMBOL(sk_filter);
  */
 unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
 {
-	struct sock_filter *fentry;	/* We walk down these */
 	void *ptr;
 	u32 A = 0;			/* Accumulator */
 	u32 X = 0;			/* Index Register */
 	u32 mem[BPF_MEMWORDS];		/* Scratch Memory Store */
+	unsigned long memvalid = 0;
 	u32 tmp;
 	int k;
 	int pc;
 
+	BUILD_BUG_ON(BPF_MEMWORDS > BITS_PER_LONG);
 	/*
 	 * Process array of filter instructions.
 	 */
 	for (pc = 0; pc < flen; pc++) {
-		fentry = &filter[pc];
+		const struct sock_filter *fentry = &filter[pc];
+		u32 f_k = fentry->k;
 
 		switch (fentry->code) {
 		case BPF_ALU|BPF_ADD|BPF_X:
 			A += X;
 			continue;
 		case BPF_ALU|BPF_ADD|BPF_K:
-			A += fentry->k;
+			A += f_k;
 			continue;
 		case BPF_ALU|BPF_SUB|BPF_X:
 			A -= X;
 			continue;
 		case BPF_ALU|BPF_SUB|BPF_K:
-			A -= fentry->k;
+			A -= f_k;
 			continue;
 		case BPF_ALU|BPF_MUL|BPF_X:
 			A *= X;
 			continue;
 		case BPF_ALU|BPF_MUL|BPF_K:
-			A *= fentry->k;
+			A *= f_k;
 			continue;
 		case BPF_ALU|BPF_DIV|BPF_X:
 			if (X == 0)
@@ -152,49 +154,49 @@ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int
 			A /= X;
 			continue;
 		case BPF_ALU|BPF_DIV|BPF_K:
-			A /= fentry->k;
+			A /= f_k;
 			continue;
 		case BPF_ALU|BPF_AND|BPF_X:
 			A &= X;
 			continue;
 		case BPF_ALU|BPF_AND|BPF_K:
-			A &= fentry->k;
+			A &= f_k;
 			continue;
 		case BPF_ALU|BPF_OR|BPF_X:
 			A |= X;
 			continue;
 		case BPF_ALU|BPF_OR|BPF_K:
-			A |= fentry->k;
+			A |= f_k;
 			continue;
 		case BPF_ALU|BPF_LSH|BPF_X:
 			A <<= X;
 			continue;
 		case BPF_ALU|BPF_LSH|BPF_K:
-			A <<= fentry->k;
+			A <<= f_k;
 			continue;
 		case BPF_ALU|BPF_RSH|BPF_X:
 			A >>= X;
 			continue;
 		case BPF_ALU|BPF_RSH|BPF_K:
-			A >>= fentry->k;
+			A >>= f_k;
 			continue;
 		case BPF_ALU|BPF_NEG:
 			A = -A;
 			continue;
 		case BPF_JMP|BPF_JA:
-			pc += fentry->k;
+			pc += f_k;
 			continue;
 		case BPF_JMP|BPF_JGT|BPF_K:
-			pc += (A > fentry->k) ? fentry->jt : fentry->jf;
+			pc += (A > f_k) ? fentry->jt : fentry->jf;
 			continue;
 		case BPF_JMP|BPF_JGE|BPF_K:
-			pc += (A >= fentry->k) ? fentry->jt : fentry->jf;
+			pc += (A >= f_k) ? fentry->jt : fentry->jf;
 			continue;
 		case BPF_JMP|BPF_JEQ|BPF_K:
-			pc += (A == fentry->k) ? fentry->jt : fentry->jf;
+			pc += (A == f_k) ? fentry->jt : fentry->jf;
 			continue;
 		case BPF_JMP|BPF_JSET|BPF_K:
-			pc += (A & fentry->k) ? fentry->jt : fentry->jf;
+			pc += (A & f_k) ? fentry->jt : fentry->jf;
 			continue;
 		case BPF_JMP|BPF_JGT|BPF_X:
 			pc += (A > X) ? fentry->jt : fentry->jf;
@@ -209,7 +211,7 @@ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int
 			pc += (A & X) ? fentry->jt : fentry->jf;
 			continue;
 		case BPF_LD|BPF_W|BPF_ABS:
-			k = fentry->k;
+			k = f_k;
 load_w:
 			ptr = load_pointer(skb, k, 4, &tmp);
 			if (ptr != NULL) {
@@ -218,7 +220,7 @@ load_w:
 			}
 			break;
 		case BPF_LD|BPF_H|BPF_ABS:
-			k = fentry->k;
+			k = f_k;
 load_h:
 			ptr = load_pointer(skb, k, 2, &tmp);
 			if (ptr != NULL) {
@@ -227,7 +229,7 @@ load_h:
 			}
 			break;
 		case BPF_LD|BPF_B|BPF_ABS:
-			k = fentry->k;
+			k = f_k;
 load_b:
 			ptr = load_pointer(skb, k, 1, &tmp);
 			if (ptr != NULL) {
@@ -242,32 +244,34 @@ load_b:
 			X = skb->len;
 			continue;
 		case BPF_LD|BPF_W|BPF_IND:
-			k = X + fentry->k;
+			k = X + f_k;
 			goto load_w;
 		case BPF_LD|BPF_H|BPF_IND:
-			k = X + fentry->k;
+			k = X + f_k;
 			goto load_h;
 		case BPF_LD|BPF_B|BPF_IND:
-			k = X + fentry->k;
+			k = X + f_k;
 			goto load_b;
 		case BPF_LDX|BPF_B|BPF_MSH:
-			ptr = load_pointer(skb, fentry->k, 1, &tmp);
+			ptr = load_pointer(skb, f_k, 1, &tmp);
 			if (ptr != NULL) {
 				X = (*(u8 *)ptr & 0xf) << 2;
 				continue;
 			}
 			return 0;
 		case BPF_LD|BPF_IMM:
-			A = fentry->k;
+			A = f_k;
 			continue;
 		case BPF_LDX|BPF_IMM:
-			X = fentry->k;
+			X = f_k;
 			continue;
 		case BPF_LD|BPF_MEM:
-			A = mem[fentry->k];
+			A = (memvalid & (1UL << f_k)) ?
+				mem[f_k] : 0;
 			continue;
 		case BPF_LDX|BPF_MEM:
-			X = mem[fentry->k];
+			X = (memvalid & (1UL << f_k)) ?
+				mem[f_k] : 0;
 			continue;
 		case BPF_MISC|BPF_TAX:
 			X = A;
@@ -276,14 +280,16 @@ load_b:
 			A = X;
 			continue;
 		case BPF_RET|BPF_K:
-			return fentry->k;
+			return f_k;
 		case BPF_RET|BPF_A:
 			return A;
 		case BPF_ST:
-			mem[fentry->k] = A;
+			memvalid |= 1UL << f_k;
+			mem[f_k] = A;
 			continue;
 		case BPF_STX:
-			mem[fentry->k] = X;
+			memvalid |= 1UL << f_k;
+			mem[f_k] = X;
 			continue;
 		default:
 			WARN_ON(1);
Signature · 1 line
1.7.4.4
#136 lore raw

PATCH 136/209 exec: make argv/envp memory visible to oom-killer

In reply to Paul Gortmaker

From: Oleg Nesterov <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 3c77f845722158206a7209c45ccddc264d19319c upstream

Brad Spengler published a local memory-allocation DoS that evades the OOM-killer (though not the virtual memory RLIMIT):
http://www.grsecurity.net/~spender/64bit_dos.c

execve()->copy_strings() can allocate a lot of memory, but this is not visible to oom-killer, nobody can see the nascent bprm->mm and take it into account.

With this patch get_arg_page() increments current's MM_ANONPAGES counter every time we allocate the new page for argv/envp. When do_execve() succeds or fails, we change this counter back.

Technically this is not 100% correct, we can't know if the new page is swapped out and turn MM_ANONPAGES into MM_SWAPENTS, but I don't think this really matters and everything becomes correct once exec changes ->mm or fails.

---
 fs/exec.c               |   32 ++++++++++++++++++++++++++++++--
 include/linux/binfmts.h |    1 +
 2 files changed, 31 insertions(+), 2 deletions(-)
fs/exec.c +30 -2
index afd9977..8d4912f 100644
@@ -158,6 +158,25 @@ out:
 
 #ifdef CONFIG_MMU
 
+static void acct_arg_size(struct linux_binprm *bprm, unsigned long pages)
+{
+	struct mm_struct *mm = current->mm;
+	long diff = (long)(pages - bprm->vma_pages);
+
+	if (!mm || !diff)
+		return;
+
+	bprm->vma_pages = pages;
+
+#ifdef SPLIT_RSS_COUNTING
+	add_mm_counter(mm, MM_ANONPAGES, diff);
+#else
+	spin_lock(&mm->page_table_lock);
+	add_mm_counter(mm, MM_ANONPAGES, diff);
+	spin_unlock(&mm->page_table_lock);
+#endif
+}
+
 static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
 		int write)
 {
@@ -180,6 +199,8 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
 		unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start;
 		struct rlimit *rlim;
 
+		acct_arg_size(bprm, size / PAGE_SIZE);
+
 		/*
 		 * We've historically supported up to 32 pages (ARG_MAX)
 		 * of argument strings even with small stacks
@@ -269,6 +290,10 @@ static bool valid_arg_len(struct linux_binprm *bprm, long len)
 
 #else
 
+static inline void acct_arg_size(struct linux_binprm *bprm, unsigned long pages)
+{
+}
+
 static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
 		int write)
 {
@@ -987,6 +1012,7 @@ int flush_old_exec(struct linux_binprm * bprm)
 	/*
 	 * Release all of the old mmap stuff
 	 */
+	acct_arg_size(bprm, 0);
 	retval = exec_mmap(bprm->mm);
 	if (retval)
 		goto out;
@@ -1411,8 +1437,10 @@ int do_execve(char * filename,
 	return retval;
 
 out:
-	if (bprm->mm)
-		mmput (bprm->mm);
+	if (bprm->mm) {
+		acct_arg_size(bprm, 0);
+		mmput(bprm->mm);
+	}
 
 out_file:
 	if (bprm->file) {
include/linux/binfmts.h +1 -0
index c809e28..39798c6 100644
@@ -29,6 +29,7 @@ struct linux_binprm{
 	char buf[BINPRM_BUF_SIZE];
 #ifdef CONFIG_MMU
 	struct vm_area_struct *vma;
+	unsigned long vma_pages;
 #else
 # define MAX_ARG_PAGES	32
 	struct page *page[MAX_ARG_PAGES];
Signature · 1 line
1.7.4.4
#137 lore raw

Re: [34-longterm 136/209] exec: make argv/envp memory visible to oom-killer

Quoted 10 lines · Paul Gortmaker

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================
...

With this patch get_arg_page() increments current's MM_ANONPAGES counter every time we allocate the new page for argv/envp. When do_execve() succeds or fails, we change this counter back.

This only works starting from 2.6.36.

before 2.6.36 kernel, oom-killer's badness() uses mm->total_vm. Please see the patch for pre2.6.36 kernel below.

Oleg.

--------------------------------------------------------------------
commit 3c77f845722158206a7209c45ccddc264d19319c upstream.

Brad Spengler published a local memory-allocation DoS that evades the OOM-killer (though not the virtual memory RLIMIT):
http://www.grsecurity.net/~spender/64bit_dos.c

execve()->copy_strings() can allocate a lot of memory, but this is not visible to oom-killer, nobody can see the nascent bprm->mm and take it into account.

With this patch get_arg_page() increments current's MM_ANONPAGES counter every time we allocate the new page for argv/envp. When do_execve() succeds or fails, we change this counter back.

Technically this is not 100% correct, we can't know if the new page is swapped out and turn MM_ANONPAGES into MM_SWAPENTS, but I don't think this really matters and everything becomes correct once exec changes ->mm or fails.

Compared to upstream:

before 2.6.36 kernel, oom-killer's badness() takes mm->total_vm into account and nothing else. So acct_arg_size() has to play with this counter too.

---

 include/linux/binfmts.h |    1 +
 fs/exec.c               |   28 ++++++++++++++++++++++++++--
 2 files changed, 27 insertions(+), 2 deletions(-)
include/linux/binfmts.h renamed from include/linux/binfmts.h~1_acct_exec_mem +1 -0
@@ -29,6 +29,7 @@ struct linux_binprm{
 	char buf[BINPRM_BUF_SIZE];
 #ifdef CONFIG_MMU
 	struct vm_area_struct *vma;
+	unsigned long vma_pages;
 #else
 # define MAX_ARG_PAGES	32
 	struct page *page[MAX_ARG_PAGES];
fs/exec.c renamed from fs/exec.c~1_acct_exec_mem +26 -2
@@ -158,6 +158,21 @@ out:
 
 #ifdef CONFIG_MMU
 
+static void acct_arg_size(struct linux_binprm *bprm, unsigned long pages)
+{
+	struct mm_struct *mm = current->mm;
+	long diff = (long)(pages - bprm->vma_pages);
+
+	if (!mm || !diff)
+		return;
+
+	bprm->vma_pages = pages;
+
+	down_write(&mm->mmap_sem);
+	mm->total_vm += diff;
+	up_write(&mm->mmap_sem);
+}
+
 static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
 		int write)
 {
@@ -180,6 +195,8 @@ static struct page *get_arg_page(struct 
 		unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start;
 		struct rlimit *rlim;
 
+		acct_arg_size(bprm, size / PAGE_SIZE);
+
 		/*
 		 * We've historically supported up to 32 pages (ARG_MAX)
 		 * of argument strings even with small stacks
@@ -270,6 +287,10 @@ static bool valid_arg_len(struct linux_b
 
 #else
 
+static inline void acct_arg_size(struct linux_binprm *bprm, unsigned long pages)
+{
+}
+
 static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
 		int write)
 {
@@ -977,6 +998,7 @@ int flush_old_exec(struct linux_binprm *
 	/*
 	 * Release all of the old mmap stuff
 	 */
+	acct_arg_size(bprm, 0);
 	retval = exec_mmap(bprm->mm);
 	if (retval)
 		goto out;
@@ -1401,8 +1423,10 @@ int do_execve(char * filename,
 	return retval;
 
 out:
-	if (bprm->mm)
-		mmput (bprm->mm);
+	if (bprm->mm) {
+		acct_arg_size(bprm, 0);
+		mmput(bprm->mm);
+	}
 
 out_file:
 	if (bprm->file) {
#138 lore raw

Re: [34-longterm 136/209] exec: make argv/envp memory visible to oom-killer

Quoted 8 lines · Oleg Nesterov
Quoted 7 lines · Paul Gortmaker

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================
...

Quoted 8 lines
Quoted 3 lines

With this patch get_arg_page() increments current's MM_ANONPAGES counter every time we allocate the new page for argv/envp. When do_execve() succeds or fails, we change this counter back.

This only works starting from 2.6.36.

before 2.6.36 kernel, oom-killer's badness() uses mm->total_vm. Please see the patch for pre2.6.36 kernel below.

Thanks Oleg -- I see the earlier discussion about this from December now, and will swap in the pre-36 version -- I appreciate the review.

Paul.

Quoted 116 lines

Oleg.

--------------------------------------------------------------------
commit 3c77f845722158206a7209c45ccddc264d19319c upstream.

Brad Spengler published a local memory-allocation DoS that evades the OOM-killer (though not the virtual memory RLIMIT):
http://www.grsecurity.net/~spender/64bit_dos.c

execve()->copy_strings() can allocate a lot of memory, but this is not visible to oom-killer, nobody can see the nascent bprm->mm and take it into account.

With this patch get_arg_page() increments current's MM_ANONPAGES counter every time we allocate the new page for argv/envp. When do_execve() succeds or fails, we change this counter back.

Technically this is not 100% correct, we can't know if the new page is swapped out and turn MM_ANONPAGES into MM_SWAPENTS, but I don't think this really matters and everything becomes correct once exec changes ->mm or fails.

Compared to upstream:

before 2.6.36 kernel, oom-killer's badness() takes mm->total_vm into account and nothing else. So acct_arg_size() has to play with this counter too.

---

 include/linux/binfmts.h |    1 +
 fs/exec.c               |   28 ++++++++++++++++++++++++++--
 2 files changed, 27 insertions(+), 2 deletions(-)
include/linux/binfmts.h renamed from include/linux/binfmts.h~1_acct_exec_mem +1 -0
@@ -29,6 +29,7 @@ struct linux_binprm{
 	char buf[BINPRM_BUF_SIZE];
 #ifdef CONFIG_MMU
 	struct vm_area_struct *vma;
+	unsigned long vma_pages;
 #else
 # define MAX_ARG_PAGES	32
 	struct page *page[MAX_ARG_PAGES];
fs/exec.c renamed from fs/exec.c~1_acct_exec_mem +26 -2
@@ -158,6 +158,21 @@ out:
 
 #ifdef CONFIG_MMU
 
+static void acct_arg_size(struct linux_binprm *bprm, unsigned long pages)
+{
+	struct mm_struct *mm = current->mm;
+	long diff = (long)(pages - bprm->vma_pages);
+
+	if (!mm || !diff)
+		return;
+
+	bprm->vma_pages = pages;
+
+	down_write(&mm->mmap_sem);
+	mm->total_vm += diff;
+	up_write(&mm->mmap_sem);
+}
+
 static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
 		int write)
 {
@@ -180,6 +195,8 @@ static struct page *get_arg_page(struct 
 		unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start;
 		struct rlimit *rlim;
 
+		acct_arg_size(bprm, size / PAGE_SIZE);
+
 		/*
 		 * We've historically supported up to 32 pages (ARG_MAX)
 		 * of argument strings even with small stacks
@@ -270,6 +287,10 @@ static bool valid_arg_len(struct linux_b
 
 #else
 
+static inline void acct_arg_size(struct linux_binprm *bprm, unsigned long pages)
+{
+}
+
 static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
 		int write)
 {
@@ -977,6 +998,7 @@ int flush_old_exec(struct linux_binprm *
 	/*
 	 * Release all of the old mmap stuff
 	 */
+	acct_arg_size(bprm, 0);
 	retval = exec_mmap(bprm->mm);
 	if (retval)
 		goto out;
@@ -1401,8 +1423,10 @@ int do_execve(char * filename,
 	return retval;
 
 out:
-	if (bprm->mm)
-		mmput (bprm->mm);
+	if (bprm->mm) {
+		acct_arg_size(bprm, 0);
+		mmput(bprm->mm);
+	}
 
 out_file:
 	if (bprm->file) {
#139 lore raw

PATCH 137/209 tcp: Don't change unlocked socket state in tcp_v4_err().

In reply to Paul Gortmaker

From: David S. Miller <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 8f49c2703b33519aaaccc63f571b465b9d2b3a2d upstream

Alexey Kuznetsov noticed a regression introduced by commit f1ecd5d9e7366609d640ff4040304ea197fbc618
("Revert Backoff [v3]: Revert RTO on ICMP destination unreachable")

The RTO and timer modification code added to tcp_v4_err() doesn't check sock_owned_by_user(), which if true means we don't have exclusive access to the socket and therefore cannot modify it's critical state.

Just skip this new code block if sock_owned_by_user() is true and eliminate the now superfluous sock_owned_by_user() code block contained within.

---
 net/ipv4/tcp_ipv4.c |    8 +++-----
 1 files changed, 3 insertions(+), 5 deletions(-)
net/ipv4/tcp_ipv4.c +3 -5
index 3c23e70..ea51c2f 100644
@@ -411,6 +411,9 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
 		    !icsk->icsk_backoff)
 			break;
 
+		if (sock_owned_by_user(sk))
+			break;
+
 		icsk->icsk_backoff--;
 		inet_csk(sk)->icsk_rto = __tcp_set_rto(tp) <<
 					 icsk->icsk_backoff;
@@ -425,11 +428,6 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
 		if (remaining) {
 			inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
 						  remaining, TCP_RTO_MAX);
-		} else if (sock_owned_by_user(sk)) {
-			/* RTO revert clocked out retransmission,
-			 * but socket is locked. Will defer. */
-			inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
-						  HZ/20, TCP_RTO_MAX);
 		} else {
 			/* RTO revert clocked out retransmission.
 			 * Will retransmit now */
Signature · 1 line
1.7.4.4
#140 lore raw

PATCH 138/209 tcp: Increase TCP_MAXSEG socket option minimum.

In reply to Paul Gortmaker

From: David S. Miller <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit 7a1abd08d52fdeddb3e9a5a33f2f15cc6a5674d2 upstream

As noted by Steve Chen, since commit f5fff5dc8a7a3f395b0525c02ba92c95d42b7390 ("tcp: advertise MSS requested by user") we can end up with a situation where tcp_select_initial_window() does a divide by a zero (or even negative) mss value.

The problem is that sometimes we effectively subtract TCPOLEN_TSTAMP_ALIGNED and/or TCPOLEN_MD5SIG_ALIGNED from the mss.

Fix this by increasing the minimum from 8 to 64.

---
 net/ipv4/tcp.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
net/ipv4/tcp.c +1 -1
index 68cd299..5ad716b 100644
@@ -2234,7 +2234,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
 		/* Values greater than interface MTU won't take effect. However
 		 * at the point when this call is done we typically don't yet
 		 * know which interface is going to be used */
-		if (val < 8 || val > MAX_TCP_WINDOW) {
+		if (val < 64 || val > MAX_TCP_WINDOW) {
 			err = -EINVAL;
 			break;
 		}
Signature · 1 line
1.7.4.4
#141 lore raw

PATCH 139/209 tcp: Make TCP_MAXSEG minimum more correct.

In reply to Paul Gortmaker

From: David S. Miller <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit c39508d6f118308355468314ff414644115a07f3 upstream

Use TCP_MIN_MSS instead of constant 64.

---
 net/ipv4/tcp.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
net/ipv4/tcp.c +1 -1
index 5ad716b..3a8cbf7 100644
@@ -2234,7 +2234,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
 		/* Values greater than interface MTU won't take effect. However
 		 * at the point when this call is done we typically don't yet
 		 * know which interface is going to be used */
-		if (val < 64 || val > MAX_TCP_WINDOW) {
+		if (val < TCP_MIN_MSS || val > MAX_TCP_WINDOW) {
 			err = -EINVAL;
 			break;
 		}
Signature · 1 line
1.7.4.4
#142 lore raw

PATCH 140/209 tcp: Bug fix in initialization of receive window.

In reply to Paul Gortmaker

From: Nandita Dukkipati <[email protected]>

=====================================================================

  | This is a commit scheduled for the next v2.6.34 longterm release. |
  | If you see a problem with using this for longterm, please comment.|

=====================================================================

commit b1afde60f2b9ee8444fba4e012dc99a3b28d224d upstream

The bug has to do with boundary checks on the initial receive window. If the initial receive window falls between init_cwnd and the receive window specified by the user, the initial window is incorrectly brought down to init_cwnd. The correct behavior is to allow it to remain unchanged.

---
 net/ipv4/tcp_output.c |    9 ++++-----
 1 files changed, 4 insertions(+), 5 deletions(-)
net/ipv4/tcp_output.c +4 -5
index a5cf575..e1819aa 100644
@@ -237,11 +237,10 @@ void tcp_select_initial_window(int __space, __u32 mss,
 		/* when initializing use the value from init_rcv_wnd
 		 * rather than the default from above
 		 */
-		if (init_rcv_wnd &&
-		    (*rcv_wnd > init_rcv_wnd * mss))
-			*rcv_wnd = init_rcv_wnd * mss;
-		else if (*rcv_wnd > init_cwnd * mss)
-			*rcv_wnd = init_cwnd * mss;
+		if (init_rcv_wnd)
+			*rcv_wnd = min(*rcv_wnd, init_rcv_wnd * mss);
+		else
+			*rcv_wnd = min(*rcv_wnd, init_cwnd * mss);
 	}
 
 	/* Set the clamp no higher than max representable value */
Signature · 1 line
1.7.4.4