Changes in 4.9.326 Bluetooth: L2CAP: Fix use-after-free caused by l2cap_chan_put ntfs: fix use-after-free in ntfs_ucsncmp() scsi: ufs: host: Hold reference returned by of_parse_phandle() net: ping6: Fix memleak in ipv6_renew_options(). net: sungem_phy: Add of_node_put() for reference returned by of_get_parent() netfilter: nf_queue: do not allow packet truncation below transport header offset ARM: crypto: comment out gcc warning that breaks clang builds mt7601u: add USB device ID for some versions of XiaoDu WiFi Dongle. ion: Make user_ion_handle_put_nolock() a void function selinux: Minor cleanups proc: Pass file mode to proc_pid_make_inode selinux: Clean up initialization of isec->sclass selinux: Convert isec->lock into a spinlock selinux: fix error initialization in inode_doinit_with_dentry() selinux: fix inode_doinit_with_dentry() LABEL_INVALID error handling include/uapi/linux/swab.h: fix userspace breakage, use __BITS_PER_LONG for swap init/main: Fix double "the" in comment init/main: properly align the multi-line comment init: move stack canary initialization after setup_arch init/main.c: extract early boot entropy from the passed cmdline ACPI: video: Force backlight native for some TongFang devices ACPI: video: Shortening quirk list by identifying Clevo by board_name only random: only call boot_init_stack_canary() once macintosh/adb: fix oob read in do_adb_query() function ALSA: bcd2000: Fix a UAF bug on the error path of probing add barriers to buffer_uptodate and set_buffer_uptodate KVM: SVM: Don't BUG if userspace injects an interrupt with GIF=0 KVM: x86: Mark TSS busy during LTR emulation _after_ all fault checks ALSA: hda/conexant: Add quirk for LENOVO 20149 Notebook model ALSA: hda/cirrus - support for iMac 12,1 model vfs: Check the truncate maximum size in inode_newsize_ok() usbnet: Fix linkwatch use-after-free on disconnect parisc: Fix device names in /proc/iomem drm/nouveau: fix another off-by-one in nvbios_addr bpf: fix overflow in prog accounting fuse: limit nsec md-raid10: fix KASAN warning ia64, processor: fix -Wincompatible-pointer-types in ia64_get_irr() PCI: Add defines for normal and subtractive PCI bridges powerpc/fsl-pci: Fix Class Code of PCIe Root Port powerpc/powernv: Avoid crashing if rng is NULL MIPS: cpuinfo: Fix a warning for CONFIG_CPUMASK_OFFSTACK USB: HCD: Fix URB giveback issue in tasklet function netfilter: nf_tables: fix null deref due to zeroed list head scsi: zfcp: Fix missing auto port scan and thus missing target ports x86/olpc: fix 'logical not is only applied to the left hand side' spmi: trace: fix stack-out-of-bound access in SPMI tracing functions ext4: add EXT4_INODE_HAS_XATTR_SPACE macro in xattr.h ext4: make sure ext4_append() always allocates new block ext4: fix use-after-free in ext4_xattr_set_entry ext4: update s_overhead_clusters in the superblock during an on-line resize ext4: fix extent status tree race in writeback error recovery path ext4: correct max_inline_xattr_value_size computing dm raid: fix address sanitizer warning in raid_status net_sched: cls_route: remove from list when handle is 0 btrfs: reject log replay if there is unsupported RO compat flag tcp: fix over estimation in sk_forced_mem_schedule() scsi: sg: Allow waiting for commands to complete on removed device Revert "net: usb: ax88179_178a needs FLAG_SEND_ZLP" Bluetooth: L2CAP: Fix l2cap_global_chan_by_psm regression nios2: time: Read timer in get_cycles only if initialized net/9p: Initialize the iounit field during fid creation net_sched: cls_route: disallow handle of 0 ALSA: info: Fix llseek return value when using callback rds: add missing barrier to release_refill ata: libata-eh: Add missing command name btrfs: fix lost error handling when looking up extended ref on log replay can: ems_usb: fix clang's -Wunaligned-access warning NFSv4.1: RECLAIM_COMPLETE must handle EACCES SUNRPC: Reinitialise the backchannel request buffers before reuse pinctrl: nomadik: Fix refcount leak in nmk_pinctrl_dt_subnode_to_map pinctrl: qcom: msm8916: Allow CAMSS GP clocks to be muxed vsock: Fix memory leak in vsock_connect() xen/xenbus: fix return type in xenbus_file_read() atm: idt77252: fix use-after-free bugs caused by tst_timer nios2: page fault et.al. are *not* restartable syscalls... nios2: don't leave NULLs in sys_call_table[] nios2: traced syscall does need to check the syscall number nios2: fix syscall restart checks nios2: restarts apply only to the first sigframe we build... nios2: add force_successful_syscall_return() netfilter: nf_tables: really skip inactive sets when allocating name fec: Fix timer capture timing in `fec_ptp_enable_pps()` irqchip/tegra: Fix overflow implicit truncation warnings usb: host: ohci-ppc-of: Fix refcount leak bug gadgetfs: ep_io - wait until IRQ finishes cxl: Fix a memory leak in an error handling path drivers:md:fix a potential use-after-free bug ext4: avoid remove directory when directory is corrupted ext4: avoid resizing to a partial cluster size tty: serial: Fix refcount leak bug in ucc_uart.c vfio: Clear the caps->buf to NULL after free mips: cavium-octeon: Fix missing of_node_put() in octeon2_usb_clocks_start ALSA: core: Add async signal helpers ALSA: timer: Use deferred fasync helper powerpc/64: Init jump labels before parse_early_param() video: fbdev: i740fb: Check the argument of i740_calc_vclk() MIPS: tlbex: Explicitly compare _PAGE_NO_EXEC against 0 Linux 4.9.326 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I3ca17af58cd0c61bd81028c496849592cfd22f0f
		
			
				
	
	
		
			250 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			250 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  *  Misc and compatibility things
 | |
|  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
 | |
|  *
 | |
|  *
 | |
|  *   This program is free software; you can redistribute it and/or modify
 | |
|  *   it under the terms of the GNU General Public License as published by
 | |
|  *   the Free Software Foundation; either version 2 of the License, or
 | |
|  *   (at your option) any later version.
 | |
|  *
 | |
|  *   This program is distributed in the hope that it will be useful,
 | |
|  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|  *   GNU General Public License for more details.
 | |
|  *
 | |
|  *   You should have received a copy of the GNU General Public License
 | |
|  *   along with this program; if not, write to the Free Software
 | |
|  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 | |
|  *
 | |
|  */
 | |
| 
 | |
| #include <linux/init.h>
 | |
| #include <linux/export.h>
 | |
| #include <linux/moduleparam.h>
 | |
| #include <linux/time.h>
 | |
| #include <linux/slab.h>
 | |
| #include <linux/ioport.h>
 | |
| #include <linux/fs.h>
 | |
| #include <sound/core.h>
 | |
| 
 | |
| #ifdef CONFIG_SND_DEBUG
 | |
| 
 | |
| #ifdef CONFIG_SND_DEBUG_VERBOSE
 | |
| #define DEFAULT_DEBUG_LEVEL	2
 | |
| #else
 | |
| #define DEFAULT_DEBUG_LEVEL	1
 | |
| #endif
 | |
| 
 | |
| static int debug = DEFAULT_DEBUG_LEVEL;
 | |
| module_param(debug, int, 0644);
 | |
| MODULE_PARM_DESC(debug, "Debug level (0 = disable)");
 | |
| 
 | |
| #endif /* CONFIG_SND_DEBUG */
 | |
| 
 | |
| void release_and_free_resource(struct resource *res)
 | |
| {
 | |
| 	if (res) {
 | |
| 		release_resource(res);
 | |
| 		kfree(res);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| EXPORT_SYMBOL(release_and_free_resource);
 | |
| 
 | |
| #ifdef CONFIG_SND_VERBOSE_PRINTK
 | |
| /* strip the leading path if the given path is absolute */
 | |
| static const char *sanity_file_name(const char *path)
 | |
| {
 | |
| 	if (*path == '/')
 | |
| 		return strrchr(path, '/') + 1;
 | |
| 	else
 | |
| 		return path;
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #if defined(CONFIG_SND_DEBUG) || defined(CONFIG_SND_VERBOSE_PRINTK)
 | |
| void __snd_printk(unsigned int level, const char *path, int line,
 | |
| 		  const char *format, ...)
 | |
| {
 | |
| 	va_list args;
 | |
| #ifdef CONFIG_SND_VERBOSE_PRINTK
 | |
| 	int kern_level;
 | |
| 	struct va_format vaf;
 | |
| 	char verbose_fmt[] = KERN_DEFAULT "ALSA %s:%d %pV";
 | |
| #endif
 | |
| 
 | |
| #ifdef CONFIG_SND_DEBUG
 | |
| 	if (debug < level)
 | |
| 		return;
 | |
| #endif
 | |
| 
 | |
| 	va_start(args, format);
 | |
| #ifdef CONFIG_SND_VERBOSE_PRINTK
 | |
| 	vaf.fmt = format;
 | |
| 	vaf.va = &args;
 | |
| 
 | |
| 	kern_level = printk_get_level(format);
 | |
| 	if (kern_level) {
 | |
| 		const char *end_of_header = printk_skip_level(format);
 | |
| 		memcpy(verbose_fmt, format, end_of_header - format);
 | |
| 		vaf.fmt = end_of_header;
 | |
| 	} else if (level)
 | |
| 		memcpy(verbose_fmt, KERN_DEBUG, sizeof(KERN_DEBUG) - 1);
 | |
| 	printk(verbose_fmt, sanity_file_name(path), line, &vaf);
 | |
| 
 | |
| #else
 | |
| 	vprintk(format, args);
 | |
| #endif
 | |
| 	va_end(args);
 | |
| }
 | |
| EXPORT_SYMBOL_GPL(__snd_printk);
 | |
| #endif
 | |
| 
 | |
| #ifdef CONFIG_PCI
 | |
| #include <linux/pci.h>
 | |
| /**
 | |
|  * snd_pci_quirk_lookup_id - look up a PCI SSID quirk list
 | |
|  * @vendor: PCI SSV id
 | |
|  * @device: PCI SSD id
 | |
|  * @list: quirk list, terminated by a null entry
 | |
|  *
 | |
|  * Look through the given quirk list and finds a matching entry
 | |
|  * with the same PCI SSID.  When subdevice is 0, all subdevice
 | |
|  * values may match.
 | |
|  *
 | |
|  * Returns the matched entry pointer, or NULL if nothing matched.
 | |
|  */
 | |
| const struct snd_pci_quirk *
 | |
| snd_pci_quirk_lookup_id(u16 vendor, u16 device,
 | |
| 			const struct snd_pci_quirk *list)
 | |
| {
 | |
| 	const struct snd_pci_quirk *q;
 | |
| 
 | |
| 	for (q = list; q->subvendor; q++) {
 | |
| 		if (q->subvendor != vendor)
 | |
| 			continue;
 | |
| 		if (!q->subdevice ||
 | |
| 		    (device & q->subdevice_mask) == q->subdevice)
 | |
| 			return q;
 | |
| 	}
 | |
| 	return NULL;
 | |
| }
 | |
| EXPORT_SYMBOL(snd_pci_quirk_lookup_id);
 | |
| 
 | |
| /**
 | |
|  * snd_pci_quirk_lookup - look up a PCI SSID quirk list
 | |
|  * @pci: pci_dev handle
 | |
|  * @list: quirk list, terminated by a null entry
 | |
|  *
 | |
|  * Look through the given quirk list and finds a matching entry
 | |
|  * with the same PCI SSID.  When subdevice is 0, all subdevice
 | |
|  * values may match.
 | |
|  *
 | |
|  * Returns the matched entry pointer, or NULL if nothing matched.
 | |
|  */
 | |
| const struct snd_pci_quirk *
 | |
| snd_pci_quirk_lookup(struct pci_dev *pci, const struct snd_pci_quirk *list)
 | |
| {
 | |
| 	if (!pci)
 | |
| 		return NULL;
 | |
| 	return snd_pci_quirk_lookup_id(pci->subsystem_vendor,
 | |
| 				       pci->subsystem_device,
 | |
| 				       list);
 | |
| }
 | |
| EXPORT_SYMBOL(snd_pci_quirk_lookup);
 | |
| #endif
 | |
| 
 | |
| /*
 | |
|  * Deferred async signal helpers
 | |
|  *
 | |
|  * Below are a few helper functions to wrap the async signal handling
 | |
|  * in the deferred work.  The main purpose is to avoid the messy deadlock
 | |
|  * around tasklist_lock and co at the kill_fasync() invocation.
 | |
|  * fasync_helper() and kill_fasync() are replaced with snd_fasync_helper()
 | |
|  * and snd_kill_fasync(), respectively.  In addition, snd_fasync_free() has
 | |
|  * to be called at releasing the relevant file object.
 | |
|  */
 | |
| struct snd_fasync {
 | |
| 	struct fasync_struct *fasync;
 | |
| 	int signal;
 | |
| 	int poll;
 | |
| 	int on;
 | |
| 	struct list_head list;
 | |
| };
 | |
| 
 | |
| static DEFINE_SPINLOCK(snd_fasync_lock);
 | |
| static LIST_HEAD(snd_fasync_list);
 | |
| 
 | |
| static void snd_fasync_work_fn(struct work_struct *work)
 | |
| {
 | |
| 	struct snd_fasync *fasync;
 | |
| 
 | |
| 	spin_lock_irq(&snd_fasync_lock);
 | |
| 	while (!list_empty(&snd_fasync_list)) {
 | |
| 		fasync = list_first_entry(&snd_fasync_list, struct snd_fasync, list);
 | |
| 		list_del_init(&fasync->list);
 | |
| 		spin_unlock_irq(&snd_fasync_lock);
 | |
| 		if (fasync->on)
 | |
| 			kill_fasync(&fasync->fasync, fasync->signal, fasync->poll);
 | |
| 		spin_lock_irq(&snd_fasync_lock);
 | |
| 	}
 | |
| 	spin_unlock_irq(&snd_fasync_lock);
 | |
| }
 | |
| 
 | |
| static DECLARE_WORK(snd_fasync_work, snd_fasync_work_fn);
 | |
| 
 | |
| int snd_fasync_helper(int fd, struct file *file, int on,
 | |
| 		      struct snd_fasync **fasyncp)
 | |
| {
 | |
| 	struct snd_fasync *fasync = NULL;
 | |
| 
 | |
| 	if (on) {
 | |
| 		fasync = kzalloc(sizeof(*fasync), GFP_KERNEL);
 | |
| 		if (!fasync)
 | |
| 			return -ENOMEM;
 | |
| 		INIT_LIST_HEAD(&fasync->list);
 | |
| 	}
 | |
| 
 | |
| 	spin_lock_irq(&snd_fasync_lock);
 | |
| 	if (*fasyncp) {
 | |
| 		kfree(fasync);
 | |
| 		fasync = *fasyncp;
 | |
| 	} else {
 | |
| 		if (!fasync) {
 | |
| 			spin_unlock_irq(&snd_fasync_lock);
 | |
| 			return 0;
 | |
| 		}
 | |
| 		*fasyncp = fasync;
 | |
| 	}
 | |
| 	fasync->on = on;
 | |
| 	spin_unlock_irq(&snd_fasync_lock);
 | |
| 	return fasync_helper(fd, file, on, &fasync->fasync);
 | |
| }
 | |
| EXPORT_SYMBOL_GPL(snd_fasync_helper);
 | |
| 
 | |
| void snd_kill_fasync(struct snd_fasync *fasync, int signal, int poll)
 | |
| {
 | |
| 	unsigned long flags;
 | |
| 
 | |
| 	if (!fasync || !fasync->on)
 | |
| 		return;
 | |
| 	spin_lock_irqsave(&snd_fasync_lock, flags);
 | |
| 	fasync->signal = signal;
 | |
| 	fasync->poll = poll;
 | |
| 	list_move(&fasync->list, &snd_fasync_list);
 | |
| 	schedule_work(&snd_fasync_work);
 | |
| 	spin_unlock_irqrestore(&snd_fasync_lock, flags);
 | |
| }
 | |
| EXPORT_SYMBOL_GPL(snd_kill_fasync);
 | |
| 
 | |
| void snd_fasync_free(struct snd_fasync *fasync)
 | |
| {
 | |
| 	if (!fasync)
 | |
| 		return;
 | |
| 	fasync->on = 0;
 | |
| 	flush_work(&snd_fasync_work);
 | |
| 	kfree(fasync);
 | |
| }
 | |
| EXPORT_SYMBOL_GPL(snd_fasync_free);
 |