Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1344036 > unrolled thread

[3.16.y-ckt stable] Linux 3.16.7-ckt25 stable review

Started byLuis Henriques <luis.henriques@canonical.com>
First post2016-02-26 11:30 +0100
Last post2016-02-29 12:40 +0100
Articles 20 on this page of 109 — 1 participant

Back to article view | Back to linux.kernel


Contents

  [3.16.y-ckt stable] Linux 3.16.7-ckt25 stable review Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:30 +0100
    [PATCH 3.16.y-ckt 117/129] ARM: 8519/1: ICST: try other dividends than 1 Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:30 +0100
    [PATCH 3.16.y-ckt 107/129] klist: fix starting point removed bug in klist iterators Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:40 +0100
    [PATCH 3.16.y-ckt 126/129] sctp: translate network order to host order when users get a hmacid Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:40 +0100
    [PATCH 3.16.y-ckt 109/129] ALSA: timer: Fix wrong instance passed to slave callbacks Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:40 +0100
    [PATCH 3.16.y-ckt 123/129] netlink: not trim skb for mmaped socket when dump Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:40 +0100
    [PATCH 3.16.y-ckt 108/129] ALSA: dummy: Implement timer backend switching more safely Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:40 +0100
    [PATCH 3.16.y-ckt 106/129] ALSA: hda - Fix speaker output from VAIO AiO machines Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:40 +0100
    [PATCH 3.16.y-ckt 100/129] mm: replace vma_lock_anon_vma with anon_vma_lock_read/write Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:40 +0100
    [PATCH 3.16.y-ckt 099/129] ocfs2/dlm: clear refmap bit of recovery lock while doing local recovery cleanup Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:40 +0100
    [PATCH 3.16.y-ckt 122/129] sctp: allow setting SCTP_SACK_IMMEDIATELY by the application Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:40 +0100
    [PATCH 3.16.y-ckt 115/129] workqueue: handle NUMA_NO_NODE for unbound pool_workqueue lookup Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:40 +0100
    [PATCH 3.16.y-ckt 111/129] ALSA: timer: Fix race between stop and interrupt Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:40 +0100
    [PATCH 3.16.y-ckt 125/129] ipv6: fix a lockdep splat Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:40 +0100
    [PATCH 3.16.y-ckt 110/129] ARM: 8517/1: ICST: avoid arithmetic overflow in icst_hz() Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:40 +0100
    [PATCH 3.16.y-ckt 120/129] af_unix: fix struct pid memory leak Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:40 +0100
    [PATCH 3.16.y-ckt 096/129] Revert "ALSA: hda - Fix noise on Gigabyte Z170X mobo" Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 093/129] SCSI: Add Marvell Console to VPD blacklist Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 084/129] radix-tree: fix race in gang lookup Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 077/129] ASoC: dpcm: fix the BE state on hw_free Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 094/129] drm: Add drm_fixp_from_fraction and drm_fixp2int_ceil Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 087/129] xhci: Fix list corruption in urb dequeue at host removal Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 098/129] mm, vmstat: fix wrong WQ sleep when memory reclaim doesn't make any progress Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 088/129] [media] tda1004x: only update the frontend properties if locked Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 083/129] drivers/scsi/sg.c: mark VMA as VM_IO to prevent migration Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 090/129] [media] saa7134-alsa: Only frees registered sound cards Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 095/129] ALSA: hda - Fix static checker warning in patch_hdmi.c Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 078/129] module: wrapper for symbol name. Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 085/129] Revert "xhci: don't finish a TD if we get a short-transfer event mid TD" Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 104/129] pty: fix possible use after free of tty->driver_data Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 097/129] dump_stack: avoid potential deadlocks Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 103/129] serial: omap: Prevent DoS using unprivileged ioctl(TIOCSRS485) Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 086/129] usb: xhci: apply XHCI_PME_STUCK_QUIRK to Intel Broxton-M platforms Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 076/129] cputime: Prevent 32bit overflow in time[val|spec]_to_cputime() Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 092/129] scsi_dh_rdac: always retry MODE SELECT on command lock violation Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 102/129] crypto: user - lock crypto_alg_list on alg dump Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 072/129] ALSA: timer: Code cleanup Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 082/129] ALSA: seq: Fix lockdep warnings due to double mutex locks Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 079/129] ALSA: hda - Add fixup for Mac Mini 7,1 model Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 101/129] radix-tree: fix oops after radix_tree_iter_retry Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 074/129] libata: fix sff host state machine locking while polling Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 069/129] ALSA: rawmidi: Remove kernel WARNING for NULL user-space buffer check Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 073/129] ALSA: timer: Fix link corruption due to double start or stop Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 091/129] Btrfs: fix hang on extent buffer lock caused by the inode_paths ioctl Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 080/129] ALSA: rawmidi: Make snd_rawmidi_transmit() race-free Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 11:50 +0100
    [PATCH 3.16.y-ckt 045/129] crypto: algif_skcipher - Add nokey compatibility path Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:00 +0100
    [PATCH 3.16.y-ckt 046/129] crypto: algif_hash - Require setkey before accept(2) Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:00 +0100
    [PATCH 3.16.y-ckt 067/129] intel_scu_ipcutil: underflow in scu_reg_access() Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:00 +0100
    [PATCH 3.16.y-ckt 056/129] cgroup: make sure a parent css isn't offlined before its children Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:00 +0100
    [PATCH 3.16.y-ckt 063/129] target: Fix WRITE_SAME/DISCARD conversion to linux 512b sectors Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:00 +0100
    [PATCH 3.16.y-ckt 060/129] rfkill: fix rfkill_fop_read wait_event usage Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:00 +0100
    [PATCH 3.16.y-ckt 044/129] crypto: algif_skcipher - Require setkey before accept(2) Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:00 +0100
    [PATCH 3.16.y-ckt 053/129] iio: add HAS_IOMEM dependency to VF610_ADC Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:00 +0100
    [PATCH 3.16.y-ckt 043/129] umount: Do not allow unmounting rootfs. Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:00 +0100
    [PATCH 3.16.y-ckt 055/129] ASoC: rt5645: fix the shift bit of IN1 boost Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:00 +0100
    [PATCH 3.16.y-ckt 048/129] crypto: algif_skcipher - Add key check exception for cipher_null Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:00 +0100
    [PATCH 3.16.y-ckt 054/129] iio: dac: mcp4725: set iio name property in sysfs Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:00 +0100
    [PATCH 3.16.y-ckt 051/129] crypto: algif_hash - Fix race condition in hash_check_key Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:00 +0100
    [PATCH 3.16.y-ckt 050/129] crypto: algif_skcipher - Remove custom release parent function Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:00 +0100
    [PATCH 3.16.y-ckt 061/129] crypto: shash - Fix has_key setting Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:00 +0100
    [PATCH 3.16.y-ckt 062/129] drm/i915/dp: fall back to 18 bpp when sink capability is unknown Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:00 +0100
    [PATCH 3.16.y-ckt 065/129] iio: inkern: fix a NULL dereference on error Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:00 +0100
    [PATCH 3.16.y-ckt 059/129] mac80211: Requeue work after scan complete for all VIF types. Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:00 +0100
    [PATCH 3.16.y-ckt 066/129] iio: pressure: mpl115: fix temperature offset sign Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:00 +0100
    [PATCH 3.16.y-ckt 058/129] libata: disable forced PORTS_IMPL for >= AHCI 1.3 Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:00 +0100
    [PATCH 3.16.y-ckt 064/129] crypto: algif_hash - wait for crypto_ahash_init() to complete Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:00 +0100
    [PATCH 3.16.y-ckt 052/129] crypto: algif_skcipher - Fix race condition in skcipher_check_key Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:00 +0100
    [PATCH 3.16.y-ckt 042/129] Revert "workqueue: make sure delayed work run in local cpu" Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:00 +0100
    [PATCH 3.16.y-ckt 068/129] ALSA: seq: Fix race at closing in virmidi driver Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:00 +0100
    [PATCH 3.16.y-ckt 024/129] USB: serial: ftdi_sio: add support for Yaesu SCU-18 cable Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 039/129] perf hists: Fix HISTC_MEM_DCACHELINE width setting Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 020/129] USB: visor: fix null-deref at probe Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 033/129] n_tty: Fix unsafe reference to "other" ldisc Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 027/129] ALSA: usb-audio: Fix TEAC UD-501/UD-503/NT-503 usb delay Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 012/129] KVM: PPC: Fix emulation of H_SET_DABR/X on POWER8 Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 049/129] crypto: algif_hash - Remove custom release parent function Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 036/129] drm/vmwgfx: respect 'nomodeset' Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 019/129] USB: cp210x: add ID for IAI USB to RS485 adaptor Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 014/129] ACPI / PCI / hotplug: unlock in error path in acpiphp_enable_slot() Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 031/129] powerpc/eeh: Fix PE location code Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 047/129] crypto: skcipher - Add crypto_skcipher_has_setkey Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 032/129] SCSI: fix crashes in sd and sr runtime PM Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 018/129] usb: hub: do not clear BOS field during reset device Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 022/129] ALSA: seq: Fix incorrect sanity check at snd_seq_oss_synth_cleanup() Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 009/129] EVM: Use crypto_memneq() for digest comparisons Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 023/129] ALSA: seq: Degrade the error message for too many opens Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 040/129] powerpc/perf: Remove PPMU_HAS_SSLOT flag for Power8 Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 008/129] iw_cxgb3: Fix incorrectly returning error on success Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 028/129] virtio_pci: fix use after free on release Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 030/129] arm64: errata: Add -mpc-relative-literal-loads to build flags Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 010/129] ALSA: usb-audio: avoid freeing umidi object twice Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 029/129] ALSA: bebob: Use a signed return type for get_formation_index Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 015/129] usb: cdc-acm: handle unlinked urb in acm read callback Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 017/129] cdc-acm:exclude Samsung phone 04e8:685d Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 035/129] ALSA: dummy: Disable switching timer backend via sysfs Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 025/129] USB: option: fix Cinterion AHxx enumeration Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 021/129] USB: serial: option: Adding support for Telit LE922 Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 016/129] usb: cdc-acm: send zero packet for intel 7260 modem Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 034/129] staging/speakup: Use tty_ldisc_ref() for paste kworker Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 038/129] perf annotate browser: Fix behaviour of Shift-Tab with nothing focussed Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:10 +0100
    [PATCH 3.16.y-ckt 005/129] USB: serial: visor: fix crash on detecting device without write_urbs Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:20 +0100
    [PATCH 3.16.y-ckt 007/129] qeth: initialize net_device with carrier off Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:20 +0100
    [PATCH 3.16.y-ckt 011/129] iio: adis_buffer: Fix out-of-bounds memory access Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:20 +0100
    [PATCH 3.16.y-ckt 002/129] [media] usbvision: fix leak of usb_dev on failure paths in usbvision_probe() Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:20 +0100
    [PATCH 3.16.y-ckt 003/129] [media] usbvision: fix crash on detecting device with invalid configuration Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:20 +0100
    [PATCH 3.16.y-ckt 004/129] tty: Fix unsafe ldisc reference via ioctl(TIOCGETD) Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:20 +0100
    [PATCH 3.16.y-ckt 006/129] ASN.1: Fix non-match detection failure on data overrun Luis Henriques <luis.henriques@canonical.com> - 2016-02-26 12:20 +0100
    [PATCH 3.16.y-ckt 131/131] net: phy: Avoid polling PHY with PHY_IGNORE_INTERRUPTS Luis Henriques <luis.henriques@canonical.com> - 2016-02-29 12:40 +0100
    [PATCH 3.16.y-ckt 130/131] net: phy: fix PHY_RUNNING in phy_state_machine Luis Henriques <luis.henriques@canonical.com> - 2016-02-29 12:40 +0100

Page 3 of 6 — ← Prev page 1 2 [3] 4 5 6  Next page →


#1344092 — [PATCH 3.16.y-ckt 074/129] libata: fix sff host state machine locking while polling

FromLuis Henriques <luis.henriques@canonical.com>
Date2016-02-26 11:50 +0100
Subject[PATCH 3.16.y-ckt 074/129] libata: fix sff host state machine locking while polling
Message-ID<r6o8c-1Sy-81@gated-at.bofh.it>
In reply to#1344036
3.16.7-ckt25 -stable review patch.  If anyone has any objections, please let me know.

---8<------------------------------------------------------------

From: Tejun Heo <tj@kernel.org>

commit 8eee1d3ed5b6fc8e14389567c9a6f53f82bb7224 upstream.

The bulk of ATA host state machine is implemented by
ata_sff_hsm_move().  The function is called from either the interrupt
handler or, if polling, a work item.  Unlike from the interrupt path,
the polling path calls the function without holding the host lock and
ata_sff_hsm_move() selectively grabs the lock.

This is completely broken.  If an IRQ triggers while polling is in
progress, the two can easily race and end up accessing the hardware
and updating state machine state at the same time.  This can put the
state machine in an illegal state and lead to a crash like the
following.

  kernel BUG at drivers/ata/libata-sff.c:1302!
  invalid opcode: 0000 [#1] SMP DEBUG_PAGEALLOC KASAN
  Modules linked in:
  CPU: 1 PID: 10679 Comm: syz-executor Not tainted 4.5.0-rc1+ #300
  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
  task: ffff88002bd00000 ti: ffff88002e048000 task.ti: ffff88002e048000
  RIP: 0010:[<ffffffff83a83409>]  [<ffffffff83a83409>] ata_sff_hsm_move+0x619/0x1c60
  ...
  Call Trace:
   <IRQ>
   [<ffffffff83a84c31>] __ata_sff_port_intr+0x1e1/0x3a0 drivers/ata/libata-sff.c:1584
   [<ffffffff83a85611>] ata_bmdma_port_intr+0x71/0x400 drivers/ata/libata-sff.c:2877
   [<     inline     >] __ata_sff_interrupt drivers/ata/libata-sff.c:1629
   [<ffffffff83a85bf3>] ata_bmdma_interrupt+0x253/0x580 drivers/ata/libata-sff.c:2902
   [<ffffffff81479f98>] handle_irq_event_percpu+0x108/0x7e0 kernel/irq/handle.c:157
   [<ffffffff8147a717>] handle_irq_event+0xa7/0x140 kernel/irq/handle.c:205
   [<ffffffff81484573>] handle_edge_irq+0x1e3/0x8d0 kernel/irq/chip.c:623
   [<     inline     >] generic_handle_irq_desc include/linux/irqdesc.h:146
   [<ffffffff811a92bc>] handle_irq+0x10c/0x2a0 arch/x86/kernel/irq_64.c:78
   [<ffffffff811a7e4d>] do_IRQ+0x7d/0x1a0 arch/x86/kernel/irq.c:240
   [<ffffffff86653d4c>] common_interrupt+0x8c/0x8c arch/x86/entry/entry_64.S:520
   <EOI>
   [<     inline     >] rcu_lock_acquire include/linux/rcupdate.h:490
   [<     inline     >] rcu_read_lock include/linux/rcupdate.h:874
   [<ffffffff8164b4a1>] filemap_map_pages+0x131/0xba0 mm/filemap.c:2145
   [<     inline     >] do_fault_around mm/memory.c:2943
   [<     inline     >] do_read_fault mm/memory.c:2962
   [<     inline     >] do_fault mm/memory.c:3133
   [<     inline     >] handle_pte_fault mm/memory.c:3308
   [<     inline     >] __handle_mm_fault mm/memory.c:3418
   [<ffffffff816efb16>] handle_mm_fault+0x2516/0x49a0 mm/memory.c:3447
   [<ffffffff8127dc16>] __do_page_fault+0x376/0x960 arch/x86/mm/fault.c:1238
   [<ffffffff8127e358>] trace_do_page_fault+0xe8/0x420 arch/x86/mm/fault.c:1331
   [<ffffffff8126f514>] do_async_page_fault+0x14/0xd0 arch/x86/kernel/kvm.c:264
   [<ffffffff86655578>] async_page_fault+0x28/0x30 arch/x86/entry/entry_64.S:986

Fix it by ensuring that the polling path is holding the host lock
before entering ata_sff_hsm_move() so that all hardware accesses and
state updates are performed under the host lock.

Signed-off-by: Tejun Heo <tj@kernel.org>
Reported-and-tested-by: Dmitry Vyukov <dvyukov@google.com>
Link: http://lkml.kernel.org/g/CACT4Y+b_JsOxJu2EZyEf+mOXORc_zid5V1-pLZSroJVxyWdSpw@mail.gmail.com
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
---
 drivers/ata/libata-sff.c | 32 +++++++++++---------------------
 1 file changed, 11 insertions(+), 21 deletions(-)

diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 2e86e3b85266..12d337754e4a 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -997,12 +997,9 @@ static inline int ata_hsm_ok_in_wq(struct ata_port *ap,
 static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
 {
 	struct ata_port *ap = qc->ap;
-	unsigned long flags;
 
 	if (ap->ops->error_handler) {
 		if (in_wq) {
-			spin_lock_irqsave(ap->lock, flags);
-
 			/* EH might have kicked in while host lock is
 			 * released.
 			 */
@@ -1014,8 +1011,6 @@ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
 				} else
 					ata_port_freeze(ap);
 			}
-
-			spin_unlock_irqrestore(ap->lock, flags);
 		} else {
 			if (likely(!(qc->err_mask & AC_ERR_HSM)))
 				ata_qc_complete(qc);
@@ -1024,10 +1019,8 @@ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
 		}
 	} else {
 		if (in_wq) {
-			spin_lock_irqsave(ap->lock, flags);
 			ata_sff_irq_on(ap);
 			ata_qc_complete(qc);
-			spin_unlock_irqrestore(ap->lock, flags);
 		} else
 			ata_qc_complete(qc);
 	}
@@ -1048,9 +1041,10 @@ int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
 {
 	struct ata_link *link = qc->dev->link;
 	struct ata_eh_info *ehi = &link->eh_info;
-	unsigned long flags = 0;
 	int poll_next;
 
+	lockdep_assert_held(ap->lock);
+
 	WARN_ON_ONCE((qc->flags & ATA_QCFLAG_ACTIVE) == 0);
 
 	/* Make sure ata_sff_qc_issue() does not throw things
@@ -1112,14 +1106,6 @@ fsm_start:
 			}
 		}
 
-		/* Send the CDB (atapi) or the first data block (ata pio out).
-		 * During the state transition, interrupt handler shouldn't
-		 * be invoked before the data transfer is complete and
-		 * hsm_task_state is changed. Hence, the following locking.
-		 */
-		if (in_wq)
-			spin_lock_irqsave(ap->lock, flags);
-
 		if (qc->tf.protocol == ATA_PROT_PIO) {
 			/* PIO data out protocol.
 			 * send first data block.
@@ -1135,9 +1121,6 @@ fsm_start:
 			/* send CDB */
 			atapi_send_cdb(ap, qc);
 
-		if (in_wq)
-			spin_unlock_irqrestore(ap->lock, flags);
-
 		/* if polling, ata_sff_pio_task() handles the rest.
 		 * otherwise, interrupt handler takes over from here.
 		 */
@@ -1361,12 +1344,14 @@ static void ata_sff_pio_task(struct work_struct *work)
 	u8 status;
 	int poll_next;
 
+	spin_lock_irq(ap->lock);
+
 	BUG_ON(ap->sff_pio_task_link == NULL);
 	/* qc can be NULL if timeout occurred */
 	qc = ata_qc_from_tag(ap, link->active_tag);
 	if (!qc) {
 		ap->sff_pio_task_link = NULL;
-		return;
+		goto out_unlock;
 	}
 
 fsm_start:
@@ -1381,11 +1366,14 @@ fsm_start:
 	 */
 	status = ata_sff_busy_wait(ap, ATA_BUSY, 5);
 	if (status & ATA_BUSY) {
+		spin_unlock_irq(ap->lock);
 		ata_msleep(ap, 2);
+		spin_lock_irq(ap->lock);
+
 		status = ata_sff_busy_wait(ap, ATA_BUSY, 10);
 		if (status & ATA_BUSY) {
 			ata_sff_queue_pio_task(link, ATA_SHORT_PAUSE);
-			return;
+			goto out_unlock;
 		}
 	}
 
@@ -1402,6 +1390,8 @@ fsm_start:
 	 */
 	if (poll_next)
 		goto fsm_start;
+out_unlock:
+	spin_unlock_irq(ap->lock);
 }
 
 /**

[toc] | [prev] | [next] | [standalone]


#1344094 — [PATCH 3.16.y-ckt 069/129] ALSA: rawmidi: Remove kernel WARNING for NULL user-space buffer check

FromLuis Henriques <luis.henriques@canonical.com>
Date2016-02-26 11:50 +0100
Subject[PATCH 3.16.y-ckt 069/129] ALSA: rawmidi: Remove kernel WARNING for NULL user-space buffer check
Message-ID<r6o8c-1Sy-85@gated-at.bofh.it>
In reply to#1344036
3.16.7-ckt25 -stable review patch.  If anyone has any objections, please let me know.

---8<------------------------------------------------------------

From: Takashi Iwai <tiwai@suse.de>

commit cc85f7a634cfaf9f0713c6aa06d08817424db37a upstream.

NULL user-space buffer can be passed even in a normal path, thus it's
not good to spew a kernel warning with stack trace at each time.
Just drop snd_BUG_ON() macro usage there.

BugLink: http://lkml.kernel.org/r/CACT4Y+YfVJ3L+q0i-4vyQVyyPD7V=OMX0PWPi29x9Bo3QaBLdw@mail.gmail.com
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
---
 sound/core/rawmidi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 6fc71a4c8a51..1d9dbed43b84 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -1188,7 +1188,7 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
 	long count1, result;
 	struct snd_rawmidi_runtime *runtime = substream->runtime;
 
-	if (snd_BUG_ON(!kernelbuf && !userbuf))
+	if (!kernelbuf && !userbuf)
 		return -EINVAL;
 	if (snd_BUG_ON(!runtime->buffer))
 		return -EINVAL;

[toc] | [prev] | [next] | [standalone]


#1344095 — [PATCH 3.16.y-ckt 073/129] ALSA: timer: Fix link corruption due to double start or stop

FromLuis Henriques <luis.henriques@canonical.com>
Date2016-02-26 11:50 +0100
Subject[PATCH 3.16.y-ckt 073/129] ALSA: timer: Fix link corruption due to double start or stop
Message-ID<r6o8c-1Sy-87@gated-at.bofh.it>
In reply to#1344036
3.16.7-ckt25 -stable review patch.  If anyone has any objections, please let me know.

---8<------------------------------------------------------------

From: Takashi Iwai <tiwai@suse.de>

commit f784beb75ce82f4136f8a0960d3ee872f7109e09 upstream.

Although ALSA timer code got hardening for races, it still causes
use-after-free error.  This is however rather a corrupted linked list,
not actually the concurrent accesses.  Namely, when timer start is
triggered twice, list_add_tail() is called twice, too.  This ends
up with the link corruption and triggers KASAN error.

The simplest fix would be replacing list_add_tail() with
list_move_tail(), but fundamentally it's the problem that we don't
check the double start/stop correctly.  So, the right fix here is to
add the proper checks to snd_timer_start() and snd_timer_stop() (and
their variants).

BugLink: http://lkml.kernel.org/r/CACT4Y+ZyPRoMQjmawbvmCEDrkBD2BQuH7R09=eOkf5ESK8kJAw@mail.gmail.com
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
---
 sound/core/timer.c | 30 ++++++++++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/sound/core/timer.c b/sound/core/timer.c
index 0447565c77af..e1d5a1061113 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -451,6 +451,10 @@ static int snd_timer_start_slave(struct snd_timer_instance *timeri)
 	unsigned long flags;
 
 	spin_lock_irqsave(&slave_active_lock, flags);
+	if (timeri->flags & SNDRV_TIMER_IFLG_RUNNING) {
+		spin_unlock_irqrestore(&slave_active_lock, flags);
+		return -EBUSY;
+	}
 	timeri->flags |= SNDRV_TIMER_IFLG_RUNNING;
 	if (timeri->master && timeri->timer) {
 		spin_lock(&timeri->timer->lock);
@@ -475,7 +479,8 @@ int snd_timer_start(struct snd_timer_instance *timeri, unsigned int ticks)
 		return -EINVAL;
 	if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
 		result = snd_timer_start_slave(timeri);
-		snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START);
+		if (result >= 0)
+			snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START);
 		return result;
 	}
 	timer = timeri->timer;
@@ -484,11 +489,18 @@ int snd_timer_start(struct snd_timer_instance *timeri, unsigned int ticks)
 	if (timer->card && timer->card->shutdown)
 		return -ENODEV;
 	spin_lock_irqsave(&timer->lock, flags);
+	if (timeri->flags & (SNDRV_TIMER_IFLG_RUNNING |
+			     SNDRV_TIMER_IFLG_START)) {
+		result = -EBUSY;
+		goto unlock;
+	}
 	timeri->ticks = timeri->cticks = ticks;
 	timeri->pticks = 0;
 	result = snd_timer_start1(timer, timeri, ticks);
+ unlock:
 	spin_unlock_irqrestore(&timer->lock, flags);
-	snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START);
+	if (result >= 0)
+		snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START);
 	return result;
 }
 
@@ -502,6 +514,10 @@ static int _snd_timer_stop(struct snd_timer_instance *timeri, int event)
 
 	if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
 		spin_lock_irqsave(&slave_active_lock, flags);
+		if (!(timeri->flags & SNDRV_TIMER_IFLG_RUNNING)) {
+			spin_unlock_irqrestore(&slave_active_lock, flags);
+			return -EBUSY;
+		}
 		timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
 		list_del_init(&timeri->ack_list);
 		list_del_init(&timeri->active_list);
@@ -512,6 +528,11 @@ static int _snd_timer_stop(struct snd_timer_instance *timeri, int event)
 	if (!timer)
 		return -EINVAL;
 	spin_lock_irqsave(&timer->lock, flags);
+	if (!(timeri->flags & (SNDRV_TIMER_IFLG_RUNNING |
+			       SNDRV_TIMER_IFLG_START))) {
+		spin_unlock_irqrestore(&timer->lock, flags);
+		return -EBUSY;
+	}
 	list_del_init(&timeri->ack_list);
 	list_del_init(&timeri->active_list);
 	if (timer->card && timer->card->shutdown) {
@@ -581,10 +602,15 @@ int snd_timer_continue(struct snd_timer_instance *timeri)
 	if (timer->card && timer->card->shutdown)
 		return -ENODEV;
 	spin_lock_irqsave(&timer->lock, flags);
+	if (timeri->flags & SNDRV_TIMER_IFLG_RUNNING) {
+		result = -EBUSY;
+		goto unlock;
+	}
 	if (!timeri->cticks)
 		timeri->cticks = 1;
 	timeri->pticks = 0;
 	result = snd_timer_start1(timer, timeri, timer->sticks);
+ unlock:
 	spin_unlock_irqrestore(&timer->lock, flags);
 	snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_CONTINUE);
 	return result;

[toc] | [prev] | [next] | [standalone]


#1344096 — [PATCH 3.16.y-ckt 091/129] Btrfs: fix hang on extent buffer lock caused by the inode_paths ioctl

FromLuis Henriques <luis.henriques@canonical.com>
Date2016-02-26 11:50 +0100
Subject[PATCH 3.16.y-ckt 091/129] Btrfs: fix hang on extent buffer lock caused by the inode_paths ioctl
Message-ID<r6o8d-1Sy-91@gated-at.bofh.it>
In reply to#1344036
3.16.7-ckt25 -stable review patch.  If anyone has any objections, please let me know.

---8<------------------------------------------------------------

From: Filipe Manana <fdmanana@suse.com>

commit 0c0fe3b0fa45082cd752553fdb3a4b42503a118e upstream.

While doing some tests I ran into an hang on an extent buffer's rwlock
that produced the following trace:

[39389.800012] NMI watchdog: BUG: soft lockup - CPU#15 stuck for 22s! [fdm-stress:32166]
[39389.800016] NMI watchdog: BUG: soft lockup - CPU#14 stuck for 22s! [fdm-stress:32165]
[39389.800016] Modules linked in: btrfs dm_mod ppdev xor sha256_generic hmac raid6_pq drbg ansi_cprng aesni_intel i2c_piix4 acpi_cpufreq aes_x86_64 ablk_helper tpm_tis parport_pc i2c_core sg cryptd evdev psmouse lrw tpm parport gf128mul serio_raw pcspkr glue_helper processor button loop autofs4 ext4 crc16 mbcache jbd2 sd_mod sr_mod cdrom ata_generic virtio_scsi ata_piix libata virtio_pci virtio_ring crc32c_intel scsi_mod e1000 virtio floppy [last unloaded: btrfs]
[39389.800016] irq event stamp: 0
[39389.800016] hardirqs last  enabled at (0): [<          (null)>]           (null)
[39389.800016] hardirqs last disabled at (0): [<ffffffff8104e58d>] copy_process+0x638/0x1a35
[39389.800016] softirqs last  enabled at (0): [<ffffffff8104e58d>] copy_process+0x638/0x1a35
[39389.800016] softirqs last disabled at (0): [<          (null)>]           (null)
[39389.800016] CPU: 14 PID: 32165 Comm: fdm-stress Not tainted 4.4.0-rc6-btrfs-next-18+ #1
[39389.800016] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS by qemu-project.org 04/01/2014
[39389.800016] task: ffff880175b1ca40 ti: ffff8800a185c000 task.ti: ffff8800a185c000
[39389.800016] RIP: 0010:[<ffffffff810902af>]  [<ffffffff810902af>] queued_spin_lock_slowpath+0x57/0x158
[39389.800016] RSP: 0018:ffff8800a185fb80  EFLAGS: 00000202
[39389.800016] RAX: 0000000000000101 RBX: ffff8801710c4e9c RCX: 0000000000000101
[39389.800016] RDX: 0000000000000100 RSI: 0000000000000001 RDI: 0000000000000001
[39389.800016] RBP: ffff8800a185fb98 R08: 0000000000000001 R09: 0000000000000000
[39389.800016] R10: ffff8800a185fb68 R11: 6db6db6db6db6db7 R12: ffff8801710c4e98
[39389.800016] R13: ffff880175b1ca40 R14: ffff8800a185fc10 R15: ffff880175b1ca40
[39389.800016] FS:  00007f6d37fff700(0000) GS:ffff8802be9c0000(0000) knlGS:0000000000000000
[39389.800016] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[39389.800016] CR2: 00007f6d300019b8 CR3: 0000000037c93000 CR4: 00000000001406e0
[39389.800016] Stack:
[39389.800016]  ffff8801710c4e98 ffff8801710c4e98 ffff880175b1ca40 ffff8800a185fbb0
[39389.800016]  ffffffff81091e11 ffff8801710c4e98 ffff8800a185fbc8 ffffffff81091895
[39389.800016]  ffff8801710c4e98 ffff8800a185fbe8 ffffffff81486c5c ffffffffa067288c
[39389.800016] Call Trace:
[39389.800016]  [<ffffffff81091e11>] queued_read_lock_slowpath+0x46/0x60
[39389.800016]  [<ffffffff81091895>] do_raw_read_lock+0x3e/0x41
[39389.800016]  [<ffffffff81486c5c>] _raw_read_lock+0x3d/0x44
[39389.800016]  [<ffffffffa067288c>] ? btrfs_tree_read_lock+0x54/0x125 [btrfs]
[39389.800016]  [<ffffffffa067288c>] btrfs_tree_read_lock+0x54/0x125 [btrfs]
[39389.800016]  [<ffffffffa0622ced>] ? btrfs_find_item+0xa7/0xd2 [btrfs]
[39389.800016]  [<ffffffffa069363f>] btrfs_ref_to_path+0xd6/0x174 [btrfs]
[39389.800016]  [<ffffffffa0693730>] inode_to_path+0x53/0xa2 [btrfs]
[39389.800016]  [<ffffffffa0693e2e>] paths_from_inode+0x117/0x2ec [btrfs]
[39389.800016]  [<ffffffffa0670cff>] btrfs_ioctl+0xd5b/0x2793 [btrfs]
[39389.800016]  [<ffffffff8108a8b0>] ? arch_local_irq_save+0x9/0xc
[39389.800016]  [<ffffffff81276727>] ? __this_cpu_preempt_check+0x13/0x15
[39389.800016]  [<ffffffff8108a8b0>] ? arch_local_irq_save+0x9/0xc
[39389.800016]  [<ffffffff8118b3d4>] ? rcu_read_unlock+0x3e/0x5d
[39389.800016]  [<ffffffff811822f8>] do_vfs_ioctl+0x42b/0x4ea
[39389.800016]  [<ffffffff8118b4f3>] ? __fget_light+0x62/0x71
[39389.800016]  [<ffffffff8118240e>] SyS_ioctl+0x57/0x79
[39389.800016]  [<ffffffff814872d7>] entry_SYSCALL_64_fastpath+0x12/0x6f
[39389.800016] Code: b9 01 01 00 00 f7 c6 00 ff ff ff 75 32 83 fe 01 89 ca 89 f0 0f 45 d7 f0 0f b1 13 39 f0 74 04 89 c6 eb e2 ff ca 0f 84 fa 00 00 00 <8b> 03 84 c0 74 04 f3 90 eb f6 66 c7 03 01 00 e9 e6 00 00 00 e8
[39389.800012] Modules linked in: btrfs dm_mod ppdev xor sha256_generic hmac raid6_pq drbg ansi_cprng aesni_intel i2c_piix4 acpi_cpufreq aes_x86_64 ablk_helper tpm_tis parport_pc i2c_core sg cryptd evdev psmouse lrw tpm parport gf128mul serio_raw pcspkr glue_helper processor button loop autofs4 ext4 crc16 mbcache jbd2 sd_mod sr_mod cdrom ata_generic virtio_scsi ata_piix libata virtio_pci virtio_ring crc32c_intel scsi_mod e1000 virtio floppy [last unloaded: btrfs]
[39389.800012] irq event stamp: 0
[39389.800012] hardirqs last  enabled at (0): [<          (null)>]           (null)
[39389.800012] hardirqs last disabled at (0): [<ffffffff8104e58d>] copy_process+0x638/0x1a35
[39389.800012] softirqs last  enabled at (0): [<ffffffff8104e58d>] copy_process+0x638/0x1a35
[39389.800012] softirqs last disabled at (0): [<          (null)>]           (null)
[39389.800012] CPU: 15 PID: 32166 Comm: fdm-stress Tainted: G             L  4.4.0-rc6-btrfs-next-18+ #1
[39389.800012] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS by qemu-project.org 04/01/2014
[39389.800012] task: ffff880179294380 ti: ffff880034a60000 task.ti: ffff880034a60000
[39389.800012] RIP: 0010:[<ffffffff81091e8d>]  [<ffffffff81091e8d>] queued_write_lock_slowpath+0x62/0x72
[39389.800012] RSP: 0018:ffff880034a639f0  EFLAGS: 00000206
[39389.800012] RAX: 0000000000000101 RBX: ffff8801710c4e98 RCX: 0000000000000000
[39389.800012] RDX: 00000000000000ff RSI: 0000000000000000 RDI: ffff8801710c4e9c
[39389.800012] RBP: ffff880034a639f8 R08: 0000000000000001 R09: 0000000000000000
[39389.800012] R10: ffff880034a639b0 R11: 0000000000001000 R12: ffff8801710c4e98
[39389.800012] R13: 0000000000000001 R14: ffff880172cbc000 R15: ffff8801710c4e00
[39389.800012] FS:  00007f6d377fe700(0000) GS:ffff8802be9e0000(0000) knlGS:0000000000000000
[39389.800012] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[39389.800012] CR2: 00007f6d3d3c1000 CR3: 0000000037c93000 CR4: 00000000001406e0
[39389.800012] Stack:
[39389.800012]  ffff8801710c4e98 ffff880034a63a10 ffffffff81091963 ffff8801710c4e98
[39389.800012]  ffff880034a63a30 ffffffff81486f1b ffffffffa0672cb3 ffff8801710c4e00
[39389.800012]  ffff880034a63a78 ffffffffa0672cb3 ffff8801710c4e00 ffff880034a63a58
[39389.800012] Call Trace:
[39389.800012]  [<ffffffff81091963>] do_raw_write_lock+0x72/0x8c
[39389.800012]  [<ffffffff81486f1b>] _raw_write_lock+0x3a/0x41
[39389.800012]  [<ffffffffa0672cb3>] ? btrfs_tree_lock+0x119/0x251 [btrfs]
[39389.800012]  [<ffffffffa0672cb3>] btrfs_tree_lock+0x119/0x251 [btrfs]
[39389.800012]  [<ffffffffa061aeba>] ? rcu_read_unlock+0x5b/0x5d [btrfs]
[39389.800012]  [<ffffffffa061ce13>] ? btrfs_root_node+0xda/0xe6 [btrfs]
[39389.800012]  [<ffffffffa061ce83>] btrfs_lock_root_node+0x22/0x42 [btrfs]
[39389.800012]  [<ffffffffa062046b>] btrfs_search_slot+0x1b8/0x758 [btrfs]
[39389.800012]  [<ffffffff810fc6b0>] ? time_hardirqs_on+0x15/0x28
[39389.800012]  [<ffffffffa06365db>] btrfs_lookup_inode+0x31/0x95 [btrfs]
[39389.800012]  [<ffffffff8108d62f>] ? trace_hardirqs_on+0xd/0xf
[39389.800012]  [<ffffffff8148482b>] ? mutex_lock_nested+0x397/0x3bc
[39389.800012]  [<ffffffffa068821b>] __btrfs_update_delayed_inode+0x59/0x1c0 [btrfs]
[39389.800012]  [<ffffffffa068858e>] __btrfs_commit_inode_delayed_items+0x194/0x5aa [btrfs]
[39389.800012]  [<ffffffff81486ab7>] ? _raw_spin_unlock+0x31/0x44
[39389.800012]  [<ffffffffa0688a48>] __btrfs_run_delayed_items+0xa4/0x15c [btrfs]
[39389.800012]  [<ffffffffa0688d62>] btrfs_run_delayed_items+0x11/0x13 [btrfs]
[39389.800012]  [<ffffffffa064048e>] btrfs_commit_transaction+0x234/0x96e [btrfs]
[39389.800012]  [<ffffffffa0618d10>] btrfs_sync_fs+0x145/0x1ad [btrfs]
[39389.800012]  [<ffffffffa0671176>] btrfs_ioctl+0x11d2/0x2793 [btrfs]
[39389.800012]  [<ffffffff8108a8b0>] ? arch_local_irq_save+0x9/0xc
[39389.800012]  [<ffffffff81140261>] ? __might_fault+0x4c/0xa7
[39389.800012]  [<ffffffff81140261>] ? __might_fault+0x4c/0xa7
[39389.800012]  [<ffffffff8108a8b0>] ? arch_local_irq_save+0x9/0xc
[39389.800012]  [<ffffffff8118b3d4>] ? rcu_read_unlock+0x3e/0x5d
[39389.800012]  [<ffffffff811822f8>] do_vfs_ioctl+0x42b/0x4ea
[39389.800012]  [<ffffffff8118b4f3>] ? __fget_light+0x62/0x71
[39389.800012]  [<ffffffff8118240e>] SyS_ioctl+0x57/0x79
[39389.800012]  [<ffffffff814872d7>] entry_SYSCALL_64_fastpath+0x12/0x6f
[39389.800012] Code: f0 0f b1 13 85 c0 75 ef eb 2a f3 90 8a 03 84 c0 75 f8 f0 0f b0 13 84 c0 75 f0 ba ff 00 00 00 eb 0a f0 0f b1 13 ff c8 74 0b f3 90 <8b> 03 83 f8 01 75 f7 eb ed c6 43 04 00 5b 5d c3 0f 1f 44 00 00

This happens because in the code path executed by the inode_paths ioctl we
end up nesting two calls to read lock a leaf's rwlock when after the first
call to read_lock() and before the second call to read_lock(), another
task (running the delayed items as part of a transaction commit) has
already called write_lock() against the leaf's rwlock. This situation is
illustrated by the following diagram:

         Task A                       Task B

  btrfs_ref_to_path()               btrfs_commit_transaction()
    read_lock(&eb->lock);

                                      btrfs_run_delayed_items()
                                        __btrfs_commit_inode_delayed_items()
                                          __btrfs_update_delayed_inode()
                                            btrfs_lookup_inode()

                                              write_lock(&eb->lock);
                                                --> task waits for lock

    read_lock(&eb->lock);
    --> makes this task hang
        forever (and task B too
	of course)

So fix this by avoiding doing the nested read lock, which is easily
avoidable. This issue does not happen if task B calls write_lock() after
task A does the second call to read_lock(), however there does not seem
to exist anything in the documentation that mentions what is the expected
behaviour for recursive locking of rwlocks (leaving the idea that doing
so is not a good usage of rwlocks).

Also, as a side effect necessary for this fix, make sure we do not
needlessly read lock extent buffers when the input path has skip_locking
set (used when called from send).

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
---
 fs/btrfs/backref.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index b16815417125..93afd58764e6 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -1286,7 +1286,8 @@ char *btrfs_ref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path,
 			read_extent_buffer(eb, dest + bytes_left,
 					   name_off, name_len);
 		if (eb != eb_in) {
-			btrfs_tree_read_unlock_blocking(eb);
+			if (!path->skip_locking)
+				btrfs_tree_read_unlock_blocking(eb);
 			free_extent_buffer(eb);
 		}
 		ret = inode_ref_info(parent, 0, fs_root, path, &found_key);
@@ -1305,9 +1306,10 @@ char *btrfs_ref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path,
 		eb = path->nodes[0];
 		/* make sure we can use eb after releasing the path */
 		if (eb != eb_in) {
-			atomic_inc(&eb->refs);
-			btrfs_tree_read_lock(eb);
-			btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK);
+			if (!path->skip_locking)
+				btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK);
+			path->nodes[0] = NULL;
+			path->locks[0] = 0;
 		}
 		btrfs_release_path(path);
 		iref = btrfs_item_ptr(eb, slot, struct btrfs_inode_ref);

[toc] | [prev] | [next] | [standalone]


#1344097 — [PATCH 3.16.y-ckt 080/129] ALSA: rawmidi: Make snd_rawmidi_transmit() race-free

FromLuis Henriques <luis.henriques@canonical.com>
Date2016-02-26 11:50 +0100
Subject[PATCH 3.16.y-ckt 080/129] ALSA: rawmidi: Make snd_rawmidi_transmit() race-free
Message-ID<r6o8d-1Sy-93@gated-at.bofh.it>
In reply to#1344036
3.16.7-ckt25 -stable review patch.  If anyone has any objections, please let me know.

---8<------------------------------------------------------------

From: Takashi Iwai <tiwai@suse.de>

commit 06ab30034ed9c200a570ab13c017bde248ddb2a6 upstream.

A kernel WARNING in snd_rawmidi_transmit_ack() is triggered by
syzkaller fuzzer:
  WARNING: CPU: 1 PID: 20739 at sound/core/rawmidi.c:1136
Call Trace:
 [<     inline     >] __dump_stack lib/dump_stack.c:15
 [<ffffffff82999e2d>] dump_stack+0x6f/0xa2 lib/dump_stack.c:50
 [<ffffffff81352089>] warn_slowpath_common+0xd9/0x140 kernel/panic.c:482
 [<ffffffff813522b9>] warn_slowpath_null+0x29/0x30 kernel/panic.c:515
 [<ffffffff84f80bd5>] snd_rawmidi_transmit_ack+0x275/0x400 sound/core/rawmidi.c:1136
 [<ffffffff84fdb3c1>] snd_virmidi_output_trigger+0x4b1/0x5a0 sound/core/seq/seq_virmidi.c:163
 [<     inline     >] snd_rawmidi_output_trigger sound/core/rawmidi.c:150
 [<ffffffff84f87ed9>] snd_rawmidi_kernel_write1+0x549/0x780 sound/core/rawmidi.c:1223
 [<ffffffff84f89fd3>] snd_rawmidi_write+0x543/0xb30 sound/core/rawmidi.c:1273
 [<ffffffff817b0323>] __vfs_write+0x113/0x480 fs/read_write.c:528
 [<ffffffff817b1db7>] vfs_write+0x167/0x4a0 fs/read_write.c:577
 [<     inline     >] SYSC_write fs/read_write.c:624
 [<ffffffff817b50a1>] SyS_write+0x111/0x220 fs/read_write.c:616
 [<ffffffff86336c36>] entry_SYSCALL_64_fastpath+0x16/0x7a arch/x86/entry/entry_64.S:185

Also a similar warning is found but in another path:
Call Trace:
 [<     inline     >] __dump_stack lib/dump_stack.c:15
 [<ffffffff82be2c0d>] dump_stack+0x6f/0xa2 lib/dump_stack.c:50
 [<ffffffff81355139>] warn_slowpath_common+0xd9/0x140 kernel/panic.c:482
 [<ffffffff81355369>] warn_slowpath_null+0x29/0x30 kernel/panic.c:515
 [<ffffffff8527e69a>] rawmidi_transmit_ack+0x24a/0x3b0 sound/core/rawmidi.c:1133
 [<ffffffff8527e851>] snd_rawmidi_transmit_ack+0x51/0x80 sound/core/rawmidi.c:1163
 [<ffffffff852d9046>] snd_virmidi_output_trigger+0x2b6/0x570 sound/core/seq/seq_virmidi.c:185
 [<     inline     >] snd_rawmidi_output_trigger sound/core/rawmidi.c:150
 [<ffffffff85285a0b>] snd_rawmidi_kernel_write1+0x4bb/0x760 sound/core/rawmidi.c:1252
 [<ffffffff85287b73>] snd_rawmidi_write+0x543/0xb30 sound/core/rawmidi.c:1302
 [<ffffffff817ba5f3>] __vfs_write+0x113/0x480 fs/read_write.c:528
 [<ffffffff817bc087>] vfs_write+0x167/0x4a0 fs/read_write.c:577
 [<     inline     >] SYSC_write fs/read_write.c:624
 [<ffffffff817bf371>] SyS_write+0x111/0x220 fs/read_write.c:616
 [<ffffffff86660276>] entry_SYSCALL_64_fastpath+0x16/0x7a arch/x86/entry/entry_64.S:185

In the former case, the reason is that virmidi has an open code
calling snd_rawmidi_transmit_ack() with the value calculated outside
the spinlock.   We may use snd_rawmidi_transmit() in a loop just for
consuming the input data, but even there, there is a race between
snd_rawmidi_transmit_peek() and snd_rawmidi_tranmit_ack().

Similarly in the latter case, it calls snd_rawmidi_transmit_peek() and
snd_rawmidi_tranmit_ack() separately without protection, so they are
racy as well.

The patch tries to address these issues by the following ways:
- Introduce the unlocked versions of snd_rawmidi_transmit_peek() and
  snd_rawmidi_transmit_ack() to be called inside the explicit lock.
- Rewrite snd_rawmidi_transmit() to be race-free (the former case).
- Make the split calls (the latter case) protected in the rawmidi spin
  lock.

BugLink: http://lkml.kernel.org/r/CACT4Y+YPq1+cYLkadwjWa5XjzF1_Vki1eHnVn-Lm0hzhSpu5PA@mail.gmail.com
BugLink: http://lkml.kernel.org/r/CACT4Y+acG4iyphdOZx47Nyq_VHGbpJQK-6xNpiqUjaZYqsXOGw@mail.gmail.com
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Tested-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
---
 include/sound/rawmidi.h      |  4 ++
 sound/core/rawmidi.c         | 98 ++++++++++++++++++++++++++++++++------------
 sound/core/seq/seq_virmidi.c | 17 +++++---
 3 files changed, 88 insertions(+), 31 deletions(-)

diff --git a/include/sound/rawmidi.h b/include/sound/rawmidi.h
index 311dafe6cc4b..5bd2bfbf6dd1 100644
--- a/include/sound/rawmidi.h
+++ b/include/sound/rawmidi.h
@@ -165,6 +165,10 @@ int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
 int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count);
 int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream,
 			 unsigned char *buffer, int count);
+int __snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
+			      unsigned char *buffer, int count);
+int __snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream,
+			       int count);
 
 /* main midi functions */
 
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 1d9dbed43b84..4a41334a5c13 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -1065,23 +1065,16 @@ int snd_rawmidi_transmit_empty(struct snd_rawmidi_substream *substream)
 EXPORT_SYMBOL(snd_rawmidi_transmit_empty);
 
 /**
- * snd_rawmidi_transmit_peek - copy data from the internal buffer
+ * __snd_rawmidi_transmit_peek - copy data from the internal buffer
  * @substream: the rawmidi substream
  * @buffer: the buffer pointer
  * @count: data size to transfer
  *
- * Copies data from the internal output buffer to the given buffer.
- *
- * Call this in the interrupt handler when the midi output is ready,
- * and call snd_rawmidi_transmit_ack() after the transmission is
- * finished.
- *
- * Return: The size of copied data, or a negative error code on failure.
+ * This is a variant of snd_rawmidi_transmit_peek() without spinlock.
  */
-int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
+int __snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
 			      unsigned char *buffer, int count)
 {
-	unsigned long flags;
 	int result, count1;
 	struct snd_rawmidi_runtime *runtime = substream->runtime;
 
@@ -1091,7 +1084,6 @@ int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
 		return -EINVAL;
 	}
 	result = 0;
-	spin_lock_irqsave(&runtime->lock, flags);
 	if (runtime->avail >= runtime->buffer_size) {
 		/* warning: lowlevel layer MUST trigger down the hardware */
 		goto __skip;
@@ -1116,25 +1108,47 @@ int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
 		}
 	}
       __skip:
+	return result;
+}
+EXPORT_SYMBOL(__snd_rawmidi_transmit_peek);
+
+/**
+ * snd_rawmidi_transmit_peek - copy data from the internal buffer
+ * @substream: the rawmidi substream
+ * @buffer: the buffer pointer
+ * @count: data size to transfer
+ *
+ * Copies data from the internal output buffer to the given buffer.
+ *
+ * Call this in the interrupt handler when the midi output is ready,
+ * and call snd_rawmidi_transmit_ack() after the transmission is
+ * finished.
+ *
+ * Return: The size of copied data, or a negative error code on failure.
+ */
+int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
+			      unsigned char *buffer, int count)
+{
+	struct snd_rawmidi_runtime *runtime = substream->runtime;
+	int result;
+	unsigned long flags;
+
+	spin_lock_irqsave(&runtime->lock, flags);
+	result = __snd_rawmidi_transmit_peek(substream, buffer, count);
 	spin_unlock_irqrestore(&runtime->lock, flags);
 	return result;
 }
 EXPORT_SYMBOL(snd_rawmidi_transmit_peek);
 
 /**
- * snd_rawmidi_transmit_ack - acknowledge the transmission
+ * __snd_rawmidi_transmit_ack - acknowledge the transmission
  * @substream: the rawmidi substream
  * @count: the transferred count
  *
- * Advances the hardware pointer for the internal output buffer with
- * the given size and updates the condition.
- * Call after the transmission is finished.
- *
- * Return: The advanced size if successful, or a negative error code on failure.
+ * This is a variant of __snd_rawmidi_transmit_ack() without spinlock.
  */
-int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count)
+int __snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count)
 {
-	unsigned long flags;
 	struct snd_rawmidi_runtime *runtime = substream->runtime;
 
 	if (runtime->buffer == NULL) {
@@ -1142,7 +1156,6 @@ int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count)
 			  "snd_rawmidi_transmit_ack: output is not active!!!\n");
 		return -EINVAL;
 	}
-	spin_lock_irqsave(&runtime->lock, flags);
 	snd_BUG_ON(runtime->avail + count > runtime->buffer_size);
 	runtime->hw_ptr += count;
 	runtime->hw_ptr %= runtime->buffer_size;
@@ -1152,9 +1165,32 @@ int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count)
 		if (runtime->drain || snd_rawmidi_ready(substream))
 			wake_up(&runtime->sleep);
 	}
-	spin_unlock_irqrestore(&runtime->lock, flags);
 	return count;
 }
+EXPORT_SYMBOL(__snd_rawmidi_transmit_ack);
+
+/**
+ * snd_rawmidi_transmit_ack - acknowledge the transmission
+ * @substream: the rawmidi substream
+ * @count: the transferred count
+ *
+ * Advances the hardware pointer for the internal output buffer with
+ * the given size and updates the condition.
+ * Call after the transmission is finished.
+ *
+ * Return: The advanced size if successful, or a negative error code on failure.
+ */
+int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count)
+{
+	struct snd_rawmidi_runtime *runtime = substream->runtime;
+	int result;
+	unsigned long flags;
+
+	spin_lock_irqsave(&runtime->lock, flags);
+	result = __snd_rawmidi_transmit_ack(substream, count);
+	spin_unlock_irqrestore(&runtime->lock, flags);
+	return result;
+}
 EXPORT_SYMBOL(snd_rawmidi_transmit_ack);
 
 /**
@@ -1170,12 +1206,22 @@ EXPORT_SYMBOL(snd_rawmidi_transmit_ack);
 int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream,
 			 unsigned char *buffer, int count)
 {
+	struct snd_rawmidi_runtime *runtime = substream->runtime;
+	int result;
+	unsigned long flags;
+
+	spin_lock_irqsave(&runtime->lock, flags);
 	if (!substream->opened)
-		return -EBADFD;
-	count = snd_rawmidi_transmit_peek(substream, buffer, count);
-	if (count < 0)
-		return count;
-	return snd_rawmidi_transmit_ack(substream, count);
+		result = -EBADFD;
+	else {
+		count = __snd_rawmidi_transmit_peek(substream, buffer, count);
+		if (count <= 0)
+			result = count;
+		else
+			result = __snd_rawmidi_transmit_ack(substream, count);
+	}
+	spin_unlock_irqrestore(&runtime->lock, flags);
+	return result;
 }
 EXPORT_SYMBOL(snd_rawmidi_transmit);
 
diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c
index f2975927551e..81134e067184 100644
--- a/sound/core/seq/seq_virmidi.c
+++ b/sound/core/seq/seq_virmidi.c
@@ -155,21 +155,26 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream,
 	struct snd_virmidi *vmidi = substream->runtime->private_data;
 	int count, res;
 	unsigned char buf[32], *pbuf;
+	unsigned long flags;
 
 	if (up) {
 		vmidi->trigger = 1;
 		if (vmidi->seq_mode == SNDRV_VIRMIDI_SEQ_DISPATCH &&
 		    !(vmidi->rdev->flags & SNDRV_VIRMIDI_SUBSCRIBE)) {
-			snd_rawmidi_transmit_ack(substream, substream->runtime->buffer_size - substream->runtime->avail);
-			return;		/* ignored */
+			while (snd_rawmidi_transmit(substream, buf,
+						    sizeof(buf)) > 0) {
+				/* ignored */
+			}
+			return;
 		}
 		if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) {
 			if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0)
 				return;
 			vmidi->event.type = SNDRV_SEQ_EVENT_NONE;
 		}
+		spin_lock_irqsave(&substream->runtime->lock, flags);
 		while (1) {
-			count = snd_rawmidi_transmit_peek(substream, buf, sizeof(buf));
+			count = __snd_rawmidi_transmit_peek(substream, buf, sizeof(buf));
 			if (count <= 0)
 				break;
 			pbuf = buf;
@@ -179,16 +184,18 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream,
 					snd_midi_event_reset_encode(vmidi->parser);
 					continue;
 				}
-				snd_rawmidi_transmit_ack(substream, res);
+				__snd_rawmidi_transmit_ack(substream, res);
 				pbuf += res;
 				count -= res;
 				if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) {
 					if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0)
-						return;
+						goto out;
 					vmidi->event.type = SNDRV_SEQ_EVENT_NONE;
 				}
 			}
 		}
+	out:
+		spin_unlock_irqrestore(&substream->runtime->lock, flags);
 	} else {
 		vmidi->trigger = 0;
 	}

[toc] | [prev] | [next] | [standalone]


#1344098 — [PATCH 3.16.y-ckt 045/129] crypto: algif_skcipher - Add nokey compatibility path

FromLuis Henriques <luis.henriques@canonical.com>
Date2016-02-26 12:00 +0100
Subject[PATCH 3.16.y-ckt 045/129] crypto: algif_skcipher - Add nokey compatibility path
Message-ID<r6ohQ-1Wt-3@gated-at.bofh.it>
In reply to#1344036
3.16.7-ckt25 -stable review patch.  If anyone has any objections, please let me know.

---8<------------------------------------------------------------

From: Herbert Xu <herbert@gondor.apana.org.au>

commit a0fa2d037129a9849918a92d91b79ed6c7bd2818 upstream.

This patch adds a compatibility path to support old applications
that do acept(2) before setkey.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
[bwh: Backported to 3.2: add struct kiocb * parameter to {recv,send}msg ops]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
---
 crypto/algif_skcipher.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 144 insertions(+), 5 deletions(-)

diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
index 10c1fd04f1ed..f0037c0c36b7 100644
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -549,6 +549,99 @@ static struct proto_ops algif_skcipher_ops = {
 	.poll		=	skcipher_poll,
 };
 
+static int skcipher_check_key(struct socket *sock)
+{
+	int err;
+	struct sock *psk;
+	struct alg_sock *pask;
+	struct skcipher_tfm *tfm;
+	struct sock *sk = sock->sk;
+	struct alg_sock *ask = alg_sk(sk);
+
+	if (ask->refcnt)
+		return 0;
+
+	psk = ask->parent;
+	pask = alg_sk(ask->parent);
+	tfm = pask->private;
+
+	err = -ENOKEY;
+	lock_sock(psk);
+	if (!tfm->has_key)
+		goto unlock;
+
+	if (!pask->refcnt++)
+		sock_hold(psk);
+
+	ask->refcnt = 1;
+	sock_put(psk);
+
+	err = 0;
+
+unlock:
+	release_sock(psk);
+
+	return err;
+}
+
+static int skcipher_sendmsg_nokey(struct kiocb *unused, struct socket *sock,
+				  struct msghdr *msg, size_t size)
+{
+	int err;
+
+	err = skcipher_check_key(sock);
+	if (err)
+		return err;
+
+	return skcipher_sendmsg(unused, sock, msg, size);
+}
+
+static ssize_t skcipher_sendpage_nokey(struct socket *sock, struct page *page,
+				       int offset, size_t size, int flags)
+{
+	int err;
+
+	err = skcipher_check_key(sock);
+	if (err)
+		return err;
+
+	return skcipher_sendpage(sock, page, offset, size, flags);
+}
+
+static int skcipher_recvmsg_nokey(struct kiocb *unused, struct socket *sock,
+				  struct msghdr *msg, size_t ignored, int flags)
+{
+	int err;
+
+	err = skcipher_check_key(sock);
+	if (err)
+		return err;
+
+	return skcipher_recvmsg(unused, sock, msg, ignored, flags);
+}
+
+static struct proto_ops algif_skcipher_ops_nokey = {
+	.family		=	PF_ALG,
+
+	.connect	=	sock_no_connect,
+	.socketpair	=	sock_no_socketpair,
+	.getname	=	sock_no_getname,
+	.ioctl		=	sock_no_ioctl,
+	.listen		=	sock_no_listen,
+	.shutdown	=	sock_no_shutdown,
+	.getsockopt	=	sock_no_getsockopt,
+	.mmap		=	sock_no_mmap,
+	.bind		=	sock_no_bind,
+	.accept		=	sock_no_accept,
+	.setsockopt	=	sock_no_setsockopt,
+
+	.release	=	af_alg_release,
+	.sendmsg	=	skcipher_sendmsg_nokey,
+	.sendpage	=	skcipher_sendpage_nokey,
+	.recvmsg	=	skcipher_recvmsg_nokey,
+	.poll		=	skcipher_poll,
+};
+
 static void *skcipher_bind(const char *name, u32 type, u32 mask)
 {
 	struct skcipher_tfm *tfm;
@@ -588,7 +681,7 @@ static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen)
 	return err;
 }
 
-static void skcipher_sock_destruct(struct sock *sk)
+static void skcipher_sock_destruct_common(struct sock *sk)
 {
 	struct alg_sock *ask = alg_sk(sk);
 	struct skcipher_ctx *ctx = ask->private;
@@ -597,10 +690,33 @@ static void skcipher_sock_destruct(struct sock *sk)
 	skcipher_free_sgl(sk);
 	sock_kfree_s(sk, ctx->iv, crypto_ablkcipher_ivsize(tfm));
 	sock_kfree_s(sk, ctx, ctx->len);
+}
+
+static void skcipher_sock_destruct(struct sock *sk)
+{
+	skcipher_sock_destruct_common(sk);
 	af_alg_release_parent(sk);
 }
 
-static int skcipher_accept_parent(void *private, struct sock *sk)
+static void skcipher_release_parent_nokey(struct sock *sk)
+{
+	struct alg_sock *ask = alg_sk(sk);
+
+	if (!ask->refcnt) {
+		sock_put(ask->parent);
+		return;
+	}
+
+	af_alg_release_parent(sk);
+}
+
+static void skcipher_sock_destruct_nokey(struct sock *sk)
+{
+	skcipher_sock_destruct_common(sk);
+	skcipher_release_parent_nokey(sk);
+}
+
+static int skcipher_accept_parent_common(void *private, struct sock *sk)
 {
 	struct skcipher_ctx *ctx;
 	struct alg_sock *ask = alg_sk(sk);
@@ -608,9 +724,6 @@ static int skcipher_accept_parent(void *private, struct sock *sk)
 	struct crypto_ablkcipher *skcipher = tfm->skcipher;
 	unsigned int len = sizeof(*ctx) + crypto_ablkcipher_reqsize(skcipher);
 
-	if (!tfm->has_key)
-		return -ENOKEY;
-
 	ctx = sock_kmalloc(sk, len, GFP_KERNEL);
 	if (!ctx)
 		return -ENOMEM;
@@ -643,12 +756,38 @@ static int skcipher_accept_parent(void *private, struct sock *sk)
 	return 0;
 }
 
+static int skcipher_accept_parent(void *private, struct sock *sk)
+{
+	struct skcipher_tfm *tfm = private;
+
+	if (!tfm->has_key)
+		return -ENOKEY;
+
+	return skcipher_accept_parent_common(private, sk);
+}
+
+static int skcipher_accept_parent_nokey(void *private, struct sock *sk)
+{
+	int err;
+
+	err = skcipher_accept_parent_common(private, sk);
+	if (err)
+		goto out;
+
+	sk->sk_destruct = skcipher_sock_destruct_nokey;
+
+out:
+	return err;
+}
+
 static const struct af_alg_type algif_type_skcipher = {
 	.bind		=	skcipher_bind,
 	.release	=	skcipher_release,
 	.setkey		=	skcipher_setkey,
 	.accept		=	skcipher_accept_parent,
+	.accept_nokey	=	skcipher_accept_parent_nokey,
 	.ops		=	&algif_skcipher_ops,
+	.ops_nokey	=	&algif_skcipher_ops_nokey,
 	.name		=	"skcipher",
 	.owner		=	THIS_MODULE
 };

[toc] | [prev] | [next] | [standalone]


#1344099 — [PATCH 3.16.y-ckt 046/129] crypto: algif_hash - Require setkey before accept(2)

FromLuis Henriques <luis.henriques@canonical.com>
Date2016-02-26 12:00 +0100
Subject[PATCH 3.16.y-ckt 046/129] crypto: algif_hash - Require setkey before accept(2)
Message-ID<r6ohQ-1Wt-7@gated-at.bofh.it>
In reply to#1344036
3.16.7-ckt25 -stable review patch.  If anyone has any objections, please let me know.

---8<------------------------------------------------------------

From: Herbert Xu <herbert@gondor.apana.org.au>

commit 6de62f15b581f920ade22d758f4c338311c2f0d4 upstream.

Hash implementations that require a key may crash if you use
them without setting a key.  This patch adds the necessary checks
so that if you do attempt to use them without a key that we return
-ENOKEY instead of proceeding.

This patch also adds a compatibility path to support old applications
that do acept(2) before setkey.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
[bwh: Backported to 3.2:
 - Add struct kiocb * parameter to {recv,send}msg ops
 - Adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
---
 crypto/algif_hash.c | 201 +++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 193 insertions(+), 8 deletions(-)

diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c
index a68b56a368a8..7a70b07f0be3 100644
--- a/crypto/algif_hash.c
+++ b/crypto/algif_hash.c
@@ -34,6 +34,11 @@ struct hash_ctx {
 	struct ahash_request req;
 };
 
+struct algif_hash_tfm {
+	struct crypto_ahash *hash;
+	bool has_key;
+};
+
 static int hash_sendmsg(struct kiocb *unused, struct socket *sock,
 			struct msghdr *msg, size_t ignored)
 {
@@ -246,22 +251,151 @@ static struct proto_ops algif_hash_ops = {
 	.accept		=	hash_accept,
 };
 
+static int hash_check_key(struct socket *sock)
+{
+	int err;
+	struct sock *psk;
+	struct alg_sock *pask;
+	struct algif_hash_tfm *tfm;
+	struct sock *sk = sock->sk;
+	struct alg_sock *ask = alg_sk(sk);
+
+	if (ask->refcnt)
+		return 0;
+
+	psk = ask->parent;
+	pask = alg_sk(ask->parent);
+	tfm = pask->private;
+
+	err = -ENOKEY;
+	lock_sock(psk);
+	if (!tfm->has_key)
+		goto unlock;
+
+	if (!pask->refcnt++)
+		sock_hold(psk);
+
+	ask->refcnt = 1;
+	sock_put(psk);
+
+	err = 0;
+
+unlock:
+	release_sock(psk);
+
+	return err;
+}
+
+static int hash_sendmsg_nokey(struct kiocb *unused, struct socket *sock,
+			      struct msghdr *msg, size_t size)
+{
+	int err;
+
+	err = hash_check_key(sock);
+	if (err)
+		return err;
+
+	return hash_sendmsg(unused, sock, msg, size);
+}
+
+static ssize_t hash_sendpage_nokey(struct socket *sock, struct page *page,
+				   int offset, size_t size, int flags)
+{
+	int err;
+
+	err = hash_check_key(sock);
+	if (err)
+		return err;
+
+	return hash_sendpage(sock, page, offset, size, flags);
+}
+
+static int hash_recvmsg_nokey(struct kiocb *unused, struct socket *sock,
+			      struct msghdr *msg, size_t ignored, int flags)
+{
+	int err;
+
+	err = hash_check_key(sock);
+	if (err)
+		return err;
+
+	return hash_recvmsg(unused, sock, msg, ignored, flags);
+}
+
+static int hash_accept_nokey(struct socket *sock, struct socket *newsock,
+			     int flags)
+{
+	int err;
+
+	err = hash_check_key(sock);
+	if (err)
+		return err;
+
+	return hash_accept(sock, newsock, flags);
+}
+
+static struct proto_ops algif_hash_ops_nokey = {
+	.family		=	PF_ALG,
+
+	.connect	=	sock_no_connect,
+	.socketpair	=	sock_no_socketpair,
+	.getname	=	sock_no_getname,
+	.ioctl		=	sock_no_ioctl,
+	.listen		=	sock_no_listen,
+	.shutdown	=	sock_no_shutdown,
+	.getsockopt	=	sock_no_getsockopt,
+	.mmap		=	sock_no_mmap,
+	.bind		=	sock_no_bind,
+	.setsockopt	=	sock_no_setsockopt,
+	.poll		=	sock_no_poll,
+
+	.release	=	af_alg_release,
+	.sendmsg	=	hash_sendmsg_nokey,
+	.sendpage	=	hash_sendpage_nokey,
+	.recvmsg	=	hash_recvmsg_nokey,
+	.accept		=	hash_accept_nokey,
+};
+
 static void *hash_bind(const char *name, u32 type, u32 mask)
 {
-	return crypto_alloc_ahash(name, type, mask);
+	struct algif_hash_tfm *tfm;
+	struct crypto_ahash *hash;
+
+	tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
+	if (!tfm)
+		return ERR_PTR(-ENOMEM);
+
+	hash = crypto_alloc_ahash(name, type, mask);
+	if (IS_ERR(hash)) {
+		kfree(tfm);
+		return ERR_CAST(hash);
+	}
+
+	tfm->hash = hash;
+
+	return tfm;
 }
 
 static void hash_release(void *private)
 {
-	crypto_free_ahash(private);
+	struct algif_hash_tfm *tfm = private;
+
+	crypto_free_ahash(tfm->hash);
+	kfree(tfm);
 }
 
 static int hash_setkey(void *private, const u8 *key, unsigned int keylen)
 {
-	return crypto_ahash_setkey(private, key, keylen);
+	struct algif_hash_tfm *tfm = private;
+	int err;
+
+	err = crypto_ahash_setkey(tfm->hash, key, keylen);
+	tfm->has_key = !err;
+
+	return err;
 }
 
-static void hash_sock_destruct(struct sock *sk)
+static void hash_sock_destruct_common(struct sock *sk)
 {
 	struct alg_sock *ask = alg_sk(sk);
 	struct hash_ctx *ctx = ask->private;
@@ -269,15 +403,40 @@ static void hash_sock_destruct(struct sock *sk)
 	sock_kfree_s(sk, ctx->result,
 		     crypto_ahash_digestsize(crypto_ahash_reqtfm(&ctx->req)));
 	sock_kfree_s(sk, ctx, ctx->len);
+}
+
+static void hash_sock_destruct(struct sock *sk)
+{
+	hash_sock_destruct_common(sk);
 	af_alg_release_parent(sk);
 }
 
-static int hash_accept_parent(void *private, struct sock *sk)
+static void hash_release_parent_nokey(struct sock *sk)
+{
+	struct alg_sock *ask = alg_sk(sk);
+
+	if (!ask->refcnt) {
+		sock_put(ask->parent);
+		return;
+	}
+
+	af_alg_release_parent(sk);
+}
+
+static void hash_sock_destruct_nokey(struct sock *sk)
+{
+	hash_sock_destruct_common(sk);
+	hash_release_parent_nokey(sk);
+}
+
+static int hash_accept_parent_common(void *private, struct sock *sk)
 {
 	struct hash_ctx *ctx;
 	struct alg_sock *ask = alg_sk(sk);
-	unsigned len = sizeof(*ctx) + crypto_ahash_reqsize(private);
-	unsigned ds = crypto_ahash_digestsize(private);
+	struct algif_hash_tfm *tfm = private;
+	struct crypto_ahash *hash = tfm->hash;
+	unsigned len = sizeof(*ctx) + crypto_ahash_reqsize(hash);
+	unsigned ds = crypto_ahash_digestsize(hash);
 
 	ctx = sock_kmalloc(sk, len, GFP_KERNEL);
 	if (!ctx)
@@ -297,7 +456,7 @@ static int hash_accept_parent(void *private, struct sock *sk)
 
 	ask->private = ctx;
 
-	ahash_request_set_tfm(&ctx->req, private);
+	ahash_request_set_tfm(&ctx->req, hash);
 	ahash_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
 				   af_alg_complete, &ctx->completion);
 
@@ -306,12 +465,38 @@ static int hash_accept_parent(void *private, struct sock *sk)
 	return 0;
 }
 
+static int hash_accept_parent(void *private, struct sock *sk)
+{
+	struct algif_hash_tfm *tfm = private;
+
+	if (!tfm->has_key && crypto_ahash_has_setkey(tfm->hash))
+		return -ENOKEY;
+
+	return hash_accept_parent_common(private, sk);
+}
+
+static int hash_accept_parent_nokey(void *private, struct sock *sk)
+{
+	int err;
+
+	err = hash_accept_parent_common(private, sk);
+	if (err)
+		goto out;
+
+	sk->sk_destruct = hash_sock_destruct_nokey;
+
+out:
+	return err;
+}
+
 static const struct af_alg_type algif_type_hash = {
 	.bind		=	hash_bind,
 	.release	=	hash_release,
 	.setkey		=	hash_setkey,
 	.accept		=	hash_accept_parent,
+	.accept_nokey	=	hash_accept_parent_nokey,
 	.ops		=	&algif_hash_ops,
+	.ops_nokey	=	&algif_hash_ops_nokey,
 	.name		=	"hash",
 	.owner		=	THIS_MODULE
 };

[toc] | [prev] | [next] | [standalone]


#1344100 — [PATCH 3.16.y-ckt 067/129] intel_scu_ipcutil: underflow in scu_reg_access()

FromLuis Henriques <luis.henriques@canonical.com>
Date2016-02-26 12:00 +0100
Subject[PATCH 3.16.y-ckt 067/129] intel_scu_ipcutil: underflow in scu_reg_access()
Message-ID<r6ohQ-1Wt-11@gated-at.bofh.it>
In reply to#1344036
3.16.7-ckt25 -stable review patch.  If anyone has any objections, please let me know.

---8<------------------------------------------------------------

From: Dan Carpenter <dan.carpenter@oracle.com>

commit b1d353ad3d5835b16724653b33c05124e1b5acf1 upstream.

"count" is controlled by the user and it can be negative.  Let's prevent
that by making it unsigned.  You have to have CAP_SYS_RAWIO to call this
function so the bug is not as serious as it could be.

Fixes: 5369c02d951a ('intel_scu_ipc: Utility driver for intel scu ipc')
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
---
 drivers/platform/x86/intel_scu_ipcutil.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/platform/x86/intel_scu_ipcutil.c b/drivers/platform/x86/intel_scu_ipcutil.c
index 02bc5a6343c3..aa454241489c 100644
--- a/drivers/platform/x86/intel_scu_ipcutil.c
+++ b/drivers/platform/x86/intel_scu_ipcutil.c
@@ -49,7 +49,7 @@ struct scu_ipc_data {
 
 static int scu_reg_access(u32 cmd, struct scu_ipc_data  *data)
 {
-	int count = data->count;
+	unsigned int count = data->count;
 
 	if (count == 0 || count == 3 || count > 4)
 		return -EINVAL;

[toc] | [prev] | [next] | [standalone]


#1344101 — [PATCH 3.16.y-ckt 056/129] cgroup: make sure a parent css isn't offlined before its children

FromLuis Henriques <luis.henriques@canonical.com>
Date2016-02-26 12:00 +0100
Subject[PATCH 3.16.y-ckt 056/129] cgroup: make sure a parent css isn't offlined before its children
Message-ID<r6ohQ-1Wt-9@gated-at.bofh.it>
In reply to#1344036
3.16.7-ckt25 -stable review patch.  If anyone has any objections, please let me know.

---8<------------------------------------------------------------

From: Tejun Heo <tj@kernel.org>

commit aa226ff4a1ce79f229c6b7a4c0a14e17fececd01 upstream.

There are three subsystem callbacks in css shutdown path -
css_offline(), css_released() and css_free().  Except for
css_released(), cgroup core didn't guarantee the order of invocation.
css_offline() or css_free() could be called on a parent css before its
children.  This behavior is unexpected and led to bugs in cpu and
memory controller.

This patch updates offline path so that a parent css is never offlined
before its children.  Each css keeps online_cnt which reaches zero iff
itself and all its children are offline and offline_css() is invoked
only after online_cnt reaches zero.

This fixes the memory controller bug and allows the fix for cpu
controller.

Signed-off-by: Tejun Heo <tj@kernel.org>
Reported-and-tested-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reported-by: Brian Christiansen <brian.o.christiansen@gmail.com>
Link: http://lkml.kernel.org/g/5698A023.9070703@de.ibm.com
Link: http://lkml.kernel.org/g/CAKB58ikDkzc8REt31WBkD99+hxNzjK4+FBmhkgS+NVrC9vjMSg@mail.gmail.com
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
[ luis: backported to 3.16:
  - file rename: cgroup-defs.h -> cgroup.h
  - adjusted context ]
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
---
 include/linux/cgroup.h |  6 ++++++
 kernel/cgroup.c        | 22 +++++++++++++++++-----
 2 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 8a111dd42d7a..c2d312de22f8 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -88,6 +88,12 @@ struct cgroup_subsys_state {
 	 */
 	u64 serial_nr;
 
+	/*
+	 * Incremented by online self and children.  Used to guarantee that
+	 * parents are not offlined before their children.
+	 */
+	atomic_t online_cnt;
+
 	/* percpu_ref killing and RCU release */
 	struct rcu_head rcu_head;
 	struct work_struct destroy_work;
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 58fd665d1217..660a21884771 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -4278,6 +4278,7 @@ static void init_and_link_css(struct cgroup_subsys_state *css,
 	INIT_LIST_HEAD(&css->sibling);
 	INIT_LIST_HEAD(&css->children);
 	css->serial_nr = css_serial_nr_next++;
+	atomic_set(&css->online_cnt, 0);
 
 	if (cgroup_parent(cgrp)) {
 		css->parent = cgroup_css(cgroup_parent(cgrp), ss);
@@ -4300,6 +4301,10 @@ static int online_css(struct cgroup_subsys_state *css)
 	if (!ret) {
 		css->flags |= CSS_ONLINE;
 		rcu_assign_pointer(css->cgroup->subsys[ss->id], css);
+
+		atomic_inc(&css->online_cnt);
+		if (css->parent)
+			atomic_inc(&css->parent->online_cnt);
 	}
 	return ret;
 }
@@ -4524,10 +4529,15 @@ static void css_killed_work_fn(struct work_struct *work)
 		container_of(work, struct cgroup_subsys_state, destroy_work);
 
 	mutex_lock(&cgroup_mutex);
-	offline_css(css);
-	mutex_unlock(&cgroup_mutex);
 
-	css_put(css);
+	do {
+		offline_css(css);
+		css_put(css);
+		/* @css can't go away while we're holding cgroup_mutex */
+		css = css->parent;
+	} while (css && atomic_dec_and_test(&css->online_cnt));
+
+	mutex_unlock(&cgroup_mutex);
 }
 
 /* css kill confirmation processing requires process context, bounce */
@@ -4536,8 +4546,10 @@ static void css_killed_ref_fn(struct percpu_ref *ref)
 	struct cgroup_subsys_state *css =
 		container_of(ref, struct cgroup_subsys_state, refcnt);
 
-	INIT_WORK(&css->destroy_work, css_killed_work_fn);
-	queue_work(cgroup_destroy_wq, &css->destroy_work);
+	if (atomic_dec_and_test(&css->online_cnt)) {
+		INIT_WORK(&css->destroy_work, css_killed_work_fn);
+		queue_work(cgroup_destroy_wq, &css->destroy_work);
+	}
 }
 
 /**

[toc] | [prev] | [next] | [standalone]


#1344102 — [PATCH 3.16.y-ckt 063/129] target: Fix WRITE_SAME/DISCARD conversion to linux 512b sectors

FromLuis Henriques <luis.henriques@canonical.com>
Date2016-02-26 12:00 +0100
Subject[PATCH 3.16.y-ckt 063/129] target: Fix WRITE_SAME/DISCARD conversion to linux 512b sectors
Message-ID<r6ohQ-1Wt-13@gated-at.bofh.it>
In reply to#1344036
3.16.7-ckt25 -stable review patch.  If anyone has any objections, please let me know.

---8<------------------------------------------------------------

From: Mike Christie <mchristi@redhat.com>

commit 8a9ebe717a133ba7bc90b06047f43cc6b8bcb8b3 upstream.

In a couple places we are not converting to/from the Linux
block layer 512 bytes sectors.

1.

The request queue values and what we do are a mismatch of
things:

max_discard_sectors - This is in linux block layer 512 byte
sectors. We are just copying this to max_unmap_lba_count.

discard_granularity - This is in bytes. We are converting it
to Linux block layer 512 byte sectors.

discard_alignment - This is in bytes. We are just copying
this over.

The problem is that the core LIO code exports these values in
spc_emulate_evpd_b0 and we use them to test request arguments
in sbc_execute_unmap, but we never convert to the block size
we export to the initiator. If we are not using 512 byte sectors
then we are exporting the wrong values or are checks are off.
And, for the discard_alignment/bytes case we are just plain messed
up.

2.

blkdev_issue_discard's start and number of sector arguments
are supposed to be in linux block layer 512 byte sectors. We are
currently passing in the values we get from the initiator which
might be based on some other sector size.

There is a similar problem in iblock_execute_write_same where
the bio functions want values in 512 byte sectors but we are
passing in what we got from the initiator.

Signed-off-by: Mike Christie <mchristi@redhat.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
[ luis: backported to 3.16:
  - dropped changes to attribute unmap_zeroes_data as 3.16 doesn't
    support LBPRZ
  - functions rename:
    * fd_execute_unmap -> fd_do_unmap
    * iblock_execute_unmap -> iblock_do_unmap
  - adjusted context ]
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
---
 drivers/target/target_core_device.c  | 43 +++++++++++++++++++++++++++
 drivers/target/target_core_file.c    | 29 ++++++-------------
 drivers/target/target_core_iblock.c  | 56 +++++++++---------------------------
 include/target/target_core_backend.h |  3 ++
 4 files changed, 69 insertions(+), 62 deletions(-)

diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index 5478aca8f4e6..07425b8d606e 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -1577,6 +1577,49 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name)
 	return dev;
 }
 
+/*
+ * Check if the underlying struct block_device request_queue supports
+ * the QUEUE_FLAG_DISCARD bit for UNMAP/WRITE_SAME in SCSI + TRIM
+ * in ATA and we need to set TPE=1
+ */
+bool target_configure_unmap_from_queue(struct se_dev_attrib *attrib,
+				       struct request_queue *q, int block_size)
+{
+	if (!blk_queue_discard(q))
+		return false;
+
+	attrib->max_unmap_lba_count = (q->limits.max_discard_sectors << 9) /
+								block_size;
+	/*
+	 * Currently hardcoded to 1 in Linux/SCSI code..
+	 */
+	attrib->max_unmap_block_desc_count = 1;
+	attrib->unmap_granularity = q->limits.discard_granularity / block_size;
+	attrib->unmap_granularity_alignment = q->limits.discard_alignment /
+								block_size;
+	return true;
+}
+EXPORT_SYMBOL(target_configure_unmap_from_queue);
+
+/*
+ * Convert from blocksize advertised to the initiator to the 512 byte
+ * units unconditionally used by the Linux block layer.
+ */
+sector_t target_to_linux_sector(struct se_device *dev, sector_t lb)
+{
+	switch (dev->dev_attrib.block_size) {
+	case 4096:
+		return lb << 3;
+	case 2048:
+		return lb << 2;
+	case 1024:
+		return lb << 1;
+	default:
+		return lb;
+	}
+}
+EXPORT_SYMBOL(target_to_linux_sector);
+
 int target_configure_device(struct se_device *dev)
 {
 	struct se_hba *hba = dev->se_hba;
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c
index 4568dc549a63..703f885deac1 100644
--- a/drivers/target/target_core_file.c
+++ b/drivers/target/target_core_file.c
@@ -164,25 +164,11 @@ static int fd_configure_device(struct se_device *dev)
 			" block_device blocks: %llu logical_block_size: %d\n",
 			dev_size, div_u64(dev_size, fd_dev->fd_block_size),
 			fd_dev->fd_block_size);
-		/*
-		 * Check if the underlying struct block_device request_queue supports
-		 * the QUEUE_FLAG_DISCARD bit for UNMAP/WRITE_SAME in SCSI + TRIM
-		 * in ATA and we need to set TPE=1
-		 */
-		if (blk_queue_discard(q)) {
-			dev->dev_attrib.max_unmap_lba_count =
-				q->limits.max_discard_sectors;
-			/*
-			 * Currently hardcoded to 1 in Linux/SCSI code..
-			 */
-			dev->dev_attrib.max_unmap_block_desc_count = 1;
-			dev->dev_attrib.unmap_granularity =
-				q->limits.discard_granularity >> 9;
-			dev->dev_attrib.unmap_granularity_alignment =
-				q->limits.discard_alignment;
+
+		if (target_configure_unmap_from_queue(&dev->dev_attrib, q,
+						      fd_dev->fd_block_size))
 			pr_debug("IFILE: BLOCK Discard support available,"
-					" disabled by default\n");
-		}
+				 " disabled by default\n");
 		/*
 		 * Enable write same emulation for IBLOCK and use 0xFFFF as
 		 * the smaller WRITE_SAME(10) only has a two-byte block count.
@@ -601,9 +587,12 @@ fd_do_unmap(struct se_cmd *cmd, void *priv, sector_t lba, sector_t nolb)
 	if (S_ISBLK(inode->i_mode)) {
 		/* The backend is block device, use discard */
 		struct block_device *bdev = inode->i_bdev;
+		struct se_device *dev = cmd->se_dev;
 
-		ret = blkdev_issue_discard(bdev, lba,
-				nolb, GFP_KERNEL, 0);
+		ret = blkdev_issue_discard(bdev,
+					   target_to_linux_sector(dev, lba),
+					   target_to_linux_sector(dev,  nolb),
+					   GFP_KERNEL, 0);
 		if (ret < 0) {
 			pr_warn("FILEIO: blkdev_issue_discard() failed: %d\n",
 				ret);
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
index be27773ab829..91c625ac40d1 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -126,27 +126,11 @@ static int iblock_configure_device(struct se_device *dev)
 	dev->dev_attrib.hw_max_sectors = queue_max_hw_sectors(q);
 	dev->dev_attrib.hw_queue_depth = q->nr_requests;
 
-	/*
-	 * Check if the underlying struct block_device request_queue supports
-	 * the QUEUE_FLAG_DISCARD bit for UNMAP/WRITE_SAME in SCSI + TRIM
-	 * in ATA and we need to set TPE=1
-	 */
-	if (blk_queue_discard(q)) {
-		dev->dev_attrib.max_unmap_lba_count =
-				q->limits.max_discard_sectors;
-
-		/*
-		 * Currently hardcoded to 1 in Linux/SCSI code..
-		 */
-		dev->dev_attrib.max_unmap_block_desc_count = 1;
-		dev->dev_attrib.unmap_granularity =
-				q->limits.discard_granularity >> 9;
-		dev->dev_attrib.unmap_granularity_alignment =
-				q->limits.discard_alignment;
-
+	if (target_configure_unmap_from_queue(&dev->dev_attrib, q,
+					      dev->dev_attrib.hw_block_size))
 		pr_debug("IBLOCK: BLOCK Discard support available,"
-				" disabled by default\n");
-	}
+			 " disabled by default\n");
+
 	/*
 	 * Enable write same emulation for IBLOCK and use 0xFFFF as
 	 * the smaller WRITE_SAME(10) only has a two-byte block count.
@@ -418,9 +402,13 @@ iblock_do_unmap(struct se_cmd *cmd, void *priv,
 		sector_t lba, sector_t nolb)
 {
 	struct block_device *bdev = priv;
+	struct se_device *dev = cmd->se_dev;
 	int ret;
 
-	ret = blkdev_issue_discard(bdev, lba, nolb, GFP_KERNEL, 0);
+	ret = blkdev_issue_discard(bdev,
+				   target_to_linux_sector(dev, lba),
+				   target_to_linux_sector(dev,  nolb),
+				   GFP_KERNEL, 0);
 	if (ret < 0) {
 		pr_err("blkdev_issue_discard() failed: %d\n", ret);
 		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
@@ -460,8 +448,10 @@ iblock_execute_write_same(struct se_cmd *cmd)
 	struct scatterlist *sg;
 	struct bio *bio;
 	struct bio_list list;
-	sector_t block_lba = cmd->t_task_lba;
-	sector_t sectors = sbc_get_write_same_sectors(cmd);
+	struct se_device *dev = cmd->se_dev;
+	sector_t block_lba = target_to_linux_sector(dev, cmd->t_task_lba);
+	sector_t sectors = target_to_linux_sector(dev,
+					sbc_get_write_same_sectors(cmd));
 
 	sg = &cmd->t_data_sg[0];
 
@@ -670,12 +660,12 @@ iblock_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
 		  enum dma_data_direction data_direction)
 {
 	struct se_device *dev = cmd->se_dev;
+	sector_t block_lba = target_to_linux_sector(dev, cmd->t_task_lba);
 	struct iblock_req *ibr;
 	struct bio *bio, *bio_start;
 	struct bio_list list;
 	struct scatterlist *sg;
 	u32 sg_num = sgl_nents;
-	sector_t block_lba;
 	unsigned bio_cnt;
 	int rw = 0;
 	int i;
@@ -701,24 +691,6 @@ iblock_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
 		rw = READ;
 	}
 
-	/*
-	 * Convert the blocksize advertised to the initiator to the 512 byte
-	 * units unconditionally used by the Linux block layer.
-	 */
-	if (dev->dev_attrib.block_size == 4096)
-		block_lba = (cmd->t_task_lba << 3);
-	else if (dev->dev_attrib.block_size == 2048)
-		block_lba = (cmd->t_task_lba << 2);
-	else if (dev->dev_attrib.block_size == 1024)
-		block_lba = (cmd->t_task_lba << 1);
-	else if (dev->dev_attrib.block_size == 512)
-		block_lba = cmd->t_task_lba;
-	else {
-		pr_err("Unsupported SCSI -> BLOCK LBA conversion:"
-				" %u\n", dev->dev_attrib.block_size);
-		return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
-	}
-
 	ibr = kzalloc(sizeof(struct iblock_req), GFP_KERNEL);
 	if (!ibr)
 		goto fail;
diff --git a/include/target/target_core_backend.h b/include/target/target_core_backend.h
index 9adc1bca1178..e006e10e08a9 100644
--- a/include/target/target_core_backend.h
+++ b/include/target/target_core_backend.h
@@ -95,5 +95,8 @@ sense_reason_t	transport_generic_map_mem_to_cmd(struct se_cmd *,
 		struct scatterlist *, u32, struct scatterlist *, u32);
 
 void	array_free(void *array, int n);
+sector_t target_to_linux_sector(struct se_device *dev, sector_t lb);
+bool target_configure_unmap_from_queue(struct se_dev_attrib *attrib,
+				       struct request_queue *q, int block_size);
 
 #endif /* TARGET_CORE_BACKEND_H */

[toc] | [prev] | [next] | [standalone]


#1344103 — [PATCH 3.16.y-ckt 060/129] rfkill: fix rfkill_fop_read wait_event usage

FromLuis Henriques <luis.henriques@canonical.com>
Date2016-02-26 12:00 +0100
Subject[PATCH 3.16.y-ckt 060/129] rfkill: fix rfkill_fop_read wait_event usage
Message-ID<r6ohQ-1Wt-15@gated-at.bofh.it>
In reply to#1344036
3.16.7-ckt25 -stable review patch.  If anyone has any objections, please let me know.

---8<------------------------------------------------------------

From: Johannes Berg <johannes.berg@intel.com>

commit 6736fde9672ff6717ac576e9bba2fd5f3dfec822 upstream.

The code within wait_event_interruptible() is called with
!TASK_RUNNING, so mustn't call any functions that can sleep,
like mutex_lock().

Since we re-check the list_empty() in a loop after the wait,
it's safe to simply use list_empty() without locking.

This bug has existed forever, but was only discovered now
because all userspace implementations, including the default
'rfkill' tool, use poll() or select() to get a readable fd
before attempting to read.

Fixes: c64fb01627e24 ("rfkill: create useful userspace interface")
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
---
 net/rfkill/core.c | 16 ++++------------
 1 file changed, 4 insertions(+), 12 deletions(-)

diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index 5307a99c1838..24f2d9d2bd31 100644
--- a/net/rfkill/core.c
+++ b/net/rfkill/core.c
@@ -1081,17 +1081,6 @@ static unsigned int rfkill_fop_poll(struct file *file, poll_table *wait)
 	return res;
 }
 
-static bool rfkill_readable(struct rfkill_data *data)
-{
-	bool r;
-
-	mutex_lock(&data->mtx);
-	r = !list_empty(&data->events);
-	mutex_unlock(&data->mtx);
-
-	return r;
-}
-
 static ssize_t rfkill_fop_read(struct file *file, char __user *buf,
 			       size_t count, loff_t *pos)
 {
@@ -1108,8 +1097,11 @@ static ssize_t rfkill_fop_read(struct file *file, char __user *buf,
 			goto out;
 		}
 		mutex_unlock(&data->mtx);
+		/* since we re-check and it just compares pointers,
+		 * using !list_empty() without locking isn't a problem
+		 */
 		ret = wait_event_interruptible(data->read_wait,
-					       rfkill_readable(data));
+					       !list_empty(&data->events));
 		mutex_lock(&data->mtx);
 
 		if (ret)

[toc] | [prev] | [next] | [standalone]


#1344104 — [PATCH 3.16.y-ckt 044/129] crypto: algif_skcipher - Require setkey before accept(2)

FromLuis Henriques <luis.henriques@canonical.com>
Date2016-02-26 12:00 +0100
Subject[PATCH 3.16.y-ckt 044/129] crypto: algif_skcipher - Require setkey before accept(2)
Message-ID<r6ohQ-1Wt-17@gated-at.bofh.it>
In reply to#1344036
3.16.7-ckt25 -stable review patch.  If anyone has any objections, please let me know.

---8<------------------------------------------------------------

From: Herbert Xu <herbert@gondor.apana.org.au>

commit dd504589577d8e8e70f51f997ad487a4cb6c026f upstream.

Some cipher implementations will crash if you try to use them
without calling setkey first.  This patch adds a check so that
the accept(2) call will fail with -ENOKEY if setkey hasn't been
done on the socket yet.

Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Tested-by: Dmitry Vyukov <dvyukov@google.com>
[bwh: Backported to 3.2: s/crypto_(alloc_|free_)?skcipher/crypto_\1ablkcipher/]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
---
 crypto/algif_skcipher.c | 48 +++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 41 insertions(+), 7 deletions(-)

diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
index bb68c92e68c6..10c1fd04f1ed 100644
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -31,6 +31,11 @@ struct skcipher_sg_list {
 	struct scatterlist sg[0];
 };
 
+struct skcipher_tfm {
+	struct crypto_ablkcipher *skcipher;
+	bool has_key;
+};
+
 struct skcipher_ctx {
 	struct list_head tsgl;
 	struct af_alg_sgl rsgl;
@@ -546,17 +551,41 @@ static struct proto_ops algif_skcipher_ops = {
 
 static void *skcipher_bind(const char *name, u32 type, u32 mask)
 {
-	return crypto_alloc_ablkcipher(name, type, mask);
+	struct skcipher_tfm *tfm;
+	struct crypto_ablkcipher *skcipher;
+
+	tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
+	if (!tfm)
+		return ERR_PTR(-ENOMEM);
+
+	skcipher = crypto_alloc_ablkcipher(name, type, mask);
+	if (IS_ERR(skcipher)) {
+		kfree(tfm);
+		return ERR_CAST(skcipher);
+	}
+
+	tfm->skcipher = skcipher;
+
+	return tfm;
 }
 
 static void skcipher_release(void *private)
 {
-	crypto_free_ablkcipher(private);
+	struct skcipher_tfm *tfm = private;
+
+	crypto_free_ablkcipher(tfm->skcipher);
+	kfree(tfm);
 }
 
 static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen)
 {
-	return crypto_ablkcipher_setkey(private, key, keylen);
+	struct skcipher_tfm *tfm = private;
+	int err;
+
+	err = crypto_ablkcipher_setkey(tfm->skcipher, key, keylen);
+	tfm->has_key = !err;
+
+	return err;
 }
 
 static void skcipher_sock_destruct(struct sock *sk)
@@ -575,20 +604,25 @@ static int skcipher_accept_parent(void *private, struct sock *sk)
 {
 	struct skcipher_ctx *ctx;
 	struct alg_sock *ask = alg_sk(sk);
-	unsigned int len = sizeof(*ctx) + crypto_ablkcipher_reqsize(private);
+	struct skcipher_tfm *tfm = private;
+	struct crypto_ablkcipher *skcipher = tfm->skcipher;
+	unsigned int len = sizeof(*ctx) + crypto_ablkcipher_reqsize(skcipher);
+
+	if (!tfm->has_key)
+		return -ENOKEY;
 
 	ctx = sock_kmalloc(sk, len, GFP_KERNEL);
 	if (!ctx)
 		return -ENOMEM;
 
-	ctx->iv = sock_kmalloc(sk, crypto_ablkcipher_ivsize(private),
+	ctx->iv = sock_kmalloc(sk, crypto_ablkcipher_ivsize(skcipher),
 			       GFP_KERNEL);
 	if (!ctx->iv) {
 		sock_kfree_s(sk, ctx, len);
 		return -ENOMEM;
 	}
 
-	memset(ctx->iv, 0, crypto_ablkcipher_ivsize(private));
+	memset(ctx->iv, 0, crypto_ablkcipher_ivsize(skcipher));
 
 	INIT_LIST_HEAD(&ctx->tsgl);
 	ctx->len = len;
@@ -600,7 +634,7 @@ static int skcipher_accept_parent(void *private, struct sock *sk)
 
 	ask->private = ctx;
 
-	ablkcipher_request_set_tfm(&ctx->req, private);
+	ablkcipher_request_set_tfm(&ctx->req, skcipher);
 	ablkcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
 					af_alg_complete, &ctx->completion);
 

[toc] | [prev] | [next] | [standalone]


#1344106 — [PATCH 3.16.y-ckt 053/129] iio: add HAS_IOMEM dependency to VF610_ADC

FromLuis Henriques <luis.henriques@canonical.com>
Date2016-02-26 12:00 +0100
Subject[PATCH 3.16.y-ckt 053/129] iio: add HAS_IOMEM dependency to VF610_ADC
Message-ID<r6ohQ-1Wt-21@gated-at.bofh.it>
In reply to#1344036
3.16.7-ckt25 -stable review patch.  If anyone has any objections, please let me know.

---8<------------------------------------------------------------

From: Vegard Nossum <vegard.nossum@oracle.com>

commit 005ce0713006a76d2b0c924ce0e2629e5d8510c3 upstream.

Ran into this on UML:

drivers/built-in.o: In function `vf610_adc_probe':
drivers/iio/adc/vf610_adc.c:744: undefined reference to `devm_ioremap_resource'

devm_ioremap_resource() is defined only when HAS_IOMEM is selected.

Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
[ luis: backported to 3.16: adjusted context ]
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
---
 drivers/iio/adc/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index a80d23628f14..70969a875317 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -233,6 +233,7 @@ config TWL6030_GPADC
 config VF610_ADC
 	tristate "Freescale vf610 ADC driver"
 	depends on OF
+	depends on HAS_IOMEM
 	help
 	  Say yes here to support for Vybrid board analog-to-digital converter.
 	  Since the IP is used for i.MX6SLX, the driver also support i.MX6SLX.

[toc] | [prev] | [next] | [standalone]


#1344107 — [PATCH 3.16.y-ckt 043/129] umount: Do not allow unmounting rootfs.

FromLuis Henriques <luis.henriques@canonical.com>
Date2016-02-26 12:00 +0100
Subject[PATCH 3.16.y-ckt 043/129] umount: Do not allow unmounting rootfs.
Message-ID<r6ohR-1Wt-27@gated-at.bofh.it>
In reply to#1344036
3.16.7-ckt25 -stable review patch.  If anyone has any objections, please let me know.

---8<------------------------------------------------------------

From: "Eric W. Biederman" <ebiederm@xmission.com>

commit da362b09e42ee0bcaf0356afee6078b4f324baff upstream.

Andrew Vagin <avagin@parallels.com> writes:

> #define _GNU_SOURCE
> #include <sys/types.h>
> #include <sys/stat.h>
> #include <fcntl.h>
> #include <sched.h>
> #include <unistd.h>
> #include <sys/mount.h>
>
> int main(int argc, char **argv)
> {
> 	int fd;
>
> 	fd = open("/proc/self/ns/mnt", O_RDONLY);
> 	if (fd < 0)
> 	   return 1;
> 	   while (1) {
> 	   	 if (umount2("/", MNT_DETACH) ||
> 		        setns(fd, CLONE_NEWNS))
> 					break;
> 					}
>
> 					return 0;
> }
>
> root@ubuntu:/home/avagin# gcc -Wall nsenter.c -o nsenter
> root@ubuntu:/home/avagin# strace ./nsenter
> execve("./nsenter", ["./nsenter"], [/* 22 vars */]) = 0
> ...
> open("/proc/self/ns/mnt", O_RDONLY)     = 3
> umount("/", MNT_DETACH)                 = 0
> setns(3, 131072)                        = 0
> umount("/", MNT_DETACH
>
causes:

> [  260.548301] ------------[ cut here ]------------
> [  260.550941] kernel BUG at /build/buildd/linux-3.13.0/fs/pnode.c:372!
> [  260.552068] invalid opcode: 0000 [#1] SMP
> [  260.552068] Modules linked in: xt_CHECKSUM iptable_mangle xt_tcpudp xt_addrtype xt_conntrack ipt_MASQUERADE iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack bridge stp llc dm_thin_pool dm_persistent_data dm_bufio dm_bio_prison iptable_filter ip_tables x_tables crct10dif_pclmul crc32_pclmul ghash_clmulni_intel binfmt_misc nfsd auth_rpcgss nfs_acl aesni_intel nfs lockd aes_x86_64 sunrpc fscache lrw gf128mul glue_helper ablk_helper cryptd serio_raw ppdev parport_pc lp parport btrfs xor raid6_pq libcrc32c psmouse floppy
> [  260.552068] CPU: 0 PID: 1723 Comm: nsenter Not tainted 3.13.0-30-generic #55-Ubuntu
> [  260.552068] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
> [  260.552068] task: ffff8800376097f0 ti: ffff880074824000 task.ti: ffff880074824000
> [  260.552068] RIP: 0010:[<ffffffff811e9483>]  [<ffffffff811e9483>] propagate_umount+0x123/0x130
> [  260.552068] RSP: 0018:ffff880074825e98  EFLAGS: 00010246
> [  260.552068] RAX: ffff88007c741140 RBX: 0000000000000002 RCX: ffff88007c741190
> [  260.552068] RDX: ffff88007c741190 RSI: ffff880074825ec0 RDI: ffff880074825ec0
> [  260.552068] RBP: ffff880074825eb0 R08: 00000000000172e0 R09: ffff88007fc172e0
> [  260.552068] R10: ffffffff811cc642 R11: ffffea0001d59000 R12: ffff88007c741140
> [  260.552068] R13: ffff88007c741140 R14: ffff88007c741140 R15: 0000000000000000
> [  260.552068] FS:  00007fd5c7e41740(0000) GS:ffff88007fc00000(0000) knlGS:0000000000000000
> [  260.552068] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [  260.552068] CR2: 00007fd5c7968050 CR3: 0000000070124000 CR4: 00000000000406f0
> [  260.552068] Stack:
> [  260.552068]  0000000000000002 0000000000000002 ffff88007c631000 ffff880074825ed8
> [  260.552068]  ffffffff811dcfac ffff88007c741140 0000000000000002 ffff88007c741160
> [  260.552068]  ffff880074825f38 ffffffff811dd12b ffffffff811cc642 0000000075640000
> [  260.552068] Call Trace:
> [  260.552068]  [<ffffffff811dcfac>] umount_tree+0x20c/0x260
> [  260.552068]  [<ffffffff811dd12b>] do_umount+0x12b/0x300
> [  260.552068]  [<ffffffff811cc642>] ? final_putname+0x22/0x50
> [  260.552068]  [<ffffffff811cc849>] ? putname+0x29/0x40
> [  260.552068]  [<ffffffff811dd88c>] SyS_umount+0xdc/0x100
> [  260.552068]  [<ffffffff8172aeff>] tracesys+0xe1/0xe6
> [  260.552068] Code: 89 50 08 48 8b 50 08 48 89 02 49 89 45 08 e9 72 ff ff ff 0f 1f 44 00 00 4c 89 e6 4c 89 e7 e8 f5 f6 ff ff 48 89 c3 e9 39 ff ff ff <0f> 0b 66 2e 0f 1f 84 00 00 00 00 00 90 66 66 66 66 90 55 b8 01
> [  260.552068] RIP  [<ffffffff811e9483>] propagate_umount+0x123/0x130
> [  260.552068]  RSP <ffff880074825e98>
> [  260.611451] ---[ end trace 11c33d85f1d4c652 ]--

Which in practice is totally uninteresting.  Only the global root user can
do it, and it is just a stupid thing to do.

However that is no excuse to allow a silly way to oops the kernel.

We can avoid this silly problem by setting MNT_LOCKED on the rootfs
mount point and thus avoid needing any special cases in the unmount
code.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Joseph Salisbury <joseph.salisbury@canonical.com>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
---
 fs/namespace.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/namespace.c b/fs/namespace.c
index b50d8daa7cb0..506a9921ea46 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2921,6 +2921,7 @@ static void __init init_mount_tree(void)
 
 	root.mnt = mnt;
 	root.dentry = mnt->mnt_root;
+	mnt->mnt_flags |= MNT_LOCKED;
 
 	set_fs_pwd(current->fs, &root);
 	set_fs_root(current->fs, &root);

[toc] | [prev] | [next] | [standalone]


#1344108 — [PATCH 3.16.y-ckt 055/129] ASoC: rt5645: fix the shift bit of IN1 boost

FromLuis Henriques <luis.henriques@canonical.com>
Date2016-02-26 12:00 +0100
Subject[PATCH 3.16.y-ckt 055/129] ASoC: rt5645: fix the shift bit of IN1 boost
Message-ID<r6ohR-1Wt-29@gated-at.bofh.it>
In reply to#1344036
3.16.7-ckt25 -stable review patch.  If anyone has any objections, please let me know.

---8<------------------------------------------------------------

From: Bard Liao <bardliao@realtek.com>

commit b28785fa9cede0d4f47310ca0dd2a4e1d50478b5 upstream.

The shift bit of IN1 boost gain control is 12.

Signed-off-by: Bard Liao <bardliao@realtek.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
---
 sound/soc/codecs/rt5645.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c
index 02147be2b302..c418699c0933 100644
--- a/sound/soc/codecs/rt5645.c
+++ b/sound/soc/codecs/rt5645.c
@@ -471,7 +471,7 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = {
 
 	/* IN1/IN2 Control */
 	SOC_SINGLE_TLV("IN1 Boost", RT5645_IN1_CTRL1,
-		RT5645_BST_SFT1, 8, 0, bst_tlv),
+		RT5645_BST_SFT1, 12, 0, bst_tlv),
 	SOC_SINGLE_TLV("IN2 Boost", RT5645_IN2_CTRL,
 		RT5645_BST_SFT2, 8, 0, bst_tlv),
 

[toc] | [prev] | [next] | [standalone]


#1344109 — [PATCH 3.16.y-ckt 048/129] crypto: algif_skcipher - Add key check exception for cipher_null

FromLuis Henriques <luis.henriques@canonical.com>
Date2016-02-26 12:00 +0100
Subject[PATCH 3.16.y-ckt 048/129] crypto: algif_skcipher - Add key check exception for cipher_null
Message-ID<r6ohR-1Wt-31@gated-at.bofh.it>
In reply to#1344036
3.16.7-ckt25 -stable review patch.  If anyone has any objections, please let me know.

---8<------------------------------------------------------------

From: Herbert Xu <herbert@gondor.apana.org.au>

commit 6e8d8ecf438792ecf7a3207488fb4eebc4edb040 upstream.

This patch adds an exception to the key check so that cipher_null
users may continue to use algif_skcipher without setting a key.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
[bwh: Backported to 3.2: use crypto_ablkcipher_has_setkey()]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
---
 crypto/algif_skcipher.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
index f0037c0c36b7..584d70f7f824 100644
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -760,7 +760,7 @@ static int skcipher_accept_parent(void *private, struct sock *sk)
 {
 	struct skcipher_tfm *tfm = private;
 
-	if (!tfm->has_key)
+	if (!tfm->has_key && crypto_ablkcipher_has_setkey(tfm->skcipher))
 		return -ENOKEY;
 
 	return skcipher_accept_parent_common(private, sk);

[toc] | [prev] | [next] | [standalone]


#1344112 — [PATCH 3.16.y-ckt 054/129] iio: dac: mcp4725: set iio name property in sysfs

FromLuis Henriques <luis.henriques@canonical.com>
Date2016-02-26 12:00 +0100
Subject[PATCH 3.16.y-ckt 054/129] iio: dac: mcp4725: set iio name property in sysfs
Message-ID<r6ohR-1Wt-39@gated-at.bofh.it>
In reply to#1344036
3.16.7-ckt25 -stable review patch.  If anyone has any objections, please let me know.

---8<------------------------------------------------------------

From: Yong Li <sdliyong@gmail.com>

commit 97a249e98a72d6b79fb7350a8dd56b147e9d5bdb upstream.

Without this change, the name entity for mcp4725 is missing in
/sys/bus/iio/devices/iio\:device*/name

With this change, name is reported correctly

Signed-off-by: Yong Li <sdliyong@gmail.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
---
 drivers/iio/dac/mcp4725.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iio/dac/mcp4725.c b/drivers/iio/dac/mcp4725.c
index 43d14588448d..b4dde8315210 100644
--- a/drivers/iio/dac/mcp4725.c
+++ b/drivers/iio/dac/mcp4725.c
@@ -300,6 +300,7 @@ static int mcp4725_probe(struct i2c_client *client,
 	data->client = client;
 
 	indio_dev->dev.parent = &client->dev;
+	indio_dev->name = id->name;
 	indio_dev->info = &mcp4725_info;
 	indio_dev->channels = &mcp4725_channel;
 	indio_dev->num_channels = 1;

[toc] | [prev] | [next] | [standalone]


#1344113 — [PATCH 3.16.y-ckt 051/129] crypto: algif_hash - Fix race condition in hash_check_key

FromLuis Henriques <luis.henriques@canonical.com>
Date2016-02-26 12:00 +0100
Subject[PATCH 3.16.y-ckt 051/129] crypto: algif_hash - Fix race condition in hash_check_key
Message-ID<r6ohR-1Wt-43@gated-at.bofh.it>
In reply to#1344036
3.16.7-ckt25 -stable review patch.  If anyone has any objections, please let me know.

---8<------------------------------------------------------------

From: Herbert Xu <herbert@gondor.apana.org.au>

commit ad46d7e33219218605ea619e32553daf4f346b9f upstream.

We need to lock the child socket in hash_check_key as otherwise
two simultaneous calls can cause the parent socket to be freed.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
---
 crypto/algif_hash.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c
index 287e3fe08428..2dfb0f10e0bb 100644
--- a/crypto/algif_hash.c
+++ b/crypto/algif_hash.c
@@ -253,22 +253,23 @@ static struct proto_ops algif_hash_ops = {
 
 static int hash_check_key(struct socket *sock)
 {
-	int err;
+	int err = 0;
 	struct sock *psk;
 	struct alg_sock *pask;
 	struct algif_hash_tfm *tfm;
 	struct sock *sk = sock->sk;
 	struct alg_sock *ask = alg_sk(sk);
 
+	lock_sock(sk);
 	if (ask->refcnt)
-		return 0;
+		goto unlock_child;
 
 	psk = ask->parent;
 	pask = alg_sk(ask->parent);
 	tfm = pask->private;
 
 	err = -ENOKEY;
-	lock_sock(psk);
+	lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
 	if (!tfm->has_key)
 		goto unlock;
 
@@ -282,6 +283,8 @@ static int hash_check_key(struct socket *sock)
 
 unlock:
 	release_sock(psk);
+unlock_child:
+	release_sock(sk);
 
 	return err;
 }

[toc] | [prev] | [next] | [standalone]


#1344114 — [PATCH 3.16.y-ckt 050/129] crypto: algif_skcipher - Remove custom release parent function

FromLuis Henriques <luis.henriques@canonical.com>
Date2016-02-26 12:00 +0100
Subject[PATCH 3.16.y-ckt 050/129] crypto: algif_skcipher - Remove custom release parent function
Message-ID<r6ohR-1Wt-45@gated-at.bofh.it>
In reply to#1344036
3.16.7-ckt25 -stable review patch.  If anyone has any objections, please let me know.

---8<------------------------------------------------------------

From: Herbert Xu <herbert@gondor.apana.org.au>

commit d7b65aee1e7b4c87922b0232eaba56a8a143a4a0 upstream.

This patch removes the custom release parent function as the
generic af_alg_release_parent now works for nokey sockets too.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
---
 crypto/algif_skcipher.c | 43 +++----------------------------------------
 1 file changed, 3 insertions(+), 40 deletions(-)

diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
index 584d70f7f824..de514c5d4503 100644
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -681,7 +681,7 @@ static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen)
 	return err;
 }
 
-static void skcipher_sock_destruct_common(struct sock *sk)
+static void skcipher_sock_destruct(struct sock *sk)
 {
 	struct alg_sock *ask = alg_sk(sk);
 	struct skcipher_ctx *ctx = ask->private;
@@ -690,33 +690,10 @@ static void skcipher_sock_destruct_common(struct sock *sk)
 	skcipher_free_sgl(sk);
 	sock_kfree_s(sk, ctx->iv, crypto_ablkcipher_ivsize(tfm));
 	sock_kfree_s(sk, ctx, ctx->len);
-}
-
-static void skcipher_sock_destruct(struct sock *sk)
-{
-	skcipher_sock_destruct_common(sk);
-	af_alg_release_parent(sk);
-}
-
-static void skcipher_release_parent_nokey(struct sock *sk)
-{
-	struct alg_sock *ask = alg_sk(sk);
-
-	if (!ask->refcnt) {
-		sock_put(ask->parent);
-		return;
-	}
-
 	af_alg_release_parent(sk);
 }
 
-static void skcipher_sock_destruct_nokey(struct sock *sk)
-{
-	skcipher_sock_destruct_common(sk);
-	skcipher_release_parent_nokey(sk);
-}
-
-static int skcipher_accept_parent_common(void *private, struct sock *sk)
+static int skcipher_accept_parent_nokey(void *private, struct sock *sk)
 {
 	struct skcipher_ctx *ctx;
 	struct alg_sock *ask = alg_sk(sk);
@@ -763,21 +740,7 @@ static int skcipher_accept_parent(void *private, struct sock *sk)
 	if (!tfm->has_key && crypto_ablkcipher_has_setkey(tfm->skcipher))
 		return -ENOKEY;
 
-	return skcipher_accept_parent_common(private, sk);
-}
-
-static int skcipher_accept_parent_nokey(void *private, struct sock *sk)
-{
-	int err;
-
-	err = skcipher_accept_parent_common(private, sk);
-	if (err)
-		goto out;
-
-	sk->sk_destruct = skcipher_sock_destruct_nokey;
-
-out:
-	return err;
+	return skcipher_accept_parent_nokey(private, sk);
 }
 
 static const struct af_alg_type algif_type_skcipher = {

[toc] | [prev] | [next] | [standalone]


#1344115 — [PATCH 3.16.y-ckt 061/129] crypto: shash - Fix has_key setting

FromLuis Henriques <luis.henriques@canonical.com>
Date2016-02-26 12:00 +0100
Subject[PATCH 3.16.y-ckt 061/129] crypto: shash - Fix has_key setting
Message-ID<r6ohR-1Wt-49@gated-at.bofh.it>
In reply to#1344036
3.16.7-ckt25 -stable review patch.  If anyone has any objections, please let me know.

---8<------------------------------------------------------------

From: Herbert Xu <herbert@gondor.apana.org.au>

commit 00420a65fa2beb3206090ead86942484df2275f3 upstream.

The has_key logic is wrong for shash algorithms as they always
have a setkey function.  So we should instead be testing against
shash_no_setkey.

Fixes: a5596d633278 ("crypto: hash - Add crypto_ahash_has_setkey")
Reported-by: Stephan Mueller <smueller@chronox.de>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Tested-by: Stephan Mueller <smueller@chronox.de>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
---
 crypto/shash.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/crypto/shash.c b/crypto/shash.c
index aa3e505045e0..03fbcd4a82c4 100644
--- a/crypto/shash.c
+++ b/crypto/shash.c
@@ -354,11 +354,10 @@ int crypto_init_shash_ops_async(struct crypto_tfm *tfm)
 	crt->final = shash_async_final;
 	crt->finup = shash_async_finup;
 	crt->digest = shash_async_digest;
+	crt->setkey = shash_async_setkey;
+
+	crt->has_setkey = alg->setkey != shash_no_setkey;
 
-	if (alg->setkey) {
-		crt->setkey = shash_async_setkey;
-		crt->has_setkey = true;
-	}
 	if (alg->export)
 		crt->export = shash_async_export;
 	if (alg->import)

[toc] | [prev] | [next] | [standalone]


Page 3 of 6 — ← Prev page 1 2 [3] 4 5 6  Next page →

Back to top | Article view | linux.kernel


csiph-web