This is the start of the stable review cycle for the 4.4.221 release. There are 70 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 03 May 2020 13:12:02 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.4.221-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.4.y and the diffstat can be found below.
thanks,
greg k-h
------------- Pseudo-Shortlog of commits:
Greg Kroah-Hartman gregkh@linuxfoundation.org Linux 4.4.221-rc1
Colin Ian King colin.king@canonical.com ext4: unsigned int compared against zero
Theodore Ts'o tytso@mit.edu ext4: fix block validity checks for journal inodes using indirect blocks
Theodore Ts'o tytso@mit.edu ext4: don't perform block validity checks on the journal inode
Theodore Ts'o tytso@mit.edu ext4: protect journal inode's blocks using block_validity
Theodore Ts'o tytso@mit.edu ext4: avoid declaring fs inconsistent due to invalid file handles
Frank Rowand frank.rowand@sony.com of: unittest: kmemleak on changeset destroy
Theodore Ts'o tytso@mit.edu ext4: convert BUG_ON's to WARN_ON's in mballoc.c
Juergen Gross jgross@suse.com xen/xenbus: ensure xenbus_map_ring_valloc() returns proper grant status
Bodo Stroesser bstroesser@ts.fujitsu.com scsi: target: fix PR IN / READ FULL STATUS for FC
Luke Nelson lukenels@cs.washington.edu bpf, x86: Fix encoding for lower 8-bit registers in BPF_STX BPF_B
Ian Rogers irogers@google.com perf/core: fix parent pid/tid in task exit events
Jason Gunthorpe jgg@mellanox.com net/cxgb4: Check the return from t4_query_params properly
Nathan Chancellor natechancellor@gmail.com usb: gadget: udc: bdc: Remove unnecessary NULL checks in bdc_req_complete
Liu Jian liujian56@huawei.com mtd: cfi: fix deadloop in cfi_cmdset_0002.c do_write_buffer
Miklos Szeredi mszeredi@redhat.com fuse: fix possibly missed wake-up after abort
Xin Long lucien.xin@gmail.com sctp: use right member as the param of list_for_each_entry
Clement Leger cleger@kalray.eu remoteproc: Fix wrong rvring index computation
Udipto Goswami ugoswami@codeaurora.org usb: f_fs: Clear OS Extended descriptor counts to zero in ffs_data_reset()
Oliver Neukum oneukum@suse.com UAS: fix deadlock in error handling and PM flushing work
Oliver Neukum oneukum@suse.com UAS: no use logging any details in case of ENODEV
Malcolm Priestley tvboxspy@gmail.com staging: vt6656: Power save stop wake_up_count wrap around.
Malcolm Priestley tvboxspy@gmail.com staging: vt6656: Fix drivers TBTT timing counter.
Xiyu Yang xiyuyang19@fudan.edu.cn staging: comedi: Fix comedi_device refcnt leak in comedi_open
Ian Abbott abbotti@mev.co.uk staging: comedi: dt2815: fix writing hi byte of analog output
Ahmad Fatoum a.fatoum@pengutronix.de ARM: imx: provide v7_cpu_resume() only on ARM_CPU_SUSPEND=y
Gyeongtaek Lee gt82.lee@samsung.com ASoC: dapm: fixup dapm kcontrol widget
Paul Moore paul@paul-moore.com audit: check the length of userspace generated audit records
Alan Stern stern@rowland.harvard.edu usb-storage: Add unusual_devs entry for JMicron JMS566
Jiri Slaby jslaby@suse.cz tty: rocket, avoid OOB access
Andrew Melnychenko andrew@daynix.com tty: hvc: fix buffer overflow during hvc_alloc().
Uros Bizjak ubizjak@gmail.com KVM: VMX: Enable machine check support for 32bit targets
Sean Christopherson sean.j.christopherson@intel.com KVM: Check validity of resolved slot when searching memslots
Alexander Tsoy alexander@tsoy.me ALSA: usb-audio: Filter out unsupported sample rates on Focusrite devices
Xiyu Yang xiyuyang19@fudan.edu.cn ALSA: usb-audio: Fix usb audio refcnt leak when getting spdif
Takashi Iwai tiwai@suse.de ALSA: usx2y: Fix potential NULL dereference
Alan Stern stern@rowland.harvard.edu USB: hub: Fix handling of connect changes during sleep
Alan Stern stern@rowland.harvard.edu USB: core: Fix free-while-in-use bug in the USB S-Glibrary
David Mosberger davidm@egauge.net drivers: usb: core: Minimize irq disabling in usb_sg_cancel()
David Mosberger davidm@egauge.net drivers: usb: core: Don't disable irqs in usb_sg_wait() during URB submit.
Jonathan Cox jonathan@jdcox.net USB: Add USB_QUIRK_DELAY_CTRL_MSG and USB_QUIRK_DELAY_INIT for Corsair K70 RGB RAPIDFIRE
Changming Liu liu.changm@northeastern.edu USB: sisusbvga: Change port variable from signed to unsigned
Piotr Krysiuk piotras@gmail.com fs/namespace.c: fix mountpoint reference counter race
Lars-Peter Clausen lars@metafoo.de iio: xilinx-xadc: Fix sequencer configuration for aux channels in simultaneous mode
Lars-Peter Clausen lars@metafoo.de iio: xilinx-xadc: Fix clearing interrupt when enabling trigger
Lars-Peter Clausen lars@metafoo.de iio: xilinx-xadc: Fix ADC-B powerdown
Takashi Iwai tiwai@suse.de ALSA: hda: Remove ASUS ROG Zenith from the blacklist
David Ahern dsahern@gmail.com xfrm: Always set XFRM_TRANSFORMED in xfrm{4,6}_output_finish
Taehee Yoo ap420073@gmail.com team: fix hang in team_mode_get()
Eric Dumazet edumazet@google.com tcp: cache line align MAX_TCP_HEADER
Xiyu Yang xiyuyang19@fudan.edu.cn net/x25: Fix x25_neigh refcnt leak when receiving frame
Xiyu Yang xiyuyang19@fudan.edu.cn net: netrom: Fix potential nr_neigh refcnt leak in nr_add_node
Taehee Yoo ap420073@gmail.com macvlan: fix null dereference in macvlan_device_event()
John Haxby john.haxby@oracle.com ipv6: fix restrict IPV6_ADDRFORM operation
Florian Fainelli f.fainelli@gmail.com pwm: bcm2835: Dynamically allocate base
Geert Uytterhoeven geert+renesas@glider.be pwm: renesas-tpu: Fix late Runtime PM enablement
Cornelia Huck cohuck@redhat.com s390/cio: avoid duplicated 'ADD' uevents
Vasily Averin vvs@virtuozzo.com ipc/util.c: sysvipc_find_ipc() should increase position index
Vasily Averin vvs@virtuozzo.com kernel/gcov/fs.c: gcov_seq_next() should increase position index
Hans de Goede hdegoede@redhat.com ASoC: Intel: atom: Take the drv->lock mutex before calling sst_send_slot_map()
Wu Bo wubo40@huawei.com scsi: iscsi: Report unbind session event when the target has been removed
Geert Uytterhoeven geert+renesas@glider.be pwm: rcar: Fix late Runtime PM enablement
Yan, Zheng zyan@redhat.com ceph: don't skip updating wanted caps when cap is stale
Qiujun Huang hqjagain@gmail.com ceph: return ceph_mdsc_do_request() errors from __get_parent()
James Smart jsmart2021@gmail.com scsi: lpfc: Fix kasan slab-out-of-bounds error in lpfc_unreg_login
Jeremy Sowden jeremy@azazel.net vti4: removed duplicate log message.
Wei Yongjun weiyongjun1@huawei.com crypto: mxs-dcp - make symbols 'sha1_null_hash' and 'sha256_null_hash' static
Arnd Bergmann arnd@arndb.de net: ipv4: avoid unused variable warning for sysctl
Nicolai Stange nstange@suse.de net: ipv4: emulate READ_ONCE() on ->hdrincl bit-field in raw_sendmsg()
Takashi Iwai tiwai@suse.de ALSA: hda - Fix incorrect usage of IS_REACHABLE()
Dmitry Monakhov dmonakhov@gmail.com ext4: fix extent_status fragmentation for plain files
-------------
Diffstat:
Makefile | 4 +- arch/arm/mach-imx/Makefile | 2 + arch/x86/kvm/vmx.c | 2 +- arch/x86/net/bpf_jit_comp.c | 18 +++++++-- drivers/crypto/mxs-dcp.c | 4 +- drivers/iio/adc/xilinx-xadc-core.c | 17 +++++++-- drivers/mtd/chips/cfi_cmdset_0002.c | 6 ++- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 2 +- drivers/net/macvlan.c | 2 +- drivers/net/team/team.c | 4 ++ drivers/of/unittest.c | 4 ++ drivers/pwm/pwm-bcm2835.c | 1 + drivers/pwm/pwm-rcar.c | 10 +++-- drivers/pwm/pwm-renesas-tpu.c | 9 ++--- drivers/remoteproc/remoteproc_core.c | 2 +- drivers/s390/cio/device.c | 13 +++++-- drivers/scsi/lpfc/lpfc_sli.c | 2 + drivers/scsi/scsi_transport_iscsi.c | 4 +- drivers/staging/comedi/comedi_fops.c | 4 +- drivers/staging/comedi/drivers/dt2815.c | 3 ++ drivers/staging/vt6656/int.c | 3 +- drivers/staging/vt6656/main_usb.c | 9 +++-- drivers/target/target_core_fabric_lib.c | 2 +- drivers/tty/hvc/hvc_console.c | 23 +++++++----- drivers/tty/rocket.c | 25 +++++++------ drivers/usb/core/hub.c | 14 +++++++ drivers/usb/core/message.c | 53 ++++++++++++++------------- drivers/usb/core/quirks.c | 4 ++ drivers/usb/gadget/function/f_fs.c | 4 ++ drivers/usb/gadget/udc/bdc/bdc_ep.c | 2 +- drivers/usb/misc/sisusbvga/sisusb.c | 20 +++++----- drivers/usb/misc/sisusbvga/sisusb_init.h | 14 +++---- drivers/usb/storage/uas.c | 46 +++++++++++++++++++++-- drivers/usb/storage/unusual_devs.h | 7 ++++ drivers/xen/xenbus/xenbus_client.c | 9 ++++- fs/ceph/caps.c | 8 +++- fs/ceph/export.c | 5 +++ fs/ext4/block_validity.c | 54 +++++++++++++++++++++++++++ fs/ext4/ext4.h | 15 +++++++- fs/ext4/extents.c | 59 ++++++++++++++++++------------ fs/ext4/ialloc.c | 2 +- fs/ext4/inode.c | 48 +++++++++++++++++------- fs/ext4/ioctl.c | 2 +- fs/ext4/mballoc.c | 6 ++- fs/ext4/namei.c | 4 +- fs/ext4/resize.c | 5 ++- fs/ext4/super.c | 28 +++++--------- fs/fuse/dev.c | 12 ++++-- fs/namespace.c | 2 +- include/linux/kvm_host.h | 2 +- include/net/tcp.h | 2 +- ipc/util.c | 2 +- kernel/audit.c | 3 ++ kernel/events/core.c | 13 +++++-- kernel/gcov/fs.c | 2 +- net/ipv4/ip_vti.c | 4 +- net/ipv4/raw.c | 4 +- net/ipv4/route.c | 3 +- net/ipv4/xfrm4_output.c | 2 - net/ipv6/ipv6_sockglue.c | 13 +++---- net/ipv6/xfrm6_output.c | 2 - net/netrom/nr_route.c | 1 + net/sctp/socket.c | 6 +-- net/x25/x25_dev.c | 4 +- sound/pci/hda/hda_intel.c | 1 - sound/pci/hda/patch_realtek.c | 2 +- sound/soc/intel/atom/sst-atom-controls.c | 2 + sound/soc/soc-dapm.c | 20 ++++++++-- sound/usb/format.c | 52 ++++++++++++++++++++++++++ sound/usb/mixer_quirks.c | 12 ++++-- sound/usb/usx2y/usbusx2yaudio.c | 2 + 71 files changed, 543 insertions(+), 209 deletions(-)
From: Dmitry Monakhov dmonakhov@gmail.com
commit 4068664e3cd2312610ceac05b74c4cf1853b8325 upstream.
Extents are cached in read_extent_tree_block(); as a result, extents are not cached for inodes with depth == 0 when we try to find the extent using ext4_find_extent(). The result of the lookup is cached in ext4_map_blocks() but is only a subset of the extent on disk. As a result, the contents of extents status cache can get very badly fragmented for certain workloads, such as a random 4k read workload.
File size of /mnt/test is 33554432 (8192 blocks of 4096 bytes) ext: logical_offset: physical_offset: length: expected: flags: 0: 0.. 8191: 40960.. 49151: 8192: last,eof
$ perf record -e 'ext4:ext4_es_*' /root/bin/fio --name=t --direct=0 --rw=randread --bs=4k --filesize=32M --size=32M --filename=/mnt/test $ perf script | grep ext4_es_insert_extent | head -n 10 fio 131 [000] 13.975421: ext4:ext4_es_insert_extent: dev 253,0 ino 12 es [494/1) mapped 41454 status W fio 131 [000] 13.975939: ext4:ext4_es_insert_extent: dev 253,0 ino 12 es [6064/1) mapped 47024 status W fio 131 [000] 13.976467: ext4:ext4_es_insert_extent: dev 253,0 ino 12 es [6907/1) mapped 47867 status W fio 131 [000] 13.976937: ext4:ext4_es_insert_extent: dev 253,0 ino 12 es [3850/1) mapped 44810 status W fio 131 [000] 13.977440: ext4:ext4_es_insert_extent: dev 253,0 ino 12 es [3292/1) mapped 44252 status W fio 131 [000] 13.977931: ext4:ext4_es_insert_extent: dev 253,0 ino 12 es [6882/1) mapped 47842 status W fio 131 [000] 13.978376: ext4:ext4_es_insert_extent: dev 253,0 ino 12 es [3117/1) mapped 44077 status W fio 131 [000] 13.978957: ext4:ext4_es_insert_extent: dev 253,0 ino 12 es [2896/1) mapped 43856 status W fio 131 [000] 13.979474: ext4:ext4_es_insert_extent: dev 253,0 ino 12 es [7479/1) mapped 48439 status W
Fix this by caching the extents for inodes with depth == 0 in ext4_find_extent().
[ Renamed ext4_es_cache_extents() to ext4_cache_extents() since this newly added function is not in extents_cache.c, and to avoid potential visual confusion with ext4_es_cache_extent(). -TYT ]
Signed-off-by: Dmitry Monakhov dmonakhov@gmail.com Link: https://lore.kernel.org/r/20191106122502.19986-1-dmonakhov@gmail.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/extents.c | 47 +++++++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 20 deletions(-)
--- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -505,6 +505,30 @@ int ext4_ext_check_inode(struct inode *i return ext4_ext_check(inode, ext_inode_hdr(inode), ext_depth(inode), 0); }
+static void ext4_cache_extents(struct inode *inode, + struct ext4_extent_header *eh) +{ + struct ext4_extent *ex = EXT_FIRST_EXTENT(eh); + ext4_lblk_t prev = 0; + int i; + + for (i = le16_to_cpu(eh->eh_entries); i > 0; i--, ex++) { + unsigned int status = EXTENT_STATUS_WRITTEN; + ext4_lblk_t lblk = le32_to_cpu(ex->ee_block); + int len = ext4_ext_get_actual_len(ex); + + if (prev && (prev != lblk)) + ext4_es_cache_extent(inode, prev, lblk - prev, ~0, + EXTENT_STATUS_HOLE); + + if (ext4_ext_is_unwritten(ex)) + status = EXTENT_STATUS_UNWRITTEN; + ext4_es_cache_extent(inode, lblk, len, + ext4_ext_pblock(ex), status); + prev = lblk + len; + } +} + static struct buffer_head * __read_extent_tree_block(const char *function, unsigned int line, struct inode *inode, ext4_fsblk_t pblk, int depth, @@ -535,26 +559,7 @@ __read_extent_tree_block(const char *fun */ if (!(flags & EXT4_EX_NOCACHE) && depth == 0) { struct ext4_extent_header *eh = ext_block_hdr(bh); - struct ext4_extent *ex = EXT_FIRST_EXTENT(eh); - ext4_lblk_t prev = 0; - int i; - - for (i = le16_to_cpu(eh->eh_entries); i > 0; i--, ex++) { - unsigned int status = EXTENT_STATUS_WRITTEN; - ext4_lblk_t lblk = le32_to_cpu(ex->ee_block); - int len = ext4_ext_get_actual_len(ex); - - if (prev && (prev != lblk)) - ext4_es_cache_extent(inode, prev, - lblk - prev, ~0, - EXTENT_STATUS_HOLE); - - if (ext4_ext_is_unwritten(ex)) - status = EXTENT_STATUS_UNWRITTEN; - ext4_es_cache_extent(inode, lblk, len, - ext4_ext_pblock(ex), status); - prev = lblk + len; - } + ext4_cache_extents(inode, eh); } return bh; errout: @@ -902,6 +907,8 @@ ext4_find_extent(struct inode *inode, ex path[0].p_bh = NULL;
i = depth; + if (!(flags & EXT4_EX_NOCACHE) && depth == 0) + ext4_cache_extents(inode, eh); /* walk through the tree */ while (i) { ext_debug("depth %d: num %d, max %d\n",
From: Takashi Iwai tiwai@suse.de
commit 6a30abaa40b62aed46ef12ea4c16c48565bdb376 upstream.
The commit c469652bb5e8 ("ALSA: hda - Use IS_REACHABLE() for dependency on input") simplified the dependencies with IS_REACHABLE() macro, but it broke due to its incorrect usage: it should have been IS_REACHABLE(CONFIG_INPUT) instead of IS_REACHABLE(INPUT).
Fixes: c469652bb5e8 ("ALSA: hda - Use IS_REACHABLE() for dependency on input") Cc: stable@vger.kernel.org Signed-off-by: Takashi Iwai tiwai@suse.de Cc: Guenter Roeck linux@roeck-us.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/pci/hda/patch_realtek.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3500,7 +3500,7 @@ static void alc280_fixup_hp_gpio4(struct } }
-#if IS_REACHABLE(INPUT) +#if IS_REACHABLE(CONFIG_INPUT) static void gpio2_mic_hotkey_event(struct hda_codec *codec, struct hda_jack_callback *event) {
From: Nicolai Stange nstange@suse.de
commit 20b50d79974ea3192e8c3ab7faf4e536e5f14d8f upstream.
Commit 8f659a03a0ba ("net: ipv4: fix for a race condition in raw_sendmsg") fixed the issue of possibly inconsistent ->hdrincl handling due to concurrent updates by reading this bit-field member into a local variable and using the thus stabilized value in subsequent tests.
However, aforementioned commit also adds the (correct) comment that
/* hdrincl should be READ_ONCE(inet->hdrincl) * but READ_ONCE() doesn't work with bit fields */
because as it stands, the compiler is free to shortcut or even eliminate the local variable at its will.
Note that I have not seen anything like this happening in reality and thus, the concern is a theoretical one.
However, in order to be on the safe side, emulate a READ_ONCE() on the bit-field by doing it on the local 'hdrincl' variable itself:
int hdrincl = inet->hdrincl; hdrincl = READ_ONCE(hdrincl);
This breaks the chain in the sense that the compiler is not allowed to replace subsequent reads from hdrincl with reloads from inet->hdrincl.
Fixes: 8f659a03a0ba ("net: ipv4: fix for a race condition in raw_sendmsg") Signed-off-by: Nicolai Stange nstange@suse.de Reviewed-by: Stefano Brivio sbrivio@redhat.com Signed-off-by: David S. Miller davem@davemloft.net Cc: Guenter Roeck linux@roeck-us.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- net/ipv4/raw.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -507,9 +507,11 @@ static int raw_sendmsg(struct sock *sk, goto out;
/* hdrincl should be READ_ONCE(inet->hdrincl) - * but READ_ONCE() doesn't work with bit fields + * but READ_ONCE() doesn't work with bit fields. + * Doing this indirectly yields the same result. */ hdrincl = inet->hdrincl; + hdrincl = READ_ONCE(hdrincl); /* * Check the flags. */
From: Arnd Bergmann arnd@arndb.de
commit 773daa3caf5d3f87fdb1ab43e9c1b367a38fa394 upstream.
The newly introudced ip_min_valid_pmtu variable is only used when CONFIG_SYSCTL is set:
net/ipv4/route.c:135:12: error: 'ip_min_valid_pmtu' defined but not used [-Werror=unused-variable]
This moves it to the other variables like it, to avoid the harmless warning.
Fixes: c7272c2f1229 ("net: ipv4: don't allow setting net.ipv4.route.min_pmtu below 68") Signed-off-by: Arnd Bergmann arnd@arndb.de Acked-by: Sabrina Dubroca sd@queasysnail.net Signed-off-by: David S. Miller davem@davemloft.net Cc: Guenter Roeck linux@roeck-us.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- net/ipv4/route.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
--- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -131,8 +131,6 @@ static int ip_rt_min_advmss __read_mostl
static int ip_rt_gc_timeout __read_mostly = RT_GC_TIMEOUT;
-static int ip_min_valid_pmtu __read_mostly = IPV4_MIN_MTU; - /* * Interface to generic destination cache. */ @@ -2705,6 +2703,7 @@ void ip_rt_multicast_event(struct in_dev static int ip_rt_gc_interval __read_mostly = 60 * HZ; static int ip_rt_gc_min_interval __read_mostly = HZ / 2; static int ip_rt_gc_elasticity __read_mostly = 8; +static int ip_min_valid_pmtu __read_mostly = IPV4_MIN_MTU;
static int ipv4_sysctl_rtcache_flush(struct ctl_table *__ctl, int write, void __user *buffer,
From: Wei Yongjun weiyongjun1@huawei.com
commit ce4e45842de3eb54b8dd6e081765d741f5b92b56 upstream.
Fixes the following sparse warnings:
drivers/crypto/mxs-dcp.c:39:15: warning: symbol 'sha1_null_hash' was not declared. Should it be static? drivers/crypto/mxs-dcp.c:43:15: warning: symbol 'sha256_null_hash' was not declared. Should it be static?
Fixes: c709eebaf5c5 ("crypto: mxs-dcp - Fix SHA null hashes and output length") Signed-off-by: Wei Yongjun weiyongjun1@huawei.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Cc: Guenter Roeck linux@roeck-us.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/crypto/mxs-dcp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/crypto/mxs-dcp.c +++ b/drivers/crypto/mxs-dcp.c @@ -37,11 +37,11 @@ * Null hashes to align with hw behavior on imx6sl and ull * these are flipped for consistency with hw output */ -const uint8_t sha1_null_hash[] = +static const uint8_t sha1_null_hash[] = "\x09\x07\xd8\xaf\x90\x18\x60\x95\xef\xbf" "\x55\x32\x0d\x4b\x6b\x5e\xee\xa3\x39\xda";
-const uint8_t sha256_null_hash[] = +static const uint8_t sha256_null_hash[] = "\x55\xb8\x52\x78\x1b\x99\x95\xa4" "\x4c\x93\x9b\x64\xe4\x41\xae\x27" "\x24\xb9\x6f\x99\xc8\xf4\xfb\x9a"
From: Jeremy Sowden jeremy@azazel.net
commit 01ce31c57b3f07c91c9d45bbaf126124cce83a5d upstream.
Removed info log-message if ipip tunnel registration fails during module-initialization: it adds nothing to the error message that is written on all failures.
Fixes: dd9ee3444014e ("vti4: Fix a ipip packet processing bug in 'IPCOMP' virtual tunnel") Signed-off-by: Jeremy Sowden jeremy@azazel.net Signed-off-by: Steffen Klassert steffen.klassert@secunet.com Cc: Guenter Roeck linux@roeck-us.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- net/ipv4/ip_vti.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
--- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c @@ -666,10 +666,8 @@ static int __init vti_init(void)
msg = "ipip tunnel"; err = xfrm4_tunnel_register(&ipip_handler, AF_INET); - if (err < 0) { - pr_info("%s: cant't register tunnel\n",__func__); + if (err < 0) goto xfrm_tunnel_failed; - }
msg = "netlink interface"; err = rtnl_link_register(&vti_link_ops);
From: James Smart jsmart2021@gmail.com
[ Upstream commit 38503943c89f0bafd9e3742f63f872301d44cbea ]
The following kasan bug was called out:
BUG: KASAN: slab-out-of-bounds in lpfc_unreg_login+0x7c/0xc0 [lpfc] Read of size 2 at addr ffff889fc7c50a22 by task lpfc_worker_3/6676 ... Call Trace: dump_stack+0x96/0xe0 ? lpfc_unreg_login+0x7c/0xc0 [lpfc] print_address_description.constprop.6+0x1b/0x220 ? lpfc_unreg_login+0x7c/0xc0 [lpfc] ? lpfc_unreg_login+0x7c/0xc0 [lpfc] __kasan_report.cold.9+0x37/0x7c ? lpfc_unreg_login+0x7c/0xc0 [lpfc] kasan_report+0xe/0x20 lpfc_unreg_login+0x7c/0xc0 [lpfc] lpfc_sli_def_mbox_cmpl+0x334/0x430 [lpfc] ...
When processing the completion of a "Reg Rpi" login mailbox command in lpfc_sli_def_mbox_cmpl, a call may be made to lpfc_unreg_login. The vpi is extracted from the completing mailbox context and passed as an input for the next. However, the vpi stored in the mailbox command context is an absolute vpi, which for SLI4 represents both base + offset. When used with a non-zero base component, (function id > 0) this results in an out-of-range access beyond the allocated phba->vpi_ids array.
Fix by subtracting the function's base value to get an accurate vpi number.
Link: https://lore.kernel.org/r/20200322181304.37655-2-jsmart2021@gmail.com Signed-off-by: James Smart jsmart2021@gmail.com Signed-off-by: Dick Kennedy dick.kennedy@broadcom.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/lpfc/lpfc_sli.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 065fdc17bbfbb..7a94c2d352390 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -2186,6 +2186,8 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) !pmb->u.mb.mbxStatus) { rpi = pmb->u.mb.un.varWords[0]; vpi = pmb->u.mb.un.varRegLogin.vpi; + if (phba->sli_rev == LPFC_SLI_REV4) + vpi -= phba->sli4_hba.max_cfg_param.vpi_base; lpfc_unreg_login(phba, vpi, rpi, pmb); pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
From: Qiujun Huang hqjagain@gmail.com
[ Upstream commit c6d50296032f0b97473eb2e274dc7cc5d0173847 ]
Return the error returned by ceph_mdsc_do_request(). Otherwise, r_target_inode ends up being NULL this ends up returning ENOENT regardless of the error.
Signed-off-by: Qiujun Huang hqjagain@gmail.com Reviewed-by: Jeff Layton jlayton@kernel.org Signed-off-by: Ilya Dryomov idryomov@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/ceph/export.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/fs/ceph/export.c b/fs/ceph/export.c index fe02ae7f056a3..ff9e60daf086b 100644 --- a/fs/ceph/export.c +++ b/fs/ceph/export.c @@ -146,6 +146,11 @@ static struct dentry *__get_parent(struct super_block *sb, } req->r_num_caps = 1; err = ceph_mdsc_do_request(mdsc, NULL, req); + if (err) { + ceph_mdsc_put_request(req); + return ERR_PTR(err); + } + inode = req->r_target_inode; if (inode) ihold(inode);
From: Yan, Zheng zyan@redhat.com
[ Upstream commit 0aa971b6fd3f92afef6afe24ef78d9bb14471519 ]
1. try_get_cap_refs() fails to get caps and finds that mds_wanted does not include what it wants. It returns -ESTALE. 2. ceph_get_caps() calls ceph_renew_caps(). ceph_renew_caps() finds that inode has cap, so it calls ceph_check_caps(). 3. ceph_check_caps() finds that issued caps (without checking if it's stale) already includes caps wanted by open file, so it skips updating wanted caps.
Above events can cause an infinite loop inside ceph_get_caps().
Signed-off-by: "Yan, Zheng" zyan@redhat.com Reviewed-by: Jeff Layton jlayton@kernel.org Signed-off-by: Ilya Dryomov idryomov@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/ceph/caps.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index aa4df4a022525..efdf81ea3b5f8 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -1734,8 +1734,12 @@ retry_locked: }
/* want more caps from mds? */ - if (want & ~(cap->mds_wanted | cap->issued)) - goto ack; + if (want & ~cap->mds_wanted) { + if (want & ~(cap->mds_wanted | cap->issued)) + goto ack; + if (!__cap_is_valid(cap)) + goto ack; + }
/* things we might delay */ if ((cap->issued & ~retain) == 0 &&
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit 1451a3eed24b5fd6a604683f0b6995e0e7e16c79 ]
Runtime PM should be enabled before calling pwmchip_add(), as PWM users can appear immediately after the PWM chip has been added. Likewise, Runtime PM should be disabled after the removal of the PWM chip.
Fixes: ed6c1476bf7f16d5 ("pwm: Add support for R-Car PWM Timer") Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Reviewed-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Thierry Reding thierry.reding@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pwm/pwm-rcar.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/pwm/pwm-rcar.c b/drivers/pwm/pwm-rcar.c index 6e99a63ffa290..df0723df1f997 100644 --- a/drivers/pwm/pwm-rcar.c +++ b/drivers/pwm/pwm-rcar.c @@ -232,24 +232,28 @@ static int rcar_pwm_probe(struct platform_device *pdev) rcar_pwm->chip.base = -1; rcar_pwm->chip.npwm = 1;
+ pm_runtime_enable(&pdev->dev); + ret = pwmchip_add(&rcar_pwm->chip); if (ret < 0) { dev_err(&pdev->dev, "failed to register PWM chip: %d\n", ret); + pm_runtime_disable(&pdev->dev); return ret; }
- pm_runtime_enable(&pdev->dev); - return 0; }
static int rcar_pwm_remove(struct platform_device *pdev) { struct rcar_pwm_chip *rcar_pwm = platform_get_drvdata(pdev); + int ret; + + ret = pwmchip_remove(&rcar_pwm->chip);
pm_runtime_disable(&pdev->dev);
- return pwmchip_remove(&rcar_pwm->chip); + return ret; }
static const struct of_device_id rcar_pwm_of_table[] = {
From: Wu Bo wubo40@huawei.com
[ Upstream commit 13e60d3ba287d96eeaf1deaadba51f71578119a3 ]
If the daemon is restarted or crashes while logging out of a session, the unbind session event sent by the kernel is not processed and is lost. When the daemon starts again, the session can't be unbound because the daemon is waiting for the event message. However, the kernel has already logged out and the event will not be resent.
When iscsid restart is complete, logout session reports error:
Logging out of session [sid: 6, target: iqn.xxxxx, portal: xx.xx.xx.xx,3260] iscsiadm: Could not logout of [sid: 6, target: iscsiadm -m node iqn.xxxxx, portal: xx.xx.xx.xx,3260]. iscsiadm: initiator reported error (9 - internal error) iscsiadm: Could not logout of all requested sessions
Make sure the unbind event is emitted.
[mkp: commit desc and applied by hand since patch was mangled]
Link: https://lore.kernel.org/r/4eab1771-2cb3-8e79-b31c-923652340e99@huawei.com Reviewed-by: Lee Duncan lduncan@suse.com Signed-off-by: Wu Bo wubo40@huawei.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/scsi_transport_iscsi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 20cf01d6ded7e..de10b461ec7ef 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -2014,7 +2014,7 @@ static void __iscsi_unbind_session(struct work_struct *work) if (session->target_id == ISCSI_MAX_TARGET) { spin_unlock_irqrestore(&session->lock, flags); mutex_unlock(&ihost->mutex); - return; + goto unbind_session_exit; }
target_id = session->target_id; @@ -2026,6 +2026,8 @@ static void __iscsi_unbind_session(struct work_struct *work) ida_simple_remove(&iscsi_sess_ida, target_id);
scsi_remove_target(&session->dev); + +unbind_session_exit: iscsi_session_event(session, ISCSI_KEVENT_UNBIND_SESSION); ISCSI_DBG_TRANS_SESSION(session, "Completed target removal\n"); }
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit 81630dc042af998b9f58cd8e2c29dab9777ea176 ]
sst_send_slot_map() uses sst_fill_and_send_cmd_unlocked() because in some places it is called with the drv->lock mutex already held.
So it must always be called with the mutex locked. This commit adds missing locking in the sst_set_be_modules() code-path.
Fixes: 24c8d14192cc ("ASoC: Intel: mrfld: add DSP core controls") Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Link: https://lore.kernel.org/r/20200402185359.3424-1-hdegoede@redhat.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/intel/atom/sst-atom-controls.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/sound/soc/intel/atom/sst-atom-controls.c b/sound/soc/intel/atom/sst-atom-controls.c index b070d47547450..067cee92d333b 100644 --- a/sound/soc/intel/atom/sst-atom-controls.c +++ b/sound/soc/intel/atom/sst-atom-controls.c @@ -963,7 +963,9 @@ static int sst_set_be_modules(struct snd_soc_dapm_widget *w, dev_dbg(c->dev, "Enter: widget=%s\n", w->name);
if (SND_SOC_DAPM_EVENT_ON(event)) { + mutex_lock(&drv->lock); ret = sst_send_slot_map(drv); + mutex_unlock(&drv->lock); if (ret) return ret; ret = sst_send_pipe_module_params(w, k);
From: Vasily Averin vvs@virtuozzo.com
[ Upstream commit f4d74ef6220c1eda0875da30457bef5c7111ab06 ]
If seq_file .next function does not change position index, read after some lseek can generate unexpected output.
https://bugzilla.kernel.org/show_bug.cgi?id=206283 Signed-off-by: Vasily Averin vvs@virtuozzo.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Acked-by: Peter Oberparleiter oberpar@linux.ibm.com Cc: Al Viro viro@zeniv.linux.org.uk Cc: Davidlohr Bueso dave@stgolabs.net Cc: Ingo Molnar mingo@redhat.com Cc: Manfred Spraul manfred@colorfullife.com Cc: NeilBrown neilb@suse.com Cc: Steven Rostedt rostedt@goodmis.org Cc: Waiman Long longman@redhat.com Link: http://lkml.kernel.org/r/f65c6ee7-bd00-f910-2f8a-37cc67e4ff88@virtuozzo.com Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/gcov/fs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/gcov/fs.c b/kernel/gcov/fs.c index edf67c493a8e1..e473f6a1f6ca7 100644 --- a/kernel/gcov/fs.c +++ b/kernel/gcov/fs.c @@ -108,9 +108,9 @@ static void *gcov_seq_next(struct seq_file *seq, void *data, loff_t *pos) { struct gcov_iterator *iter = data;
+ (*pos)++; if (gcov_iter_next(iter)) return NULL; - (*pos)++;
return iter; }
From: Vasily Averin vvs@virtuozzo.com
[ Upstream commit 89163f93c6f969da5811af5377cc10173583123b ]
If seq_file .next function does not change position index, read after some lseek can generate unexpected output.
https://bugzilla.kernel.org/show_bug.cgi?id=206283 Signed-off-by: Vasily Averin vvs@virtuozzo.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Acked-by: Waiman Long longman@redhat.com Cc: Davidlohr Bueso dave@stgolabs.net Cc: Manfred Spraul manfred@colorfullife.com Cc: Al Viro viro@zeniv.linux.org.uk Cc: Ingo Molnar mingo@redhat.com Cc: NeilBrown neilb@suse.com Cc: Peter Oberparleiter oberpar@linux.ibm.com Cc: Steven Rostedt rostedt@goodmis.org Link: http://lkml.kernel.org/r/b7a20945-e315-8bb0-21e6-3875c14a8494@virtuozzo.com Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- ipc/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ipc/util.c b/ipc/util.c index 0f401d94b7c65..2724f9071ab39 100644 --- a/ipc/util.c +++ b/ipc/util.c @@ -756,13 +756,13 @@ static struct kern_ipc_perm *sysvipc_find_ipc(struct ipc_ids *ids, loff_t pos, total++; }
+ *new_pos = pos + 1; if (total >= ids->in_use) return NULL;
for (; pos < IPCMNI; pos++) { ipc = idr_find(&ids->ipcs_idr, pos); if (ipc != NULL) { - *new_pos = pos + 1; rcu_read_lock(); ipc_lock_object(ipc); return ipc;
From: Cornelia Huck cohuck@redhat.com
[ Upstream commit 05ce3e53f375295c2940390b2b429e506e07655c ]
The common I/O layer delays the ADD uevent for subchannels and delegates generating this uevent to the individual subchannel drivers. The io_subchannel driver will do so when the associated ccw_device has been registered -- but unconditionally, so more ADD uevents will be generated if a subchannel has been unbound from the io_subchannel driver and later rebound.
To fix this, only generate the ADD event if uevents were still suppressed for the device.
Fixes: fa1a8c23eb7d ("s390: cio: Delay uevents for subchannels") Message-Id: 20200327124503.9794-2-cohuck@redhat.com Reported-by: Boris Fiuczynski fiuczy@linux.ibm.com Reviewed-by: Peter Oberparleiter oberpar@linux.ibm.com Reviewed-by: Boris Fiuczynski fiuczy@linux.ibm.com Signed-off-by: Cornelia Huck cohuck@redhat.com Signed-off-by: Vasily Gorbik gor@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/s390/cio/device.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 6aae684128021..2389a1dc6d300 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -872,8 +872,10 @@ static void io_subchannel_register(struct ccw_device *cdev) * Now we know this subchannel will stay, we can throw * our delayed uevent. */ - dev_set_uevent_suppress(&sch->dev, 0); - kobject_uevent(&sch->dev.kobj, KOBJ_ADD); + if (dev_get_uevent_suppress(&sch->dev)) { + dev_set_uevent_suppress(&sch->dev, 0); + kobject_uevent(&sch->dev.kobj, KOBJ_ADD); + } /* make it known to the system */ ret = ccw_device_add(cdev); if (ret) { @@ -1082,8 +1084,11 @@ static int io_subchannel_probe(struct subchannel *sch) * Throw the delayed uevent for the subchannel, register * the ccw_device and exit. */ - dev_set_uevent_suppress(&sch->dev, 0); - kobject_uevent(&sch->dev.kobj, KOBJ_ADD); + if (dev_get_uevent_suppress(&sch->dev)) { + /* should always be the case for the console */ + dev_set_uevent_suppress(&sch->dev, 0); + kobject_uevent(&sch->dev.kobj, KOBJ_ADD); + } cdev = sch_get_cdev(sch); rc = ccw_device_add(cdev); if (rc) {
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit d5a3c7a4536e1329a758e14340efd0e65252bd3d ]
Runtime PM should be enabled before calling pwmchip_add(), as PWM users can appear immediately after the PWM chip has been added. Likewise, Runtime PM should always be disabled after the removal of the PWM chip, even if the latter failed.
Fixes: 99b82abb0a35b073 ("pwm: Add Renesas TPU PWM driver") Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Thierry Reding thierry.reding@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pwm/pwm-renesas-tpu.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/pwm/pwm-renesas-tpu.c b/drivers/pwm/pwm-renesas-tpu.c index 075c1a764ba29..6247a956cc089 100644 --- a/drivers/pwm/pwm-renesas-tpu.c +++ b/drivers/pwm/pwm-renesas-tpu.c @@ -423,16 +423,17 @@ static int tpu_probe(struct platform_device *pdev) tpu->chip.base = -1; tpu->chip.npwm = TPU_CHANNEL_MAX;
+ pm_runtime_enable(&pdev->dev); + ret = pwmchip_add(&tpu->chip); if (ret < 0) { dev_err(&pdev->dev, "failed to register PWM chip\n"); + pm_runtime_disable(&pdev->dev); return ret; }
dev_info(&pdev->dev, "TPU PWM %d registered\n", tpu->pdev->id);
- pm_runtime_enable(&pdev->dev); - return 0; }
@@ -442,12 +443,10 @@ static int tpu_remove(struct platform_device *pdev) int ret;
ret = pwmchip_remove(&tpu->chip); - if (ret) - return ret;
pm_runtime_disable(&pdev->dev);
- return 0; + return ret; }
#ifdef CONFIG_OF
From: Florian Fainelli f.fainelli@gmail.com
[ Upstream commit 2c25b07e5ec119cab609e41407a1fb3fa61442f5 ]
The newer 2711 and 7211 chips have two PWM controllers and failure to dynamically allocate the PWM base would prevent the second PWM controller instance being probed for succeeding with an -EEXIST error from alloc_pwms().
Fixes: e5a06dc5ac1f ("pwm: Add BCM2835 PWM driver") Signed-off-by: Florian Fainelli f.fainelli@gmail.com Acked-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Reviewed-by: Nicolas Saenz Julienne nsaenzjulienne@suse.de Signed-off-by: Thierry Reding thierry.reding@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pwm/pwm-bcm2835.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/pwm/pwm-bcm2835.c b/drivers/pwm/pwm-bcm2835.c index b4c7f956b6fa6..388a9fa5c1d24 100644 --- a/drivers/pwm/pwm-bcm2835.c +++ b/drivers/pwm/pwm-bcm2835.c @@ -160,6 +160,7 @@ static int bcm2835_pwm_probe(struct platform_device *pdev)
pc->chip.dev = &pdev->dev; pc->chip.ops = &bcm2835_pwm_ops; + pc->chip.base = -1; pc->chip.npwm = 2;
platform_set_drvdata(pdev, pc);
From: John Haxby john.haxby@oracle.com
[ Upstream commit 82c9ae440857840c56e05d4fb1427ee032531346 ]
Commit b6f6118901d1 ("ipv6: restrict IPV6_ADDRFORM operation") fixed a problem found by syzbot an unfortunate logic error meant that it also broke IPV6_ADDRFORM.
Rearrange the checks so that the earlier test is just one of the series of checks made before moving the socket from IPv6 to IPv4.
Fixes: b6f6118901d1 ("ipv6: restrict IPV6_ADDRFORM operation") Signed-off-by: John Haxby john.haxby@oracle.com Cc: stable@vger.kernel.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/ipv6/ipv6_sockglue.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
--- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -185,15 +185,14 @@ static int do_ipv6_setsockopt(struct soc retv = -EBUSY; break; } - } else if (sk->sk_protocol == IPPROTO_TCP) { - if (sk->sk_prot != &tcpv6_prot) { - retv = -EBUSY; - break; - } - break; - } else { + } + if (sk->sk_protocol == IPPROTO_TCP && + sk->sk_prot != &tcpv6_prot) { + retv = -EBUSY; break; } + if (sk->sk_protocol != IPPROTO_TCP) + break; if (sk->sk_state != TCP_ESTABLISHED) { retv = -ENOTCONN; break;
From: Taehee Yoo ap420073@gmail.com
[ Upstream commit 4dee15b4fd0d61ec6bbd179238191e959d34cf7a ]
In the macvlan_device_event(), the list_first_entry_or_null() is used. This function could return null pointer if there is no node. But, the macvlan module doesn't check the null pointer. So, null-ptr-deref would occur.
bond0 | +----+-----+ | | macvlan0 macvlan1 | | dummy0 dummy1
The problem scenario. If dummy1 is removed, 1. ->dellink() of dummy1 is called. 2. NETDEV_UNREGISTER of dummy1 notification is sent to macvlan module. 3. ->dellink() of macvlan1 is called. 4. NETDEV_UNREGISTER of macvlan1 notification is sent to bond module. 5. __bond_release_one() is called and it internally calls dev_set_mac_address(). 6. dev_set_mac_address() calls the ->ndo_set_mac_address() of macvlan1, which is macvlan_set_mac_address(). 7. macvlan_set_mac_address() calls the dev_set_mac_address() with dummy1. 8. NETDEV_CHANGEADDR of dummy1 is sent to macvlan module. 9. In the macvlan_device_event(), it calls list_first_entry_or_null(). At this point, dummy1 and macvlan1 were removed. So, list_first_entry_or_null() will return NULL.
Test commands: ip netns add nst ip netns exec nst ip link add bond0 type bond for i in {0..10} do ip netns exec nst ip link add dummy$i type dummy ip netns exec nst ip link add macvlan$i link dummy$i \ type macvlan mode passthru ip netns exec nst ip link set macvlan$i master bond0 done ip netns del nst
Splat looks like: [ 40.585687][ T146] general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] SMP DEI [ 40.587249][ T146] KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] [ 40.588342][ T146] CPU: 1 PID: 146 Comm: kworker/u8:2 Not tainted 5.7.0-rc1+ #532 [ 40.589299][ T146] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 [ 40.590469][ T146] Workqueue: netns cleanup_net [ 40.591045][ T146] RIP: 0010:macvlan_device_event+0x4e2/0x900 [macvlan] [ 40.591905][ T146] Code: 00 00 00 00 00 fc ff df 80 3c 06 00 0f 85 45 02 00 00 48 89 da 48 b8 00 00 00 00 00 fc ff d2 [ 40.594126][ T146] RSP: 0018:ffff88806116f4a0 EFLAGS: 00010246 [ 40.594783][ T146] RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000000000 [ 40.595653][ T146] RDX: 0000000000000000 RSI: ffff88806547ddd8 RDI: ffff8880540f1360 [ 40.596495][ T146] RBP: ffff88804011a808 R08: fffffbfff4fb8421 R09: fffffbfff4fb8421 [ 40.597377][ T146] R10: ffffffffa7dc2107 R11: 0000000000000000 R12: 0000000000000008 [ 40.598186][ T146] R13: ffff88804011a000 R14: ffff8880540f1000 R15: 1ffff1100c22de9a [ 40.599012][ T146] FS: 0000000000000000(0000) GS:ffff888067800000(0000) knlGS:0000000000000000 [ 40.600004][ T146] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 40.600665][ T146] CR2: 00005572d3a807b8 CR3: 000000005fcf4003 CR4: 00000000000606e0 [ 40.601485][ T146] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 40.602461][ T146] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 40.603443][ T146] Call Trace: [ 40.603871][ T146] ? nf_tables_dump_setelem+0xa0/0xa0 [nf_tables] [ 40.604587][ T146] ? macvlan_uninit+0x100/0x100 [macvlan] [ 40.605212][ T146] ? __module_text_address+0x13/0x140 [ 40.605842][ T146] notifier_call_chain+0x90/0x160 [ 40.606477][ T146] dev_set_mac_address+0x28e/0x3f0 [ 40.607117][ T146] ? netdev_notify_peers+0xc0/0xc0 [ 40.607762][ T146] ? __module_text_address+0x13/0x140 [ 40.608440][ T146] ? notifier_call_chain+0x90/0x160 [ 40.609097][ T146] ? dev_set_mac_address+0x1f0/0x3f0 [ 40.609758][ T146] dev_set_mac_address+0x1f0/0x3f0 [ 40.610402][ T146] ? __local_bh_enable_ip+0xe9/0x1b0 [ 40.611071][ T146] ? bond_hw_addr_flush+0x77/0x100 [bonding] [ 40.611823][ T146] ? netdev_notify_peers+0xc0/0xc0 [ 40.612461][ T146] ? bond_hw_addr_flush+0x77/0x100 [bonding] [ 40.613213][ T146] ? bond_hw_addr_flush+0x77/0x100 [bonding] [ 40.613963][ T146] ? __local_bh_enable_ip+0xe9/0x1b0 [ 40.614631][ T146] ? bond_time_in_interval.isra.31+0x90/0x90 [bonding] [ 40.615484][ T146] ? __bond_release_one+0x9f0/0x12c0 [bonding] [ 40.616230][ T146] __bond_release_one+0x9f0/0x12c0 [bonding] [ 40.616949][ T146] ? bond_enslave+0x47c0/0x47c0 [bonding] [ 40.617642][ T146] ? lock_downgrade+0x730/0x730 [ 40.618218][ T146] ? check_flags.part.42+0x450/0x450 [ 40.618850][ T146] ? __mutex_unlock_slowpath+0xd0/0x670 [ 40.619519][ T146] ? trace_hardirqs_on+0x30/0x180 [ 40.620117][ T146] ? wait_for_completion+0x250/0x250 [ 40.620754][ T146] bond_netdev_event+0x822/0x970 [bonding] [ 40.621460][ T146] ? __module_text_address+0x13/0x140 [ 40.622097][ T146] notifier_call_chain+0x90/0x160 [ 40.622806][ T146] rollback_registered_many+0x660/0xcf0 [ 40.623522][ T146] ? netif_set_real_num_tx_queues+0x780/0x780 [ 40.624290][ T146] ? notifier_call_chain+0x90/0x160 [ 40.624957][ T146] ? netdev_upper_dev_unlink+0x114/0x180 [ 40.625686][ T146] ? __netdev_adjacent_dev_unlink_neighbour+0x30/0x30 [ 40.626421][ T146] ? mutex_is_locked+0x13/0x50 [ 40.627016][ T146] ? unregister_netdevice_queue+0xf2/0x240 [ 40.627663][ T146] unregister_netdevice_many.part.134+0x13/0x1b0 [ 40.628362][ T146] default_device_exit_batch+0x2d9/0x390 [ 40.628987][ T146] ? unregister_netdevice_many+0x40/0x40 [ 40.629615][ T146] ? dev_change_net_namespace+0xcb0/0xcb0 [ 40.630279][ T146] ? prepare_to_wait_exclusive+0x2e0/0x2e0 [ 40.630943][ T146] ? ops_exit_list.isra.9+0x97/0x140 [ 40.631554][ T146] cleanup_net+0x441/0x890 [ ... ]
Fixes: e289fd28176b ("macvlan: fix the problem when mac address changes for passthru mode") Reported-by: syzbot+5035b1f9dc7ea4558d5a@syzkaller.appspotmail.com Signed-off-by: Taehee Yoo ap420073@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/macvlan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -1561,7 +1561,7 @@ static int macvlan_device_event(struct n struct macvlan_dev, list);
- if (macvlan_sync_address(vlan->dev, dev->dev_addr)) + if (vlan && macvlan_sync_address(vlan->dev, dev->dev_addr)) return NOTIFY_BAD;
break;
From: Xiyu Yang xiyuyang19@fudan.edu.cn
[ Upstream commit d03f228470a8c0a22b774d1f8d47071e0de4f6dd ]
nr_add_node() invokes nr_neigh_get_dev(), which returns a local reference of the nr_neigh object to "nr_neigh" with increased refcnt.
When nr_add_node() returns, "nr_neigh" becomes invalid, so the refcount should be decreased to keep refcount balanced.
The issue happens in one normal path of nr_add_node(), which forgets to decrease the refcnt increased by nr_neigh_get_dev() and causes a refcnt leak. It should decrease the refcnt before the function returns like other normal paths do.
Fix this issue by calling nr_neigh_put() before the nr_add_node() returns.
Signed-off-by: Xiyu Yang xiyuyang19@fudan.edu.cn Signed-off-by: Xin Tan tanxin.ctf@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/netrom/nr_route.c | 1 + 1 file changed, 1 insertion(+)
--- a/net/netrom/nr_route.c +++ b/net/netrom/nr_route.c @@ -199,6 +199,7 @@ static int __must_check nr_add_node(ax25 /* refcount initialized at 1 */ spin_unlock_bh(&nr_node_list_lock);
+ nr_neigh_put(nr_neigh); return 0; } nr_node_lock(nr_node);
From: Xiyu Yang xiyuyang19@fudan.edu.cn
[ Upstream commit f35d12971b4d814cdb2f659d76b42f0c545270b6 ]
x25_lapb_receive_frame() invokes x25_get_neigh(), which returns a reference of the specified x25_neigh object to "nb" with increased refcnt.
When x25_lapb_receive_frame() returns, local variable "nb" becomes invalid, so the refcount should be decreased to keep refcount balanced.
The reference counting issue happens in one path of x25_lapb_receive_frame(). When pskb_may_pull() returns false, the function forgets to decrease the refcnt increased by x25_get_neigh(), causing a refcnt leak.
Fix this issue by calling x25_neigh_put() when pskb_may_pull() returns false.
Fixes: cb101ed2c3c7 ("x25: Handle undersized/fragmented skbs") Signed-off-by: Xiyu Yang xiyuyang19@fudan.edu.cn Signed-off-by: Xin Tan tanxin.ctf@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/x25/x25_dev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/net/x25/x25_dev.c +++ b/net/x25/x25_dev.c @@ -120,8 +120,10 @@ int x25_lapb_receive_frame(struct sk_buf goto drop; }
- if (!pskb_may_pull(skb, 1)) + if (!pskb_may_pull(skb, 1)) { + x25_neigh_put(nb); return 0; + }
switch (skb->data[0]) {
From: Eric Dumazet edumazet@google.com
[ Upstream commit 9bacd256f1354883d3c1402655153367982bba49 ]
TCP stack is dumb in how it cooks its output packets.
Depending on MAX_HEADER value, we might chose a bad ending point for the headers.
If we align the end of TCP headers to cache line boundary, we make sure to always use the smallest number of cache lines, which always help.
Signed-off-by: Eric Dumazet edumazet@google.com Cc: Soheil Hassas Yeganeh soheil@google.com Acked-by: Soheil Hassas Yeganeh soheil@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/net/tcp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -52,7 +52,7 @@ extern struct inet_hashinfo tcp_hashinfo extern struct percpu_counter tcp_orphan_count; void tcp_time_wait(struct sock *sk, int state, int timeo);
-#define MAX_TCP_HEADER (128 + MAX_HEADER) +#define MAX_TCP_HEADER L1_CACHE_ALIGN(128 + MAX_HEADER) #define MAX_TCP_OPTION_SPACE 40 #define TCP_MIN_SND_MSS 48 #define TCP_MIN_GSO_SIZE (TCP_MIN_SND_MSS - MAX_TCP_OPTION_SPACE)
From: Taehee Yoo ap420073@gmail.com
[ Upstream commit 1c30fbc76b8f0c07c92a8ca4cd7c456612e17eb5 ]
When team mode is changed or set, the team_mode_get() is called to check whether the mode module is inserted or not. If the mode module is not inserted, it calls the request_module(). In the request_module(), it creates a child process, which is the "modprobe" process and waits for the done of the child process. At this point, the following locks were used. down_read(&cb_lock()); by genl_rcv() genl_lock(); by genl_rcv_msc() rtnl_lock(); by team_nl_cmd_options_set() mutex_lock(&team->lock); by team_nl_team_get()
Concurrently, the team module could be removed by rmmod or "modprobe -r" The __exit function of team module is team_module_exit(), which calls team_nl_fini() and it tries to acquire following locks. down_write(&cb_lock); genl_lock(); Because of the genl_lock() and cb_lock, this process can't be finished earlier than request_module() routine.
The problem secenario. CPU0 CPU1 team_mode_get request_module() modprobe -r team_mode_roundrobin team <--(B) modprobe team <--(A) team_mode_roundrobin
By request_module(), the "modprobe team_mode_roundrobin" command will be executed. At this point, the modprobe process will decide that the team module should be inserted before team_mode_roundrobin. Because the team module is being removed.
By the module infrastructure, the same module insert/remove operations can't be executed concurrently. So, (A) waits for (B) but (B) also waits for (A) because of locks. So that the hang occurs at this point.
Test commands: while : do teamd -d & killall teamd & modprobe -rv team_mode_roundrobin & done
The approach of this patch is to hold the reference count of the team module if the team module is compiled as a module. If the reference count of the team module is not zero while request_module() is being called, the team module will not be removed at that moment. So that the above scenario could not occur.
Fixes: 3d249d4ca7d0 ("net: introduce ethernet teaming device") Signed-off-by: Taehee Yoo ap420073@gmail.com Reviewed-by: Jiri Pirko jiri@mellanox.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/team/team.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -466,6 +466,9 @@ static const struct team_mode *team_mode struct team_mode_item *mitem; const struct team_mode *mode = NULL;
+ if (!try_module_get(THIS_MODULE)) + return NULL; + spin_lock(&mode_list_lock); mitem = __find_mode(kind); if (!mitem) { @@ -481,6 +484,7 @@ static const struct team_mode *team_mode }
spin_unlock(&mode_list_lock); + module_put(THIS_MODULE); return mode; }
From: David Ahern dsahern@gmail.com
[ Upstream commit 0c922a4850eba2e668f73a3f1153196e09abb251 ]
IPSKB_XFRM_TRANSFORMED and IP6SKB_XFRM_TRANSFORMED are skb flags set by xfrm code to tell other skb handlers that the packet has been passed through the xfrm output functions. Simplify the code and just always set them rather than conditionally based on netfilter enabled thus making the flag available for other users.
Signed-off-by: David Ahern dsahern@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/ipv4/xfrm4_output.c | 2 -- net/ipv6/xfrm6_output.c | 2 -- 2 files changed, 4 deletions(-)
--- a/net/ipv4/xfrm4_output.c +++ b/net/ipv4/xfrm4_output.c @@ -75,9 +75,7 @@ int xfrm4_output_finish(struct sock *sk, { memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
-#ifdef CONFIG_NETFILTER IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED; -#endif
return xfrm_output(sk, skb); } --- a/net/ipv6/xfrm6_output.c +++ b/net/ipv6/xfrm6_output.c @@ -125,9 +125,7 @@ int xfrm6_output_finish(struct sock *sk, { memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
-#ifdef CONFIG_NETFILTER IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED; -#endif
return xfrm_output(sk, skb); }
From: Takashi Iwai tiwai@suse.de
[ Upstream commit a8cf44f085ac12c0b5b8750ebb3b436c7f455419 ]
The commit 3c6fd1f07ed0 ("ALSA: hda: Add driver blacklist") added a new blacklist for the devices that are known to have empty codecs, and one of the entries was ASUS ROG Zenith II (PCI SSID 1043:874f). However, it turned out that the very same PCI SSID is used for the previous model that does have the valid HD-audio codecs and the change broke the sound on it.
This patch reverts the corresponding entry as a temporary solution. Although Zenith II and co will see get the empty HD-audio bus again, it'd be merely resource wastes and won't affect the functionality, so it's no end of the world. We'll need to address this later, e.g. by either switching to DMI string matching or using PCI ID & SSID pairs.
Fixes: 3c6fd1f07ed0 ("ALSA: hda: Add driver blacklist") Reported-by: Johnathan Smithinovic johnathan.smithinovic@gmx.at Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20200419071926.22683-1-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/pci/hda/hda_intel.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index faf2554397021..da9f6749b3be2 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1978,7 +1978,6 @@ static const struct hdac_io_ops pci_hda_io_ops = { * should be ignored from the beginning. */ static const struct snd_pci_quirk driver_blacklist[] = { - SND_PCI_QUIRK(0x1043, 0x874f, "ASUS ROG Zenith II / Strix", 0), SND_PCI_QUIRK(0x1462, 0xcb59, "MSI TRX40 Creator", 0), SND_PCI_QUIRK(0x1462, 0xcb60, "MSI TRX40", 0), {}
From: Lars-Peter Clausen lars@metafoo.de
commit e44ec7794d88f918805d700240211a9ec05ed89d upstream.
The check for shutting down the second ADC is inverted. This causes it to be powered down when it should be enabled. As a result channels that are supposed to be handled by the second ADC return invalid conversion results.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de Fixes: bdc8cda1d010 ("iio:adc: Add Xilinx XADC driver") Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/iio/adc/xilinx-xadc-core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/iio/adc/xilinx-xadc-core.c +++ b/drivers/iio/adc/xilinx-xadc-core.c @@ -709,13 +709,14 @@ static int xadc_power_adc_b(struct xadc { uint16_t val;
+ /* Powerdown the ADC-B when it is not needed. */ switch (seq_mode) { case XADC_CONF1_SEQ_SIMULTANEOUS: case XADC_CONF1_SEQ_INDEPENDENT: - val = XADC_CONF2_PD_ADC_B; + val = 0; break; default: - val = 0; + val = XADC_CONF2_PD_ADC_B; break; }
From: Lars-Peter Clausen lars@metafoo.de
commit f954b098fbac4d183219ce5b42d76d6df2aed50a upstream.
When enabling the trigger and unmasking the end-of-sequence (EOS) interrupt the EOS interrupt should be cleared from the status register. Otherwise it is possible that it was still set from a previous capture. If that is the case the interrupt would fire immediately even though no conversion has been done yet and stale data is being read from the device.
The old code only clears the interrupt if the interrupt was previously unmasked. Which does not make much sense since the interrupt is always masked at this point and in addition masking the interrupt does not clear the interrupt from the status register. So the clearing needs to be done unconditionally.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de Fixes: bdc8cda1d010 ("iio:adc: Add Xilinx XADC driver") Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/iio/adc/xilinx-xadc-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/iio/adc/xilinx-xadc-core.c +++ b/drivers/iio/adc/xilinx-xadc-core.c @@ -660,7 +660,7 @@ static int xadc_trigger_set_state(struct
spin_lock_irqsave(&xadc->lock, flags); xadc_read_reg(xadc, XADC_AXI_REG_IPIER, &val); - xadc_write_reg(xadc, XADC_AXI_REG_IPISR, val & XADC_AXI_INT_EOS); + xadc_write_reg(xadc, XADC_AXI_REG_IPISR, XADC_AXI_INT_EOS); if (state) val |= XADC_AXI_INT_EOS; else
From: Lars-Peter Clausen lars@metafoo.de
commit 8bef455c8b1694547ee59e8b1939205ed9d901a6 upstream.
The XADC has two internal ADCs. Depending on the mode it is operating in either one or both of them are used. The device manual calls this continuous (one ADC) and simultaneous (both ADCs) mode.
The meaning of the sequencing register for the aux channels changes depending on the mode.
In continuous mode each bit corresponds to one of the 16 aux channels. And the single ADC will convert them one by one in order.
In simultaneous mode the aux channels are split into two groups the first 8 channels are assigned to the first ADC and the other 8 channels to the second ADC. The upper 8 bits of the sequencing register are unused and the lower 8 bits control both ADCs. This means a bit needs to be set if either the corresponding channel from the first group or the second group (or both) are set.
Currently the driver does not have the special handling required for simultaneous mode. Add it.
Signed-off-by: Lars-Peter Clausen lars@metafoo.de Fixes: bdc8cda1d010 ("iio:adc: Add Xilinx XADC driver") Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/iio/adc/xilinx-xadc-core.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
--- a/drivers/iio/adc/xilinx-xadc-core.c +++ b/drivers/iio/adc/xilinx-xadc-core.c @@ -785,6 +785,16 @@ static int xadc_preenable(struct iio_dev if (ret) goto err;
+ /* + * In simultaneous mode the upper and lower aux channels are samples at + * the same time. In this mode the upper 8 bits in the sequencer + * register are don't care and the lower 8 bits control two channels + * each. As such we must set the bit if either the channel in the lower + * group or the upper group is enabled. + */ + if (seq_mode == XADC_CONF1_SEQ_SIMULTANEOUS) + scan_mask = ((scan_mask >> 8) | scan_mask) & 0xff0000; + ret = xadc_write_adc_reg(xadc, XADC_REG_SEQ(1), scan_mask >> 16); if (ret) goto err;
From: Piotr Krysiuk piotras@gmail.com
A race condition between threads updating mountpoint reference counter affects longterm releases 4.4.220, 4.9.220, 4.14.177 and 4.19.118.
The mountpoint reference counter corruption may occur when: * one thread increments m_count member of struct mountpoint [under namespace_sem, but not holding mount_lock] pivot_root() * another thread simultaneously decrements the same m_count [under mount_lock, but not holding namespace_sem] put_mountpoint() unhash_mnt() umount_mnt() mntput_no_expire()
To fix this race condition, grab mount_lock before updating m_count in pivot_root().
Reference: CVE-2020-12114 Cc: Al Viro viro@zeniv.linux.org.uk Signed-off-by: Piotr Krysiuk piotras@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/namespace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/namespace.c +++ b/fs/namespace.c @@ -3161,8 +3161,8 @@ SYSCALL_DEFINE2(pivot_root, const char _ /* make certain new is below the root */ if (!is_path_reachable(new_mnt, new.dentry, &root)) goto out4; - root_mp->m_count++; /* pin it so it won't go away */ lock_mount_hash(); + root_mp->m_count++; /* pin it so it won't go away */ detach_mnt(new_mnt, &parent_path); detach_mnt(root_mnt, &root_parent); if (root_mnt->mnt.mnt_flags & MNT_LOCKED) {
From: Changming Liu liu.changm@northeastern.edu
commit 2df7405f79ce1674d73c2786fe1a8727c905d65b upstream.
Change a bunch of arguments of wrapper functions which pass signed integer to an unsigned integer which might cause undefined behaviors when sign integer overflow.
Signed-off-by: Changming Liu liu.changm@northeastern.edu Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/BL0PR06MB45482D71EA822D75A0E60A2EE5D50@BL0PR06MB45... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/misc/sisusbvga/sisusb.c | 20 ++++++++++---------- drivers/usb/misc/sisusbvga/sisusb_init.h | 14 +++++++------- 2 files changed, 17 insertions(+), 17 deletions(-)
--- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c @@ -1243,20 +1243,20 @@ static int sisusb_read_mem_bulk(struct s
#ifdef INCL_SISUSB_CON int -sisusb_setreg(struct sisusb_usb_data *sisusb, int port, u8 data) +sisusb_setreg(struct sisusb_usb_data *sisusb, u32 port, u8 data) { return sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port, data); }
int -sisusb_getreg(struct sisusb_usb_data *sisusb, int port, u8 *data) +sisusb_getreg(struct sisusb_usb_data *sisusb, u32 port, u8 *data) { return sisusb_read_memio_byte(sisusb, SISUSB_TYPE_IO, port, data); } #endif
int -sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port, u8 index, u8 data) +sisusb_setidxreg(struct sisusb_usb_data *sisusb, u32 port, u8 index, u8 data) { int ret; ret = sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port, index); @@ -1265,7 +1265,7 @@ sisusb_setidxreg(struct sisusb_usb_data }
int -sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port, u8 index, u8 *data) +sisusb_getidxreg(struct sisusb_usb_data *sisusb, u32 port, u8 index, u8 *data) { int ret; ret = sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port, index); @@ -1274,7 +1274,7 @@ sisusb_getidxreg(struct sisusb_usb_data }
int -sisusb_setidxregandor(struct sisusb_usb_data *sisusb, int port, u8 idx, +sisusb_setidxregandor(struct sisusb_usb_data *sisusb, u32 port, u8 idx, u8 myand, u8 myor) { int ret; @@ -1289,7 +1289,7 @@ sisusb_setidxregandor(struct sisusb_usb_ }
static int -sisusb_setidxregmask(struct sisusb_usb_data *sisusb, int port, u8 idx, +sisusb_setidxregmask(struct sisusb_usb_data *sisusb, u32 port, u8 idx, u8 data, u8 mask) { int ret; @@ -1303,13 +1303,13 @@ sisusb_setidxregmask(struct sisusb_usb_d }
int -sisusb_setidxregor(struct sisusb_usb_data *sisusb, int port, u8 index, u8 myor) +sisusb_setidxregor(struct sisusb_usb_data *sisusb, u32 port, u8 index, u8 myor) { return(sisusb_setidxregandor(sisusb, port, index, 0xff, myor)); }
int -sisusb_setidxregand(struct sisusb_usb_data *sisusb, int port, u8 idx, u8 myand) +sisusb_setidxregand(struct sisusb_usb_data *sisusb, u32 port, u8 idx, u8 myand) { return(sisusb_setidxregandor(sisusb, port, idx, myand, 0x00)); } @@ -2849,8 +2849,8 @@ static int sisusb_handle_command(struct sisusb_usb_data *sisusb, struct sisusb_command *y, unsigned long arg) { - int retval, port, length; - u32 address; + int retval, length; + u32 port, address;
/* All our commands require the device * to be initialized. --- a/drivers/usb/misc/sisusbvga/sisusb_init.h +++ b/drivers/usb/misc/sisusbvga/sisusb_init.h @@ -811,17 +811,17 @@ static const struct SiS_VCLKData SiSUSB_ int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo); int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo);
-extern int sisusb_setreg(struct sisusb_usb_data *sisusb, int port, u8 data); -extern int sisusb_getreg(struct sisusb_usb_data *sisusb, int port, u8 * data); -extern int sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port, +extern int sisusb_setreg(struct sisusb_usb_data *sisusb, u32 port, u8 data); +extern int sisusb_getreg(struct sisusb_usb_data *sisusb, u32 port, u8 * data); +extern int sisusb_setidxreg(struct sisusb_usb_data *sisusb, u32 port, u8 index, u8 data); -extern int sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port, +extern int sisusb_getidxreg(struct sisusb_usb_data *sisusb, u32 port, u8 index, u8 * data); -extern int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, int port, +extern int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, u32 port, u8 idx, u8 myand, u8 myor); -extern int sisusb_setidxregor(struct sisusb_usb_data *sisusb, int port, +extern int sisusb_setidxregor(struct sisusb_usb_data *sisusb, u32 port, u8 index, u8 myor); -extern int sisusb_setidxregand(struct sisusb_usb_data *sisusb, int port, +extern int sisusb_setidxregand(struct sisusb_usb_data *sisusb, u32 port, u8 idx, u8 myand);
void sisusb_delete(struct kref *kref);
From: Jonathan Cox jonathan@jdcox.net
commit be34a5854b4606bd7a160ad3cb43415d623596c7 upstream.
The Corsair K70 RGB RAPIDFIRE needs the USB_QUIRK_DELAY_INIT and USB_QUIRK_DELAY_CTRL_MSG to function or it will randomly not respond on boot, just like other Corsair keyboards
Signed-off-by: Jonathan Cox jonathan@jdcox.net Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/20200410212427.2886-1-jonathan@jdcox.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/core/quirks.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -272,6 +272,10 @@ static const struct usb_device_id usb_qu /* Corsair K70 LUX */ { USB_DEVICE(0x1b1c, 0x1b36), .driver_info = USB_QUIRK_DELAY_INIT },
+ /* Corsair K70 RGB RAPDIFIRE */ + { USB_DEVICE(0x1b1c, 0x1b38), .driver_info = USB_QUIRK_DELAY_INIT | + USB_QUIRK_DELAY_CTRL_MSG }, + /* MIDI keyboard WORLDE MINI */ { USB_DEVICE(0x1c75, 0x0204), .driver_info = USB_QUIRK_CONFIG_INTF_STRINGS },
From: David Mosberger davidm@egauge.net
commit 98b74b0ee57af1bcb6e8b2e76e707a71c5ef8ec9 upstream.
usb_submit_urb() may take quite long to execute. For example, a single sg list may have 30 or more entries, possibly leading to that many calls to DMA-map pages. This can cause interrupt latency of several hundred micro-seconds.
Avoid the problem by releasing the io->lock spinlock and re-enabling interrupts before calling usb_submit_urb(). This opens races with usb_sg_cancel() and sg_complete(). Handle those races by using usb_block_urb() to stop URBs from being submitted after usb_sg_cancel() or sg_complete() with error.
Note that usb_unlink_urb() is guaranteed to return -ENODEV if !io->urbs[i]->dev and since the -ENODEV case is already handled, we don't have to check for !io->urbs[i]->dev explicitly.
Before this change, reading 512MB from an ext3 filesystem on a USB memory stick showed a throughput of 12 MB/s with about 500 missed deadlines.
With this change, reading the same file gave the same throughput but only one or two missed deadlines.
Signed-off-by: David Mosberger davidm@egauge.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/core/message.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-)
--- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -306,9 +306,10 @@ static void sg_complete(struct urb *urb) */ spin_unlock(&io->lock); for (i = 0, found = 0; i < io->entries; i++) { - if (!io->urbs[i] || !io->urbs[i]->dev) + if (!io->urbs[i]) continue; if (found) { + usb_block_urb(io->urbs[i]); retval = usb_unlink_urb(io->urbs[i]); if (retval != -EINPROGRESS && retval != -ENODEV && @@ -519,12 +520,10 @@ void usb_sg_wait(struct usb_sg_request * int retval;
io->urbs[i]->dev = io->dev; - retval = usb_submit_urb(io->urbs[i], GFP_ATOMIC); - - /* after we submit, let completions or cancellations fire; - * we handshake using io->status. - */ spin_unlock_irq(&io->lock); + + retval = usb_submit_urb(io->urbs[i], GFP_NOIO); + switch (retval) { /* maybe we retrying will recover */ case -ENXIO: /* hc didn't queue this one */ @@ -594,8 +593,8 @@ void usb_sg_cancel(struct usb_sg_request for (i = 0; i < io->entries; i++) { int retval;
- if (!io->urbs[i]->dev) - continue; + usb_block_urb(io->urbs[i]); + retval = usb_unlink_urb(io->urbs[i]); if (retval != -EINPROGRESS && retval != -ENODEV
From: David Mosberger davidm@egauge.net
commit 5f2e5fb873e269fcb806165715d237f0de4ecf1d upstream.
Restructure usb_sg_cancel() so we don't have to disable interrupts while cancelling the URBs.
Suggested-by: Alan Stern stern@rowland.harvard.edu Signed-off-by: David Mosberger davidm@egauge.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/core/message.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-)
--- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -581,31 +581,28 @@ EXPORT_SYMBOL_GPL(usb_sg_wait); void usb_sg_cancel(struct usb_sg_request *io) { unsigned long flags; + int i, retval;
spin_lock_irqsave(&io->lock, flags); + if (io->status) { + spin_unlock_irqrestore(&io->lock, flags); + return; + } + /* shut everything down */ + io->status = -ECONNRESET; + spin_unlock_irqrestore(&io->lock, flags);
- /* shut everything down, if it didn't already */ - if (!io->status) { - int i; - - io->status = -ECONNRESET; - spin_unlock(&io->lock); - for (i = 0; i < io->entries; i++) { - int retval; - - usb_block_urb(io->urbs[i]); + for (i = io->entries - 1; i >= 0; --i) { + usb_block_urb(io->urbs[i]);
- retval = usb_unlink_urb(io->urbs[i]); - if (retval != -EINPROGRESS - && retval != -ENODEV - && retval != -EBUSY - && retval != -EIDRM) - dev_warn(&io->dev->dev, "%s, unlink --> %d\n", - __func__, retval); - } - spin_lock(&io->lock); + retval = usb_unlink_urb(io->urbs[i]); + if (retval != -EINPROGRESS + && retval != -ENODEV + && retval != -EBUSY + && retval != -EIDRM) + dev_warn(&io->dev->dev, "%s, unlink --> %d\n", + __func__, retval); } - spin_unlock_irqrestore(&io->lock, flags); } EXPORT_SYMBOL_GPL(usb_sg_cancel);
From: Alan Stern stern@rowland.harvard.edu
commit 056ad39ee9253873522f6469c3364964a322912b upstream.
FuzzUSB (a variant of syzkaller) found a free-while-still-in-use bug in the USB scatter-gather library:
BUG: KASAN: use-after-free in atomic_read include/asm-generic/atomic-instrumented.h:26 [inline] BUG: KASAN: use-after-free in usb_hcd_unlink_urb+0x5f/0x170 drivers/usb/core/hcd.c:1607 Read of size 4 at addr ffff888065379610 by task kworker/u4:1/27
CPU: 1 PID: 27 Comm: kworker/u4:1 Not tainted 5.5.11 #2 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014 Workqueue: scsi_tmf_2 scmd_eh_abort_handler Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0xce/0x128 lib/dump_stack.c:118 print_address_description.constprop.4+0x21/0x3c0 mm/kasan/report.c:374 __kasan_report+0x153/0x1cb mm/kasan/report.c:506 kasan_report+0x12/0x20 mm/kasan/common.c:639 check_memory_region_inline mm/kasan/generic.c:185 [inline] check_memory_region+0x152/0x1b0 mm/kasan/generic.c:192 __kasan_check_read+0x11/0x20 mm/kasan/common.c:95 atomic_read include/asm-generic/atomic-instrumented.h:26 [inline] usb_hcd_unlink_urb+0x5f/0x170 drivers/usb/core/hcd.c:1607 usb_unlink_urb+0x72/0xb0 drivers/usb/core/urb.c:657 usb_sg_cancel+0x14e/0x290 drivers/usb/core/message.c:602 usb_stor_stop_transport+0x5e/0xa0 drivers/usb/storage/transport.c:937
This bug occurs when cancellation of the S-G transfer races with transfer completion. When that happens, usb_sg_cancel() may continue to access the transfer's URBs after usb_sg_wait() has freed them.
The bug is caused by the fact that usb_sg_cancel() does not take any sort of reference to the transfer, and so there is nothing to prevent the URBs from being deallocated while the routine is trying to use them. The fix is to take such a reference by incrementing the transfer's io->count field while the cancellation is in progres and decrementing it afterward. The transfer's URBs are not deallocated until io->complete is triggered, which happens when io->count reaches zero.
Signed-off-by: Alan Stern stern@rowland.harvard.edu Reported-and-tested-by: Kyungtae Kim kt0755@gmail.com CC: stable@vger.kernel.org Link: https://lore.kernel.org/r/Pine.LNX.4.44L0.2003281615140.14837-100000@netride... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/core/message.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
--- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -584,12 +584,13 @@ void usb_sg_cancel(struct usb_sg_request int i, retval;
spin_lock_irqsave(&io->lock, flags); - if (io->status) { + if (io->status || io->count == 0) { spin_unlock_irqrestore(&io->lock, flags); return; } /* shut everything down */ io->status = -ECONNRESET; + io->count++; /* Keep the request alive until we're done */ spin_unlock_irqrestore(&io->lock, flags);
for (i = io->entries - 1; i >= 0; --i) { @@ -603,6 +604,12 @@ void usb_sg_cancel(struct usb_sg_request dev_warn(&io->dev->dev, "%s, unlink --> %d\n", __func__, retval); } + + spin_lock_irqsave(&io->lock, flags); + io->count--; + if (!io->count) + complete(&io->complete); + spin_unlock_irqrestore(&io->lock, flags); } EXPORT_SYMBOL_GPL(usb_sg_cancel);
From: Alan Stern stern@rowland.harvard.edu
commit 9f952e26295d977dbfc6fedeaf8c4f112c818d37 upstream.
Commit 8099f58f1ecd ("USB: hub: Don't record a connect-change event during reset-resume") wasn't very well conceived. The problem it tried to fix was that if a connect-change event occurred while the system was asleep (such as a device disconnecting itself from the bus when it is suspended and then reconnecting when it resumes) requiring a reset-resume during the system wakeup transition, the hub port's change_bit entry would remain set afterward. This would cause the hub driver to believe another connect-change event had occurred after the reset-resume, which was wrong and would lead the driver to send unnecessary requests to the device (which could interfere with a firmware update).
The commit tried to fix this by not setting the change_bit during the wakeup. But this was the wrong thing to do; it means that when a device is unplugged while the system is asleep, the hub driver doesn't realize anything has happened: The change_bit flag which would tell it to handle the disconnect event is clear.
The commit needs to be reverted and the problem fixed in a different way. Fortunately an alternative solution was noted in the commit's Changelog: We can continue to set the change_bit entry in hub_activate() but then clear it when a reset-resume occurs. That way the the hub driver will see the change_bit when a device is disconnected but won't see it when the device is still present.
That's what this patch does.
Reported-and-tested-by: Peter Chen peter.chen@nxp.com Signed-off-by: Alan Stern stern@rowland.harvard.edu Fixes: 8099f58f1ecd ("USB: hub: Don't record a connect-change event during reset-resume") Tested-by: Paul Zimmerman pauldzim@gmail.com CC: stable@vger.kernel.org Link: https://lore.kernel.org/r/Pine.LNX.4.44L0.2004221602480.11262-100000@iolanth... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/core/hub.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
--- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1175,6 +1175,11 @@ static void hub_activate(struct usb_hub #ifdef CONFIG_PM udev->reset_resume = 1; #endif + /* Don't set the change_bits when the device + * was powered off. + */ + if (test_bit(port1, hub->power_bits)) + set_bit(port1, hub->change_bits);
} else { /* The power session is gone; tell hub_wq */ @@ -2939,6 +2944,15 @@ static int check_port_resume_type(struct if (portchange & USB_PORT_STAT_C_ENABLE) usb_clear_port_feature(hub->hdev, port1, USB_PORT_FEAT_C_ENABLE); + + /* + * Whatever made this reset-resume necessary may have + * turned on the port1 bit in hub->change_bits. But after + * a successful reset-resume we want the bit to be clear; + * if it was on it would indicate that something happened + * following the reset-resume. + */ + clear_bit(port1, hub->change_bits); }
return status;
From: Takashi Iwai tiwai@suse.de
commit 7686e3485253635c529cdd5f416fc640abaf076f upstream.
The error handling code in usX2Y_rate_set() may hit a potential NULL dereference when an error occurs before allocating all us->urb[]. Add a proper NULL check for fixing the corner case.
Reported-by: Lin Yi teroincn@gmail.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20200420075529.27203-1-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/usb/usx2y/usbusx2yaudio.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/sound/usb/usx2y/usbusx2yaudio.c +++ b/sound/usb/usx2y/usbusx2yaudio.c @@ -691,6 +691,8 @@ static int usX2Y_rate_set(struct usX2Yde us->submitted = 2*NOOF_SETRATE_URBS; for (i = 0; i < NOOF_SETRATE_URBS; ++i) { struct urb *urb = us->urb[i]; + if (!urb) + continue; if (urb->status) { if (!err) err = -ENODEV;
From: Xiyu Yang xiyuyang19@fudan.edu.cn
commit 59e1947ca09ebd1cae147c08c7c41f3141233c84 upstream.
snd_microii_spdif_default_get() invokes snd_usb_lock_shutdown(), which increases the refcount of the snd_usb_audio object "chip".
When snd_microii_spdif_default_get() returns, local variable "chip" becomes invalid, so the refcount should be decreased to keep refcount balanced.
The reference counting issue happens in several exception handling paths of snd_microii_spdif_default_get(). When those error scenarios occur such as usb_ifnum_to_if() returns NULL, the function forgets to decrease the refcnt increased by snd_usb_lock_shutdown(), causing a refcnt leak.
Fix this issue by jumping to "end" label when those error scenarios occur.
Fixes: 447d6275f0c2 ("ALSA: usb-audio: Add sanity checks for endpoint accesses") Signed-off-by: Xiyu Yang xiyuyang19@fudan.edu.cn Signed-off-by: Xin Tan tanxin.ctf@gmail.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/1587617711-13200-1-git-send-email-xiyuyang19@fudan... Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/usb/mixer_quirks.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
--- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -1519,11 +1519,15 @@ static int snd_microii_spdif_default_get
/* use known values for that card: interface#1 altsetting#1 */ iface = usb_ifnum_to_if(chip->dev, 1); - if (!iface || iface->num_altsetting < 2) - return -EINVAL; + if (!iface || iface->num_altsetting < 2) { + err = -EINVAL; + goto end; + } alts = &iface->altsetting[1]; - if (get_iface_desc(alts)->bNumEndpoints < 1) - return -EINVAL; + if (get_iface_desc(alts)->bNumEndpoints < 1) { + err = -EINVAL; + goto end; + } ep = get_endpoint(alts, 0)->bEndpointAddress;
err = snd_usb_ctl_msg(chip->dev,
From: Alexander Tsoy alexander@tsoy.me
commit 1c826792586f526a5a5cd21d55aad388f5bb0b23 upstream.
Many Focusrite devices supports a limited set of sample rates per altsetting. These includes audio interfaces with ADAT ports: - Scarlett 18i6, 18i8 1st gen, 18i20 1st gen; - Scarlett 18i8 2nd gen, 18i20 2nd gen; - Scarlett 18i8 3rd gen, 18i20 3rd gen; - Clarett 2Pre USB, 4Pre USB, 8Pre USB.
Maximum rate is exposed in the last 4 bytes of Format Type descriptor which has a non-standard bLength = 10.
Tested-by: Alexey Skobkin skobkin-ru@ya.ru Signed-off-by: Alexander Tsoy alexander@tsoy.me Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20200418175815.12211-1-alexander@tsoy.me Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/usb/format.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+)
--- a/sound/usb/format.c +++ b/sound/usb/format.c @@ -223,6 +223,52 @@ static int parse_audio_format_rates_v1(s }
/* + * Many Focusrite devices supports a limited set of sampling rates per + * altsetting. Maximum rate is exposed in the last 4 bytes of Format Type + * descriptor which has a non-standard bLength = 10. + */ +static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip, + struct audioformat *fp, + unsigned int rate) +{ + struct usb_interface *iface; + struct usb_host_interface *alts; + unsigned char *fmt; + unsigned int max_rate; + + iface = usb_ifnum_to_if(chip->dev, fp->iface); + if (!iface) + return true; + + alts = &iface->altsetting[fp->altset_idx]; + fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, + NULL, UAC_FORMAT_TYPE); + if (!fmt) + return true; + + if (fmt[0] == 10) { /* bLength */ + max_rate = combine_quad(&fmt[6]); + + /* Validate max rate */ + if (max_rate != 48000 && + max_rate != 96000 && + max_rate != 192000 && + max_rate != 384000) { + + usb_audio_info(chip, + "%u:%d : unexpected max rate: %u\n", + fp->iface, fp->altsetting, max_rate); + + return true; + } + + return rate <= max_rate; + } + + return true; +} + +/* * Helper function to walk the array of sample rate triplets reported by * the device. The problem is that we need to parse whole array first to * get to know how many sample rates we have to expect. @@ -258,6 +304,11 @@ static int parse_uac2_sample_rate_range( }
for (rate = min; rate <= max; rate += res) { + /* Filter out invalid rates on Focusrite devices */ + if (USB_ID_VENDOR(chip->usb_id) == 0x1235 && + !focusrite_valid_sample_rate(chip, fp, rate)) + goto skip_rate; + if (fp->rate_table) fp->rate_table[nr_rates] = rate; if (!fp->rate_min || rate < fp->rate_min) @@ -272,6 +323,7 @@ static int parse_uac2_sample_rate_range( break; }
+skip_rate: /* avoid endless loop */ if (res == 0) break;
From: Sean Christopherson sean.j.christopherson@intel.com
commit b6467ab142b708dd076f6186ca274f14af379c72 upstream.
Check that the resolved slot (somewhat confusingly named 'start') is a valid/allocated slot before doing the final comparison to see if the specified gfn resides in the associated slot. The resolved slot can be invalid if the binary search loop terminated because the search index was incremented beyond the number of used slots.
This bug has existed since the binary search algorithm was introduced, but went unnoticed because KVM statically allocated memory for the max number of slots, i.e. the access would only be truly out-of-bounds if all possible slots were allocated and the specified gfn was less than the base of the lowest memslot. Commit 36947254e5f98 ("KVM: Dynamically size memslot array based on number of used slots") eliminated the "all possible slots allocated" condition and made the bug embarrasingly easy to hit.
Fixes: 9c1a5d38780e6 ("kvm: optimize GFN to memslot lookup with large slots amount") Reported-by: syzbot+d889b59b2bb87d4047a2@syzkaller.appspotmail.com Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson sean.j.christopherson@intel.com Message-Id: 20200408064059.8957-2-sean.j.christopherson@intel.com Reviewed-by: Cornelia Huck cohuck@redhat.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- include/linux/kvm_host.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -934,7 +934,7 @@ search_memslots(struct kvm_memslots *slo start = slot + 1; }
- if (gfn >= memslots[start].base_gfn && + if (start < slots->used_slots && gfn >= memslots[start].base_gfn && gfn < memslots[start].base_gfn + memslots[start].npages) { atomic_set(&slots->lru_slot, start); return &memslots[start];
From: Uros Bizjak ubizjak@gmail.com
commit fb56baae5ea509e63c2a068d66a4d8ea91969fca upstream.
There is no reason to limit the use of do_machine_check to 64bit targets. MCE handling works for both target familes.
Cc: Paolo Bonzini pbonzini@redhat.com Cc: Sean Christopherson sean.j.christopherson@intel.com Cc: stable@vger.kernel.org Fixes: a0861c02a981 ("KVM: Add VT-x machine check support") Signed-off-by: Uros Bizjak ubizjak@gmail.com Message-Id: 20200414071414.45636-1-ubizjak@gmail.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/x86/kvm/vmx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -5441,7 +5441,7 @@ static int handle_rmode_exception(struct */ static void kvm_machine_check(void) { -#if defined(CONFIG_X86_MCE) && defined(CONFIG_X86_64) +#if defined(CONFIG_X86_MCE) struct pt_regs regs = { .cs = 3, /* Fake ring 3 no matter what the guest ran on */ .flags = X86_EFLAGS_IF,
From: Andrew Melnychenko andrew@daynix.com
commit 9a9fc42b86c06120744555fea43fdcabe297c656 upstream.
If there is a lot(more then 16) of virtio-console devices or virtio_console module is reloaded - buffers 'vtermnos' and 'cons_ops' are overflowed. In older kernels it overruns spinlock which leads to kernel freezing: https://bugzilla.redhat.com/show_bug.cgi?id=1786239
To reproduce the issue, you can try simple script that loads/unloads module. Something like this: while [ 1 ] do modprobe virtio_console sleep 2 modprobe -r virtio_console sleep 2 done
Description of problem: Guest get 'Call Trace' when loading module "virtio_console" and unloading it frequently - clearly reproduced on kernel-4.18.0:
[ 81.498208] ------------[ cut here ]------------ [ 81.499263] pvqspinlock: lock 0xffffffff92080020 has corrupted value 0xc0774ca0! [ 81.501000] WARNING: CPU: 0 PID: 785 at kernel/locking/qspinlock_paravirt.h:500 __pv_queued_spin_unlock_slowpath+0xc0/0xd0 [ 81.503173] Modules linked in: virtio_console fuse xt_CHECKSUM ipt_MASQUERADE xt_conntrack ipt_REJECT nft_counter nf_nat_tftp nft_objref nf_conntrack_tftp tun bridge stp llc nft_fib_inet nft_fib_ipv4 nft_fib_ipv6 nft_fib nft_reject_inet nf_reject_ipv4 nf_reject_ipv6 nft_reject nft_ct nf_tables_set nft_chain_nat_ipv6 nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 nft_chain_route_ipv6 nft_chain_nat_ipv4 nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack nft_chain_route_ipv4 ip6_tables nft_compat ip_set nf_tables nfnetlink sunrpc bochs_drm drm_vram_helper ttm drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops drm i2c_piix4 pcspkr crct10dif_pclmul crc32_pclmul joydev ghash_clmulni_intel ip_tables xfs libcrc32c sd_mod sg ata_generic ata_piix virtio_net libata crc32c_intel net_failover failover serio_raw virtio_scsi dm_mirror dm_region_hash dm_log dm_mod [last unloaded: virtio_console] [ 81.517019] CPU: 0 PID: 785 Comm: kworker/0:2 Kdump: loaded Not tainted 4.18.0-167.el8.x86_64 #1 [ 81.518639] Hardware name: Red Hat KVM, BIOS 1.12.0-5.scrmod+el8.2.0+5159+d8aa4d83 04/01/2014 [ 81.520205] Workqueue: events control_work_handler [virtio_console] [ 81.521354] RIP: 0010:__pv_queued_spin_unlock_slowpath+0xc0/0xd0 [ 81.522450] Code: 07 00 48 63 7a 10 e8 bf 64 f5 ff 66 90 c3 8b 05 e6 cf d6 01 85 c0 74 01 c3 8b 17 48 89 fe 48 c7 c7 38 4b 29 91 e8 3a 6c fa ff <0f> 0b c3 0f 0b 90 90 90 90 90 90 90 90 90 90 90 0f 1f 44 00 00 48 [ 81.525830] RSP: 0018:ffffb51a01ffbd70 EFLAGS: 00010282 [ 81.526798] RAX: 0000000000000000 RBX: 0000000000000010 RCX: 0000000000000000 [ 81.528110] RDX: ffff9e66f1826480 RSI: ffff9e66f1816a08 RDI: ffff9e66f1816a08 [ 81.529437] RBP: ffffffff9153ff10 R08: 000000000000026c R09: 0000000000000053 [ 81.530732] R10: 0000000000000000 R11: ffffb51a01ffbc18 R12: ffff9e66cd682200 [ 81.532133] R13: ffffffff9153ff10 R14: ffff9e6685569500 R15: ffff9e66cd682000 [ 81.533442] FS: 0000000000000000(0000) GS:ffff9e66f1800000(0000) knlGS:0000000000000000 [ 81.534914] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 81.535971] CR2: 00005624c55b14d0 CR3: 00000003a023c000 CR4: 00000000003406f0 [ 81.537283] Call Trace: [ 81.537763] __raw_callee_save___pv_queued_spin_unlock_slowpath+0x11/0x20 [ 81.539011] .slowpath+0x9/0xe [ 81.539585] hvc_alloc+0x25e/0x300 [ 81.540237] init_port_console+0x28/0x100 [virtio_console] [ 81.541251] handle_control_message.constprop.27+0x1c4/0x310 [virtio_console] [ 81.542546] control_work_handler+0x70/0x10c [virtio_console] [ 81.543601] process_one_work+0x1a7/0x3b0 [ 81.544356] worker_thread+0x30/0x390 [ 81.545025] ? create_worker+0x1a0/0x1a0 [ 81.545749] kthread+0x112/0x130 [ 81.546358] ? kthread_flush_work_fn+0x10/0x10 [ 81.547183] ret_from_fork+0x22/0x40 [ 81.547842] ---[ end trace aa97649bd16c8655 ]--- [ 83.546539] general protection fault: 0000 [#1] SMP NOPTI [ 83.547422] CPU: 5 PID: 3225 Comm: modprobe Kdump: loaded Tainted: G W --------- - - 4.18.0-167.el8.x86_64 #1 [ 83.549191] Hardware name: Red Hat KVM, BIOS 1.12.0-5.scrmod+el8.2.0+5159+d8aa4d83 04/01/2014 [ 83.550544] RIP: 0010:__pv_queued_spin_lock_slowpath+0x19a/0x2a0 [ 83.551504] Code: c4 c1 ea 12 41 be 01 00 00 00 4c 8d 6d 14 41 83 e4 03 8d 42 ff 49 c1 e4 05 48 98 49 81 c4 40 a5 02 00 4c 03 24 c5 60 48 34 91 <49> 89 2c 24 b8 00 80 00 00 eb 15 84 c0 75 0a 41 0f b6 54 24 14 84 [ 83.554449] RSP: 0018:ffffb51a0323fdb0 EFLAGS: 00010202 [ 83.555290] RAX: 000000000000301c RBX: ffffffff92080020 RCX: 0000000000000001 [ 83.556426] RDX: 000000000000301d RSI: 0000000000000000 RDI: 0000000000000000 [ 83.557556] RBP: ffff9e66f196a540 R08: 000000000000028a R09: ffff9e66d2757788 [ 83.558688] R10: 0000000000000000 R11: 0000000000000000 R12: 646e61725f770b07 [ 83.559821] R13: ffff9e66f196a554 R14: 0000000000000001 R15: 0000000000180000 [ 83.560958] FS: 00007fd5032e8740(0000) GS:ffff9e66f1940000(0000) knlGS:0000000000000000 [ 83.562233] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 83.563149] CR2: 00007fd5022b0da0 CR3: 000000038c334000 CR4: 00000000003406e0
Signed-off-by: Andrew Melnychenko andrew@daynix.com Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/20200414191503.3471783-1-andrew@daynix.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/tty/hvc/hvc_console.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-)
--- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c @@ -289,10 +289,6 @@ int hvc_instantiate(uint32_t vtermno, in vtermnos[index] = vtermno; cons_ops[index] = ops;
- /* reserve all indices up to and including this index */ - if (last_hvc < index) - last_hvc = index; - /* check if we need to re-register the kernel console */ hvc_check_console(index);
@@ -896,13 +892,22 @@ struct hvc_struct *hvc_alloc(uint32_t vt cons_ops[i] == hp->ops) break;
- /* no matching slot, just use a counter */ - if (i >= MAX_NR_HVC_CONSOLES) - i = ++last_hvc; + if (i >= MAX_NR_HVC_CONSOLES) { + + /* find 'empty' slot for console */ + for (i = 0; i < MAX_NR_HVC_CONSOLES && vtermnos[i] != -1; i++) { + } + + /* no matching slot, just use a counter */ + if (i == MAX_NR_HVC_CONSOLES) + i = ++last_hvc + MAX_NR_HVC_CONSOLES; + }
hp->index = i; - cons_ops[i] = ops; - vtermnos[i] = vtermno; + if (i < MAX_NR_HVC_CONSOLES) { + cons_ops[i] = ops; + vtermnos[i] = vtermno; + }
list_add_tail(&(hp->next), &hvc_structs); spin_unlock(&hvc_structs_lock);
From: Jiri Slaby jslaby@suse.cz
commit 7127d24372bf23675a36edc64d092dc7fd92ebe8 upstream.
init_r_port can access pc104 array out of bounds. pc104 is a 2D array defined to have 4 members. Each member has 8 submembers. * we can have more than 4 (PCI) boards, i.e. [board] can be OOB * line is not modulo-ed by anything, so the first line on the second board can be 4, on the 3rd 12 or alike (depending on previously registered boards). It's zero only on the first line of the first board. So even [line] can be OOB, quite soon (with the 2nd registered board already).
This code is broken for ages, so just avoid the OOB accesses and don't try to fix it as we would need to find out the correct line number. Use the default: RS232, if we are out.
Generally, if anyone needs to set the interface types, a module parameter is past the last thing that should be used for this purpose. The parameters' description says it's for ISA cards anyway.
Signed-off-by: Jiri Slaby jslaby@suse.cz Cc: stable stable@vger.kernel.org Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Link: https://lore.kernel.org/r/20200417105959.15201-2-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/tty/rocket.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-)
--- a/drivers/tty/rocket.c +++ b/drivers/tty/rocket.c @@ -645,18 +645,21 @@ static void init_r_port(int board, int a info->port.ops = &rocket_port_ops; init_completion(&info->close_wait); info->flags &= ~ROCKET_MODE_MASK; - switch (pc104[board][line]) { - case 422: - info->flags |= ROCKET_MODE_RS422; - break; - case 485: - info->flags |= ROCKET_MODE_RS485; - break; - case 232: - default: + if (board < ARRAY_SIZE(pc104) && line < ARRAY_SIZE(pc104_1)) + switch (pc104[board][line]) { + case 422: + info->flags |= ROCKET_MODE_RS422; + break; + case 485: + info->flags |= ROCKET_MODE_RS485; + break; + case 232: + default: + info->flags |= ROCKET_MODE_RS232; + break; + } + else info->flags |= ROCKET_MODE_RS232; - break; - }
info->intmask = RXF_TRIG | TXFIFO_MT | SRC_INT | DELTA_CD | DELTA_CTS | DELTA_DSR; if (sInitChan(ctlp, &info->channel, aiop, chan) == 0) {
From: Alan Stern stern@rowland.harvard.edu
commit 94f9c8c3c404ee1f7aaff81ad4f24aec4e34a78b upstream.
Cyril Roelandt reports that his JMicron JMS566 USB-SATA bridge fails to handle WRITE commands with the FUA bit set, even though it claims to support FUA. (Oddly enough, a later version of the same bridge, version 2.03 as opposed to 1.14, doesn't claim to support FUA. Also oddly, the bridge _does_ support FUA when using the UAS transport instead of the Bulk-Only transport -- but this device was blacklisted for uas in commit bc3bdb12bbb3 ("usb-storage: Disable UAS on JMicron SATA enclosure") for apparently unrelated reasons.)
This patch adds a usb-storage unusual_devs entry with the BROKEN_FUA flag. This allows the bridge to work properly with usb-storage.
Reported-and-tested-by: Cyril Roelandt tipecaml@gmail.com Signed-off-by: Alan Stern stern@rowland.harvard.edu CC: stable@vger.kernel.org Link: https://lore.kernel.org/r/Pine.LNX.4.44L0.2004221613110.11262-100000@iolanth... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/storage/unusual_devs.h | 7 +++++++ 1 file changed, 7 insertions(+)
--- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -2208,6 +2208,13 @@ UNUSUAL_DEV( 0x3340, 0xffff, 0x0000, 0x USB_SC_DEVICE,USB_PR_DEVICE,NULL, US_FL_MAX_SECTORS_64 ),
+/* Reported by Cyril Roelandt tipecaml@gmail.com */ +UNUSUAL_DEV( 0x357d, 0x7788, 0x0114, 0x0114, + "JMicron", + "USB to ATA/ATAPI Bridge", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_BROKEN_FUA ), + /* Reported by Andrey Rahmatullin wrar@altlinux.org */ UNUSUAL_DEV( 0x4102, 0x1020, 0x0100, 0x0100, "iRiver",
From: Paul Moore paul@paul-moore.com
commit 763dafc520add02a1f4639b500c509acc0ea8e5b upstream.
Commit 756125289285 ("audit: always check the netlink payload length in audit_receive_msg()") fixed a number of missing message length checks, but forgot to check the length of userspace generated audit records. The good news is that you need CAP_AUDIT_WRITE to submit userspace audit records, which is generally only given to trusted processes, so the impact should be limited.
Cc: stable@vger.kernel.org Fixes: 756125289285 ("audit: always check the netlink payload length in audit_receive_msg()") Reported-by: syzbot+49e69b4d71a420ceda3e@syzkaller.appspotmail.com Signed-off-by: Paul Moore paul@paul-moore.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- kernel/audit.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/kernel/audit.c +++ b/kernel/audit.c @@ -919,6 +919,9 @@ static int audit_receive_msg(struct sk_b case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2: if (!audit_enabled && msg_type != AUDIT_USER_AVC) return 0; + /* exit early if there isn't at least one character to print */ + if (data_len < 2) + return -EINVAL;
err = audit_filter_user(msg_type); if (err == 1) { /* match or error */
From: Gyeongtaek Lee gt82.lee@samsung.com
commit ebf1474745b4373fdde0fcf32d9d1f369b50b212 upstream.
snd_soc_dapm_kcontrol widget which is created by autodisable control should contain correct on_val, mask and shift because it is set when the widget is powered and changed value is applied on registers by following code in dapm_seq_run_coalesced().
mask |= w->mask << w->shift; if (w->power) value |= w->on_val << w->shift; else value |= w->off_val << w->shift;
Shift on the mask in dapm_kcontrol_data_alloc() is removed to prevent double shift. And, on_val in dapm_kcontrol_set_value() is modified to get correct value in the dapm_seq_run_coalesced().
Signed-off-by: Gyeongtaek Lee gt82.lee@samsung.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/000001d61537%24b212f620%241638e260%24@samsung.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/soc/soc-dapm.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-)
--- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -384,7 +384,7 @@ static int dapm_kcontrol_data_alloc(stru
memset(&template, 0, sizeof(template)); template.reg = e->reg; - template.mask = e->mask << e->shift_l; + template.mask = e->mask; template.shift = e->shift_l; template.off_val = snd_soc_enum_item_to_val(e, 0); template.on_val = template.off_val; @@ -510,8 +510,22 @@ static bool dapm_kcontrol_set_value(cons if (data->value == value) return false;
- if (data->widget) - data->widget->on_val = value; + if (data->widget) { + switch (dapm_kcontrol_get_wlist(kcontrol)->widgets[0]->id) { + case snd_soc_dapm_switch: + case snd_soc_dapm_mixer: + case snd_soc_dapm_mixer_named_ctl: + data->widget->on_val = value & data->widget->mask; + break; + case snd_soc_dapm_demux: + case snd_soc_dapm_mux: + data->widget->on_val = value >> data->widget->shift; + break; + default: + data->widget->on_val = value; + break; + } + }
data->value = value;
From: Ahmad Fatoum a.fatoum@pengutronix.de
commit f1baca8896ae18e12c45552a4c4ae2086aa7e02c upstream.
512a928affd5 ("ARM: imx: build v7_cpu_resume() unconditionally") introduced an unintended linker error for i.MX6 configurations that have ARM_CPU_SUSPEND=n which can happen if neither CONFIG_PM, CONFIG_CPU_IDLE, nor ARM_PSCI_FW are selected.
Fix this by having v7_cpu_resume() compiled only when cpu_resume() it calls is available as well.
The C declaration for the function remains unguarded to avoid future code inadvertently using a stub and introducing a regression to the bug the original commit fixed.
Cc: stable@vger.kernel.org Fixes: 512a928affd5 ("ARM: imx: build v7_cpu_resume() unconditionally") Reported-by: Clemens Gruber clemens.gruber@pqgruber.com Signed-off-by: Ahmad Fatoum a.fatoum@pengutronix.de Tested-by: Roland Hieber rhi@pengutronix.de Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/arm/mach-imx/Makefile | 2 ++ 1 file changed, 2 insertions(+)
--- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -91,8 +91,10 @@ AFLAGS_suspend-imx6.o :=-Wa,-march=armv7 obj-$(CONFIG_SOC_IMX6) += suspend-imx6.o obj-$(CONFIG_SOC_IMX53) += suspend-imx53.o endif +ifeq ($(CONFIG_ARM_CPU_SUSPEND),y) AFLAGS_resume-imx6.o :=-Wa,-march=armv7-a obj-$(CONFIG_SOC_IMX6) += resume-imx6.o +endif obj-$(CONFIG_SOC_IMX6) += pm-imx6.o
obj-$(CONFIG_SOC_IMX50) += mach-imx50.o
From: Ian Abbott abbotti@mev.co.uk
commit ed87d33ddbcd9a1c3b5ae87995da34e6f51a862c upstream.
The DT2815 analog output command is 16 bits wide, consisting of the 12-bit sample value in bits 15 to 4, the channel number in bits 3 to 1, and a voltage or current selector in bit 0. Both bytes of the 16-bit command need to be written in turn to a single 8-bit data register. However, the driver currently only writes the low 8-bits. It is broken and appears to have always been broken.
Electronic copies of the DT2815 User's Manual seem impossible to find online, but looking at the source code, a best guess for the sequence the driver intended to use to write the analog output command is as follows:
1. Wait for the status register to read 0x00. 2. Write the low byte of the command to the data register. 3. Wait for the status register to read 0x80. 4. Write the high byte of the command to the data register.
Step 4 is missing from the driver. Add step 4 to (hopefully) fix the driver.
Also add a "FIXME" comment about setting bit 0 of the low byte of the command. Supposedly, it is used to choose between voltage output and current output, but the current driver always sets it to 1.
Signed-off-by: Ian Abbott abbotti@mev.co.uk Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/20200406142015.126982-1-abbotti@mev.co.uk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/staging/comedi/drivers/dt2815.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/staging/comedi/drivers/dt2815.c +++ b/drivers/staging/comedi/drivers/dt2815.c @@ -101,6 +101,7 @@ static int dt2815_ao_insn(struct comedi_ int ret;
for (i = 0; i < insn->n; i++) { + /* FIXME: lo bit 0 chooses voltage output or current output */ lo = ((data[i] & 0x0f) << 4) | (chan << 1) | 0x01; hi = (data[i] & 0xff0) >> 4;
@@ -114,6 +115,8 @@ static int dt2815_ao_insn(struct comedi_ if (ret) return ret;
+ outb(hi, dev->iobase + DT2815_DATA); + devpriv->ao_readback[chan] = data[i]; } return i;
From: Xiyu Yang xiyuyang19@fudan.edu.cn
commit 332e0e17ad49e084b7db670ef43b5eb59abd9e34 upstream.
comedi_open() invokes comedi_dev_get_from_minor(), which returns a reference of the COMEDI device to "dev" with increased refcount.
When comedi_open() returns, "dev" becomes invalid, so the refcount should be decreased to keep refcount balanced.
The reference counting issue happens in one exception handling path of comedi_open(). When "cfp" allocation is failed, the refcnt increased by comedi_dev_get_from_minor() is not decreased, causing a refcnt leak.
Fix this issue by calling comedi_dev_put() on this error path when "cfp" allocation is failed.
Fixes: 20f083c07565 ("staging: comedi: prepare support for per-file read and write subdevices") Signed-off-by: Xiyu Yang xiyuyang19@fudan.edu.cn Cc: stable stable@vger.kernel.org Signed-off-by: Xin Tan tanxin.ctf@gmail.com Signed-off-by: Ian Abbott abbotti@mev.co.uk Link: https://lore.kernel.org/r/1587361459-83622-1-git-send-email-xiyuyang19@fudan... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/staging/comedi/comedi_fops.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -2592,8 +2592,10 @@ static int comedi_open(struct inode *ino }
cfp = kzalloc(sizeof(*cfp), GFP_KERNEL); - if (!cfp) + if (!cfp) { + comedi_dev_put(dev); return -ENOMEM; + }
cfp->dev = dev;
From: Malcolm Priestley tvboxspy@gmail.com
commit 09057742af98a39ebffa27fac4f889dc873132de upstream.
The drivers TBTT counter is not synchronized with mac80211 timestamp.
Reorder the functions and use vnt_update_next_tbtt to do the final synchronize.
Fixes: c15158797df6 ("staging: vt6656: implement TSF counter") Cc: stable stable@vger.kernel.org Signed-off-by: Malcolm Priestley tvboxspy@gmail.com Link: https://lore.kernel.org/r/375d0b25-e8bc-c8f7-9b10-6cc705d486ee@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/staging/vt6656/main_usb.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
--- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -762,12 +762,15 @@ static void vnt_bss_info_changed(struct vnt_mac_reg_bits_on(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
- vnt_adjust_tsf(priv, conf->beacon_rate->hw_value, - conf->sync_tsf, priv->current_tsf); - vnt_mac_set_beacon_interval(priv, conf->beacon_int);
vnt_reset_next_tbtt(priv, conf->beacon_int); + + vnt_adjust_tsf(priv, conf->beacon_rate->hw_value, + conf->sync_tsf, priv->current_tsf); + + vnt_update_next_tbtt(priv, + conf->sync_tsf, conf->beacon_int); } else { vnt_clear_current_tsf(priv);
From: Malcolm Priestley tvboxspy@gmail.com
commit ea81c3486442f4643fc9825a2bb1b430b829bccd upstream.
conf.listen_interval can sometimes be zero causing wake_up_count to wrap around up to many beacons too late causing CTRL-EVENT-BEACON-LOSS as in.
wpa_supplicant[795]: message repeated 45 times: [..CTRL-EVENT-BEACON-LOSS ]
Fixes: 43c93d9bf5e2 ("staging: vt6656: implement power saving code.") Cc: stable stable@vger.kernel.org Signed-off-by: Malcolm Priestley tvboxspy@gmail.com Link: https://lore.kernel.org/r/fce47bb5-7ca6-7671-5094-5c6107302f2b@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/staging/vt6656/int.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/staging/vt6656/int.c +++ b/drivers/staging/vt6656/int.c @@ -157,7 +157,8 @@ void vnt_int_process_data(struct vnt_pri priv->wake_up_count = priv->hw->conf.listen_interval;
- --priv->wake_up_count; + if (priv->wake_up_count) + --priv->wake_up_count;
/* Turn on wake up to listen next beacon */ if (priv->wake_up_count == 1)
From: Oliver Neukum oneukum@suse.com
commit 5963dec98dc52d52476390485f07a29c30c6a582 upstream.
Once a device is gone, the internal state does not matter anymore. There is no need to spam the logs.
Signed-off-by: Oliver Neukum oneukum@suse.com Cc: stable stable@vger.kernel.org Fixes: 326349f824619 ("uas: add dead request list") Link: https://lore.kernel.org/r/20200415141750.811-1-oneukum@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/storage/uas.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -191,6 +191,9 @@ static void uas_log_cmd_state(struct scs struct uas_cmd_info *ci = (void *)&cmnd->SCp; struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
+ if (status == -ENODEV) /* too late */ + return; + scmd_printk(KERN_INFO, cmnd, "%s %d uas-tag %d inflight:%s%s%s%s%s%s%s%s%s%s%s%s ", prefix, status, cmdinfo->uas_tag,
From: Oliver Neukum oneukum@suse.com
commit f6cc6093a729ede1ff5658b493237c42b82ba107 upstream.
A SCSI error handler and block runtime PM must not allocate memory with GFP_KERNEL. Furthermore they must not wait for tasks allocating memory with GFP_KERNEL. That means that they cannot share a workqueue with arbitrary tasks.
Fix this for UAS using a private workqueue.
Signed-off-by: Oliver Neukum oneukum@suse.com Fixes: f9dc024a2da1f ("uas: pre_reset and suspend: Fix a few races") Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/20200415141750.811-2-oneukum@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/storage/uas.c | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-)
--- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -82,6 +82,19 @@ static void uas_free_streams(struct uas_ static void uas_log_cmd_state(struct scsi_cmnd *cmnd, const char *prefix, int status);
+/* + * This driver needs its own workqueue, as we need to control memory allocation. + * + * In the course of error handling and power management uas_wait_for_pending_cmnds() + * needs to flush pending work items. In these contexts we cannot allocate memory + * by doing block IO as we would deadlock. For the same reason we cannot wait + * for anything allocating memory not heeding these constraints. + * + * So we have to control all work items that can be on the workqueue we flush. + * Hence we cannot share a queue and need our own. + */ +static struct workqueue_struct *workqueue; + static void uas_do_work(struct work_struct *work) { struct uas_dev_info *devinfo = @@ -110,7 +123,7 @@ static void uas_do_work(struct work_stru if (!err) cmdinfo->state &= ~IS_IN_WORK_LIST; else - schedule_work(&devinfo->work); + queue_work(workqueue, &devinfo->work); } out: spin_unlock_irqrestore(&devinfo->lock, flags); @@ -135,7 +148,7 @@ static void uas_add_work(struct uas_cmd_
lockdep_assert_held(&devinfo->lock); cmdinfo->state |= IS_IN_WORK_LIST; - schedule_work(&devinfo->work); + queue_work(workqueue, &devinfo->work); }
static void uas_zap_pending(struct uas_dev_info *devinfo, int result) @@ -1176,7 +1189,31 @@ static struct usb_driver uas_driver = { .id_table = uas_usb_ids, };
-module_usb_driver(uas_driver); +static int __init uas_init(void) +{ + int rv; + + workqueue = alloc_workqueue("uas", WQ_MEM_RECLAIM, 0); + if (!workqueue) + return -ENOMEM; + + rv = usb_register(&uas_driver); + if (rv) { + destroy_workqueue(workqueue); + return -ENOMEM; + } + + return 0; +} + +static void __exit uas_exit(void) +{ + usb_deregister(&uas_driver); + destroy_workqueue(workqueue); +} + +module_init(uas_init); +module_exit(uas_exit);
MODULE_LICENSE("GPL"); MODULE_AUTHOR(
From: Udipto Goswami ugoswami@codeaurora.org
commit 1c2e54fbf1da5e5445a0ab132c862b02ccd8d230 upstream.
For userspace functions using OS Descriptors, if a function also supplies Extended Property descriptors currently the counts and lengths stored in the ms_os_descs_ext_prop_{count,name_len,data_len} variables are not getting reset to 0 during an unbind or when the epfiles are closed. If the same function is re-bound and the descriptors are re-written, this results in those count/length variables to monotonically increase causing the VLA allocation in _ffs_func_bind() to grow larger and larger at each bind/unbind cycle and eventually fail to allocate.
Fix this by clearing the ms_os_descs_ext_prop count & lengths to 0 in ffs_data_reset().
Fixes: f0175ab51993 ("usb: gadget: f_fs: OS descriptors support") Cc: stable@vger.kernel.org Signed-off-by: Udipto Goswami ugoswami@codeaurora.org Signed-off-by: Sriharsha Allenki sallenki@codeaurora.org Reviewed-by: Manu Gautam mgautam@codeaurora.org Link: https://lore.kernel.org/r/20200402044521.9312-1-sallenki@codeaurora.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/gadget/function/f_fs.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -1511,6 +1511,10 @@ static void ffs_data_reset(struct ffs_da ffs->state = FFS_READ_DESCRIPTORS; ffs->setup_state = FFS_NO_SETUP; ffs->flags = 0; + + ffs->ms_os_descs_ext_prop_count = 0; + ffs->ms_os_descs_ext_prop_name_len = 0; + ffs->ms_os_descs_ext_prop_data_len = 0; }
From: Clement Leger cleger@kalray.eu
commit 00a0eec59ddbb1ce966b19097d8a8d2f777e726a upstream.
Index of rvring is computed using pointer arithmetic. However, since rvring->rvdev->vring is the base of the vring array, computation of rvring idx should be reversed. It previously lead to writing at negative indices in the resource table.
Signed-off-by: Clement Leger cleger@kalray.eu Link: https://lore.kernel.org/r/20191004073736.8327-1-cleger@kalray.eu Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Cc: Doug Anderson dianders@chromium.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/remoteproc/remoteproc_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -288,7 +288,7 @@ void rproc_free_vring(struct rproc_vring { int size = PAGE_ALIGN(vring_size(rvring->len, rvring->align)); struct rproc *rproc = rvring->rvdev->rproc; - int idx = rvring->rvdev->vring - rvring; + int idx = rvring - rvring->rvdev->vring; struct fw_rsc_vdev *rsc;
dma_free_coherent(rproc->dev.parent, size, rvring->va, rvring->dma);
From: Xin Long lucien.xin@gmail.com
commit a8dd397903a6e57157f6265911f7d35681364427 upstream.
Commit d04adf1b3551 ("sctp: reset owner sk for data chunks on out queues when migrating a sock") made a mistake that using 'list' as the param of list_for_each_entry to traverse the retransmit, sacked and abandoned queues, while chunks are using 'transmitted_list' to link into these queues.
It could cause NULL dereference panic if there are chunks in any of these queues when peeling off one asoc.
So use the chunk member 'transmitted_list' instead in this patch.
Fixes: d04adf1b3551 ("sctp: reset owner sk for data chunks on out queues when migrating a sock") Signed-off-by: Xin Long lucien.xin@gmail.com Acked-by: Marcelo Ricardo Leitner marcelo.leitner@gmail.com Acked-by: Neil Horman nhorman@tuxdriver.com Signed-off-by: David S. Miller davem@davemloft.net Cc: Guenter Roeck linux@roeck-us.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- net/sctp/socket.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -185,13 +185,13 @@ static void sctp_for_each_tx_datachunk(s list_for_each_entry(chunk, &t->transmitted, transmitted_list) cb(chunk);
- list_for_each_entry(chunk, &q->retransmit, list) + list_for_each_entry(chunk, &q->retransmit, transmitted_list) cb(chunk);
- list_for_each_entry(chunk, &q->sacked, list) + list_for_each_entry(chunk, &q->sacked, transmitted_list) cb(chunk);
- list_for_each_entry(chunk, &q->abandoned, list) + list_for_each_entry(chunk, &q->abandoned, transmitted_list) cb(chunk);
list_for_each_entry(chunk, &q->out_chunk_list, list)
From: Miklos Szeredi mszeredi@redhat.com
commit 2d84a2d19b6150c6dbac1e6ebad9c82e4c123772 upstream.
In current fuse_drop_waiting() implementation it's possible that fuse_wait_aborted() will not be woken up in the unlikely case that fuse_abort_conn() + fuse_wait_aborted() runs in between checking fc->connected and calling atomic_dec(&fc->num_waiting).
Do the atomic_dec_and_test() unconditionally, which also provides the necessary barrier against reordering with the fc->connected check.
The explicit smp_mb() in fuse_wait_aborted() is not actually needed, since the spin_unlock() in fuse_abort_conn() provides the necessary RELEASE barrier after resetting fc->connected. However, this is not a performance sensitive path, and adding the explicit barrier makes it easier to document.
Signed-off-by: Miklos Szeredi mszeredi@redhat.com Fixes: b8f95e5d13f5 ("fuse: umount should wait for all requests") Cc: stable@vger.kernel.org #v4.19 Cc: Guenter Roeck linux@roeck-us.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/fuse/dev.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
--- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -145,9 +145,13 @@ static bool fuse_block_alloc(struct fuse
static void fuse_drop_waiting(struct fuse_conn *fc) { - if (fc->connected) { - atomic_dec(&fc->num_waiting); - } else if (atomic_dec_and_test(&fc->num_waiting)) { + /* + * lockess check of fc->connected is okay, because atomic_dec_and_test() + * provides a memory barrier mached with the one in fuse_wait_aborted() + * to ensure no wake-up is missed. + */ + if (atomic_dec_and_test(&fc->num_waiting) && + !READ_ONCE(fc->connected)) { /* wake up aborters */ wake_up_all(&fc->blocked_waitq); } @@ -2222,6 +2226,8 @@ EXPORT_SYMBOL_GPL(fuse_abort_conn);
void fuse_wait_aborted(struct fuse_conn *fc) { + /* matches implicit memory barrier in fuse_drop_waiting() */ + smp_mb(); wait_event(fc->blocked_waitq, atomic_read(&fc->num_waiting) == 0); }
From: Liu Jian liujian56@huawei.com
commit d9b8a67b3b95a5c5aae6422b8113adc1c2485f2b upstream.
In function do_write_buffer(), in the for loop, there is a case chip_ready() returns 1 while chip_good() returns 0, so it never break the loop. To fix this, chip_good() is enough and it should timeout if it stay bad for a while.
Fixes: dfeae1073583("mtd: cfi_cmdset_0002: Change write buffer to check correct value") Signed-off-by: Yi Huaijie yihuaijie@huawei.com Signed-off-by: Liu Jian liujian56@huawei.com Reviewed-by: Tokunori Ikegami ikegami_to@yahoo.co.jp Signed-off-by: Richard Weinberger richard@nod.at Cc: Guenter Roeck linux@roeck-us.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/mtd/chips/cfi_cmdset_0002.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -1881,7 +1881,11 @@ static int __xipram do_write_buffer(stru continue; }
- if (time_after(jiffies, timeo) && !chip_ready(map, adr)) + /* + * We check "time_after" and "!chip_good" before checking "chip_good" to avoid + * the failure due to scheduling. + */ + if (time_after(jiffies, timeo) && !chip_good(map, adr, datum)) break;
if (chip_good(map, adr, datum)) {
From: Nathan Chancellor natechancellor@gmail.com
commit 09b04abb70f096333bef6bc95fa600b662e7ee13 upstream.
When building with Clang + -Wtautological-pointer-compare:
drivers/usb/gadget/udc/bdc/bdc_ep.c:543:28: warning: comparison of address of 'req->queue' equal to a null pointer is always false [-Wtautological-pointer-compare] if (req == NULL || &req->queue == NULL || &req->usb_req == NULL) ~~~~~^~~~~ ~~~~ drivers/usb/gadget/udc/bdc/bdc_ep.c:543:51: warning: comparison of address of 'req->usb_req' equal to a null pointer is always false [-Wtautological-pointer-compare] if (req == NULL || &req->queue == NULL || &req->usb_req == NULL) ~~~~~^~~~~~~ ~~~~ 2 warnings generated.
As it notes, these statements will always evaluate to false so remove them.
Fixes: efed421a94e6 ("usb: gadget: Add UDC driver for Broadcom USB3.0 device controller IP BDC") Link: https://github.com/ClangBuiltLinux/linux/issues/749 Signed-off-by: Nathan Chancellor natechancellor@gmail.com Signed-off-by: Felipe Balbi balbi@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/gadget/udc/bdc/bdc_ep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/usb/gadget/udc/bdc/bdc_ep.c +++ b/drivers/usb/gadget/udc/bdc/bdc_ep.c @@ -546,7 +546,7 @@ static void bdc_req_complete(struct bdc_ { struct bdc *bdc = ep->bdc;
- if (req == NULL || &req->queue == NULL || &req->usb_req == NULL) + if (req == NULL) return;
dev_dbg(bdc->dev, "%s ep:%s status:%d\n", __func__, ep->name, status);
From: Jason Gunthorpe jgg@mellanox.com
commit c799fca8baf18d1bbbbad6c3b736eefbde8bdb90 upstream.
Positive return values are also failures that don't set val, although this probably can't happen. Fixes gcc 10 warning:
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c: In function ‘t4_phy_fw_ver’: drivers/net/ethernet/chelsio/cxgb4/t4_hw.c:3747:14: warning: ‘val’ may be used uninitialized in this function [-Wmaybe-uninitialized] 3747 | *phy_fw_ver = val;
Fixes: 01b6961410b7 ("cxgb4: Add PHY firmware support for T420-BT cards") Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -3341,7 +3341,7 @@ int t4_phy_fw_ver(struct adapter *adap, FW_PARAMS_PARAM_Z_V(FW_PARAMS_PARAM_DEV_PHYFW_VERSION)); ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1, ¶m, &val); - if (ret < 0) + if (ret) return ret; *phy_fw_ver = val; return 0;
From: Ian Rogers irogers@google.com
commit f3bed55e850926614b9898fe982f66d2541a36a5 upstream.
Current logic yields the child task as the parent.
Before: $ perf record bash -c "perf list > /dev/null" $ perf script -D |grep 'FORK|EXIT' 4387036190981094 0x5a70 [0x30]: PERF_RECORD_FORK(10472:10472):(10470:10470) 4387036606207580 0xf050 [0x30]: PERF_RECORD_EXIT(10472:10472):(10472:10472) 4387036607103839 0x17150 [0x30]: PERF_RECORD_EXIT(10470:10470):(10470:10470) ^ Note the repeated values here -------------------/
After: 383281514043 0x9d8 [0x30]: PERF_RECORD_FORK(2268:2268):(2266:2266) 383442003996 0x2180 [0x30]: PERF_RECORD_EXIT(2268:2268):(2266:2266) 383451297778 0xb70 [0x30]: PERF_RECORD_EXIT(2266:2266):(2265:2265)
Fixes: 94d5d1b2d891 ("perf_counter: Report the cloning task as parent on perf_counter_fork()") Reported-by: KP Singh kpsingh@google.com Signed-off-by: Ian Rogers irogers@google.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/20200417182842.12522-1-irogers@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- kernel/events/core.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
--- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -5810,10 +5810,17 @@ static void perf_event_task_output(struc goto out;
task_event->event_id.pid = perf_event_pid(event, task); - task_event->event_id.ppid = perf_event_pid(event, current); - task_event->event_id.tid = perf_event_tid(event, task); - task_event->event_id.ptid = perf_event_tid(event, current); + + if (task_event->event_id.header.type == PERF_RECORD_EXIT) { + task_event->event_id.ppid = perf_event_pid(event, + task->real_parent); + task_event->event_id.ptid = perf_event_pid(event, + task->real_parent); + } else { /* PERF_RECORD_FORK */ + task_event->event_id.ppid = perf_event_pid(event, current); + task_event->event_id.ptid = perf_event_tid(event, current); + }
task_event->event_id.time = perf_event_clock(event);
From: Luke Nelson lukenels@cs.washington.edu
[ Upstream commit aee194b14dd2b2bde6252b3acf57d36dccfc743a ]
This patch fixes an encoding bug in emit_stx for BPF_B when the source register is BPF_REG_FP.
The current implementation for BPF_STX BPF_B in emit_stx saves one REX byte when the operands can be encoded using Mod-R/M alone. The lower 8 bits of registers %rax, %rbx, %rcx, and %rdx can be accessed without using a REX prefix via %al, %bl, %cl, and %dl, respectively. Other registers, (e.g., %rsi, %rdi, %rbp, %rsp) require a REX prefix to use their 8-bit equivalents (%sil, %dil, %bpl, %spl).
The current code checks if the source for BPF_STX BPF_B is BPF_REG_1 or BPF_REG_2 (which map to %rdi and %rsi), in which case it emits the required REX prefix. However, it misses the case when the source is BPF_REG_FP (mapped to %rbp).
The result is that BPF_STX BPF_B with BPF_REG_FP as the source operand will read from register %ch instead of the correct %bpl. This patch fixes the problem by fixing and refactoring the check on which registers need the extra REX byte. Since no BPF registers map to %rsp, there is no need to handle %spl.
Fixes: 622582786c9e0 ("net: filter: x86: internal BPF JIT") Signed-off-by: Xi Wang xi.wang@gmail.com Signed-off-by: Luke Nelson luke.r.nels@gmail.com Signed-off-by: Alexei Starovoitov ast@kernel.org Link: https://lore.kernel.org/bpf/20200418232655.23870-1-luke.r.nels@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/net/bpf_jit_comp.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index dd9a861fd5264..bea13c35979e5 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c @@ -145,6 +145,19 @@ static bool is_ereg(u32 reg) BIT(BPF_REG_9)); }
+/* + * is_ereg_8l() == true if BPF register 'reg' is mapped to access x86-64 + * lower 8-bit registers dil,sil,bpl,spl,r8b..r15b, which need extra byte + * of encoding. al,cl,dl,bl have simpler encoding. + */ +static bool is_ereg_8l(u32 reg) +{ + return is_ereg(reg) || + (1 << reg) & (BIT(BPF_REG_1) | + BIT(BPF_REG_2) | + BIT(BPF_REG_FP)); +} + /* add modifiers if 'reg' maps to x64 registers r8..r15 */ static u8 add_1mod(u8 byte, u32 reg) { @@ -731,9 +744,8 @@ st: if (is_imm8(insn->off)) /* STX: *(u8*)(dst_reg + off) = src_reg */ case BPF_STX | BPF_MEM | BPF_B: /* emit 'mov byte ptr [rax + off], al' */ - if (is_ereg(dst_reg) || is_ereg(src_reg) || - /* have to add extra byte for x86 SIL, DIL regs */ - src_reg == BPF_REG_1 || src_reg == BPF_REG_2) + if (is_ereg(dst_reg) || is_ereg_8l(src_reg)) + /* Add extra byte for eregs or SIL,DIL,BPL in src_reg */ EMIT2(add_2mod(0x40, dst_reg, src_reg), 0x88); else EMIT1(0x88);
From: Bodo Stroesser bstroesser@ts.fujitsu.com
[ Upstream commit 8fed04eb79a74cbf471dfaa755900a51b37273ab ]
Creation of the response to READ FULL STATUS fails for FC based reservations. Reason is the too high loop limit (< 24) in fc_get_pr_transport_id(). The string representation of FC WWPN is 23 chars long only ("11:22:33:44:55:66:77:88"). So when i is 23, the loop body is executed a last time for the ending '\0' of the string and thus hex2bin() reports an error.
Link: https://lore.kernel.org/r/20200408132610.14623-3-bstroesser@ts.fujitsu.com Signed-off-by: Bodo Stroesser bstroesser@ts.fujitsu.com Reviewed-by: Mike Christie mchristi@redhat.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/target/target_core_fabric_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/target/target_core_fabric_lib.c b/drivers/target/target_core_fabric_lib.c index 6e75095af6818..2ecb2f7042a13 100644 --- a/drivers/target/target_core_fabric_lib.c +++ b/drivers/target/target_core_fabric_lib.c @@ -75,7 +75,7 @@ static int fc_get_pr_transport_id( * encoded TransportID. */ ptr = &se_nacl->initiatorname[0]; - for (i = 0; i < 24; ) { + for (i = 0; i < 23; ) { if (!strncmp(&ptr[i], ":", 1)) { i++; continue;
From: Juergen Gross jgross@suse.com
[ Upstream commit 6b51fd3f65a22e3d1471b18a1d56247e246edd46 ]
xenbus_map_ring_valloc() maps a ring page and returns the status of the used grant (0 meaning success).
There are Xen hypervisors which might return the value 1 for the status of a failed grant mapping due to a bug. Some callers of xenbus_map_ring_valloc() test for errors by testing the returned status to be less than zero, resulting in no error detected and crashing later due to a not available ring page.
Set the return value of xenbus_map_ring_valloc() to GNTST_general_error in case the grant status reported by Xen is greater than zero.
This is part of XSA-316.
Signed-off-by: Juergen Gross jgross@suse.com Reviewed-by: Wei Liu wl@xen.org Link: https://lore.kernel.org/r/20200326080358.1018-1-jgross@suse.com Signed-off-by: Juergen Gross jgross@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/xen/xenbus/xenbus_client.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c index 056da6ee1a357..df27cefb2fa35 100644 --- a/drivers/xen/xenbus/xenbus_client.c +++ b/drivers/xen/xenbus/xenbus_client.c @@ -469,7 +469,14 @@ EXPORT_SYMBOL_GPL(xenbus_free_evtchn); int xenbus_map_ring_valloc(struct xenbus_device *dev, grant_ref_t *gnt_refs, unsigned int nr_grefs, void **vaddr) { - return ring_ops->map(dev, gnt_refs, nr_grefs, vaddr); + int err; + + err = ring_ops->map(dev, gnt_refs, nr_grefs, vaddr); + /* Some hypervisors are buggy and can return 1. */ + if (err > 0) + err = GNTST_general_error; + + return err; } EXPORT_SYMBOL_GPL(xenbus_map_ring_valloc);
From: Theodore Ts'o tytso@mit.edu
[ Upstream commit 907ea529fc4c3296701d2bfc8b831dd2a8121a34 ]
If the in-core buddy bitmap gets corrupted (or out of sync with the block bitmap), issue a WARN_ON and try to recover. In most cases this involves skipping trying to allocate out of a particular block group. We can end up declaring the file system corrupted, which is fair, since the file system probably should be checked before we proceed any further.
Link: https://lore.kernel.org/r/20200414035649.293164-1-tytso@mit.edu Google-Bug-Id: 34811296 Google-Bug-Id: 34639169 Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Sasha Levin sashal@kernel.org --- fs/ext4/mballoc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index fda49f4c5a8eb..04fab14e630c1 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -1944,7 +1944,8 @@ void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac, int free;
free = e4b->bd_info->bb_free; - BUG_ON(free <= 0); + if (WARN_ON(free <= 0)) + return;
i = e4b->bd_info->bb_first_free;
@@ -1965,7 +1966,8 @@ void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac, }
mb_find_extent(e4b, i, ac->ac_g_ex.fe_len, &ex); - BUG_ON(ex.fe_len <= 0); + if (WARN_ON(ex.fe_len <= 0)) + break; if (free < ex.fe_len) { ext4_grp_locked_error(sb, e4b->bd_group, 0, 0, "%d free clusters as per "
From: Frank Rowand frank.rowand@sony.com
[ Upstream commit b3fb36ed694b05738d45218ea72cf7feb10ce2b1 ]
kmemleak reports several memory leaks from devicetree unittest. This is the fix for problem 1 of 5.
of_unittest_changeset() reaches deeply into the dynamic devicetree functions. Several nodes were left with an elevated reference count and thus were not properly cleaned up. Fix the reference counts so that the memory will be freed.
Fixes: 201c910bd689 ("of: Transactional DT support.") Reported-by: Erhard F. erhard_f@mailbox.org Signed-off-by: Frank Rowand frank.rowand@sony.com Signed-off-by: Rob Herring robh@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/of/unittest.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 91e6891b777b6..109497dbfba08 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -544,6 +544,10 @@ static void __init of_unittest_changeset(void) mutex_unlock(&of_mutex);
of_changeset_destroy(&chgset); + + of_node_put(n1); + of_node_put(n2); + of_node_put(n21); #endif }
From: Theodore Ts'o tytso@mit.edu
commit 8a363970d1dc38c4ec4ad575c862f776f468d057 upstream.
If we receive a file handle, either from NFS or open_by_handle_at(2), and it points at an inode which has not been initialized, and the file system has metadata checksums enabled, we shouldn't try to get the inode, discover the checksum is invalid, and then declare the file system as being inconsistent.
This can be reproduced by creating a test file system via "mke2fs -t ext4 -O metadata_csum /tmp/foo.img 8M", mounting it, cd'ing into that directory, and then running the following program.
#define _GNU_SOURCE #include <fcntl.h>
struct handle { struct file_handle fh; unsigned char fid[MAX_HANDLE_SZ]; };
int main(int argc, char **argv) { struct handle h = {{8, 1 }, { 12, }};
open_by_handle_at(AT_FDCWD, &h.fh, O_RDONLY); return 0; }
Google-Bug-Id: 120690101 Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@kernel.org Signed-off-by: Ashwin H ashwinh@vmware.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/ext4.h | 15 +++++++++++++-- fs/ext4/ialloc.c | 2 +- fs/ext4/inode.c | 44 +++++++++++++++++++++++++++++++------------- fs/ext4/ioctl.c | 2 +- fs/ext4/namei.c | 4 ++-- fs/ext4/resize.c | 5 +++-- fs/ext4/super.c | 28 ++++++++++------------------ 7 files changed, 61 insertions(+), 39 deletions(-)
--- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -2497,8 +2497,19 @@ int do_journal_get_write_access(handle_t #define FALL_BACK_TO_NONDELALLOC 1 #define CONVERT_INLINE_DATA 2
-extern struct inode *ext4_iget(struct super_block *, unsigned long); -extern struct inode *ext4_iget_normal(struct super_block *, unsigned long); +typedef enum { + EXT4_IGET_NORMAL = 0, + EXT4_IGET_SPECIAL = 0x0001, /* OK to iget a system inode */ + EXT4_IGET_HANDLE = 0x0002 /* Inode # is from a handle */ +} ext4_iget_flags; + +extern struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, + ext4_iget_flags flags, const char *function, + unsigned int line); + +#define ext4_iget(sb, ino, flags) \ + __ext4_iget((sb), (ino), (flags), __func__, __LINE__) + extern int ext4_write_inode(struct inode *, struct writeback_control *); extern int ext4_setattr(struct dentry *, struct iattr *); extern int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry, --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -1150,7 +1150,7 @@ struct inode *ext4_orphan_get(struct sup if (!ext4_test_bit(bit, bitmap_bh->b_data)) goto bad_orphan;
- inode = ext4_iget(sb, ino); + inode = ext4_iget(sb, ino, EXT4_IGET_NORMAL); if (IS_ERR(inode)) { err = PTR_ERR(inode); ext4_error(sb, "couldn't read orphan inode %lu (err %d)", --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4214,7 +4214,9 @@ static inline void ext4_iget_extra_inode EXT4_I(inode)->i_inline_off = 0; }
-struct inode *ext4_iget(struct super_block *sb, unsigned long ino) +struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, + ext4_iget_flags flags, const char *function, + unsigned int line) { struct ext4_iloc iloc; struct ext4_inode *raw_inode; @@ -4227,6 +4229,18 @@ struct inode *ext4_iget(struct super_blo uid_t i_uid; gid_t i_gid;
+ if (((flags & EXT4_IGET_NORMAL) && + (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO)) || + (ino < EXT4_ROOT_INO) || + (ino > le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count))) { + if (flags & EXT4_IGET_HANDLE) + return ERR_PTR(-ESTALE); + __ext4_error(sb, function, line, + "inode #%lu: comm %s: iget: illegal inode #", + ino, current->comm); + return ERR_PTR(-EFSCORRUPTED); + } + inode = iget_locked(sb, ino); if (!inode) return ERR_PTR(-ENOMEM); @@ -4242,11 +4256,18 @@ struct inode *ext4_iget(struct super_blo raw_inode = ext4_raw_inode(&iloc);
if ((ino == EXT4_ROOT_INO) && (raw_inode->i_links_count == 0)) { - EXT4_ERROR_INODE(inode, "root inode unallocated"); + ext4_error_inode(inode, function, line, 0, + "iget: root inode unallocated"); ret = -EFSCORRUPTED; goto bad_inode; }
+ if ((flags & EXT4_IGET_HANDLE) && + (raw_inode->i_links_count == 0) && (raw_inode->i_mode == 0)) { + ret = -ESTALE; + goto bad_inode; + } + if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) { ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize); if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize > @@ -4273,7 +4294,8 @@ struct inode *ext4_iget(struct super_blo }
if (!ext4_inode_csum_verify(inode, raw_inode, ei)) { - EXT4_ERROR_INODE(inode, "checksum invalid"); + ext4_error_inode(inode, function, line, 0, + "iget: checksum invalid"); ret = -EFSBADCRC; goto bad_inode; } @@ -4321,7 +4343,8 @@ struct inode *ext4_iget(struct super_blo ((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32; inode->i_size = ext4_isize(raw_inode); if ((size = i_size_read(inode)) < 0) { - EXT4_ERROR_INODE(inode, "bad i_size value: %lld", size); + ext4_error_inode(inode, function, line, 0, + "iget: bad i_size value: %lld", size); ret = -EFSCORRUPTED; goto bad_inode; } @@ -4404,7 +4427,8 @@ struct inode *ext4_iget(struct super_blo ret = 0; if (ei->i_file_acl && !ext4_data_block_valid(EXT4_SB(sb), ei->i_file_acl, 1)) { - EXT4_ERROR_INODE(inode, "bad extended attribute block %llu", + ext4_error_inode(inode, function, line, 0, + "iget: bad extended attribute block %llu", ei->i_file_acl); ret = -EFSCORRUPTED; goto bad_inode; @@ -4459,7 +4483,8 @@ struct inode *ext4_iget(struct super_blo make_bad_inode(inode); } else { ret = -EFSCORRUPTED; - EXT4_ERROR_INODE(inode, "bogus i_mode (%o)", inode->i_mode); + ext4_error_inode(inode, function, line, 0, + "iget: bogus i_mode (%o)", inode->i_mode); goto bad_inode; } brelse(iloc.bh); @@ -4473,13 +4498,6 @@ bad_inode: return ERR_PTR(ret); }
-struct inode *ext4_iget_normal(struct super_block *sb, unsigned long ino) -{ - if (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO) - return ERR_PTR(-EFSCORRUPTED); - return ext4_iget(sb, ino); -} - static int ext4_inode_blocks_set(handle_t *handle, struct ext4_inode *raw_inode, struct ext4_inode_info *ei) --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c @@ -105,7 +105,7 @@ static long swap_inode_boot_loader(struc if (!inode_owner_or_capable(inode) || !capable(CAP_SYS_ADMIN)) return -EPERM;
- inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO); + inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO, EXT4_IGET_SPECIAL); if (IS_ERR(inode_bl)) return PTR_ERR(inode_bl); ei_bl = EXT4_I(inode_bl); --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -1601,7 +1601,7 @@ static struct dentry *ext4_lookup(struct dentry); return ERR_PTR(-EFSCORRUPTED); } - inode = ext4_iget_normal(dir->i_sb, ino); + inode = ext4_iget(dir->i_sb, ino, EXT4_IGET_NORMAL); if (inode == ERR_PTR(-ESTALE)) { EXT4_ERROR_INODE(dir, "deleted inode referenced: %u", @@ -1646,7 +1646,7 @@ struct dentry *ext4_get_parent(struct de return ERR_PTR(-EFSCORRUPTED); }
- return d_obtain_alias(ext4_iget_normal(d_inode(child)->i_sb, ino)); + return d_obtain_alias(ext4_iget(d_inode(child)->i_sb, ino, EXT4_IGET_NORMAL)); }
/* --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c @@ -1649,7 +1649,7 @@ int ext4_group_add(struct super_block *s "No reserved GDT blocks, can't resize"); return -EPERM; } - inode = ext4_iget(sb, EXT4_RESIZE_INO); + inode = ext4_iget(sb, EXT4_RESIZE_INO, EXT4_IGET_SPECIAL); if (IS_ERR(inode)) { ext4_warning(sb, "Error opening resize inode"); return PTR_ERR(inode); @@ -1977,7 +1977,8 @@ retry: }
if (!resize_inode) - resize_inode = ext4_iget(sb, EXT4_RESIZE_INO); + resize_inode = ext4_iget(sb, EXT4_RESIZE_INO, + EXT4_IGET_SPECIAL); if (IS_ERR(resize_inode)) { ext4_warning(sb, "Error opening resize inode"); return PTR_ERR(resize_inode); --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1022,20 +1022,11 @@ static struct inode *ext4_nfs_get_inode( { struct inode *inode;
- if (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO) - return ERR_PTR(-ESTALE); - if (ino > le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count)) - return ERR_PTR(-ESTALE); - - /* iget isn't really right if the inode is currently unallocated!! - * - * ext4_read_inode will return a bad_inode if the inode had been - * deleted, so we should be safe. - * + /* * Currently we don't know the generation for parent directory, so * a generation of 0 means "accept any" */ - inode = ext4_iget_normal(sb, ino); + inode = ext4_iget(sb, ino, EXT4_IGET_HANDLE); if (IS_ERR(inode)) return ERR_CAST(inode); if (generation && inode->i_generation != generation) { @@ -4036,7 +4027,7 @@ no_journal: * so we can safely mount the rest of the filesystem now. */
- root = ext4_iget(sb, EXT4_ROOT_INO); + root = ext4_iget(sb, EXT4_ROOT_INO, EXT4_IGET_SPECIAL); if (IS_ERR(root)) { ext4_msg(sb, KERN_ERR, "get root inode failed"); ret = PTR_ERR(root); @@ -4273,11 +4264,12 @@ static journal_t *ext4_get_journal(struc
BUG_ON(!ext4_has_feature_journal(sb));
- /* First, test for the existence of a valid inode on disk. Bad - * things happen if we iget() an unused inode, as the subsequent - * iput() will try to delete it. */ - - journal_inode = ext4_iget(sb, journal_inum); + /* + * Test for the existence of a valid inode on disk. Bad things + * happen if we iget() an unused inode, as the subsequent iput() + * will try to delete it. + */ + journal_inode = ext4_iget(sb, journal_inum, EXT4_IGET_SPECIAL); if (IS_ERR(journal_inode)) { ext4_msg(sb, KERN_ERR, "no journal found"); return NULL; @@ -5241,7 +5233,7 @@ static int ext4_quota_enable(struct supe if (!qf_inums[type]) return -EPERM;
- qf_inode = ext4_iget(sb, qf_inums[type]); + qf_inode = ext4_iget(sb, qf_inums[type], EXT4_IGET_SPECIAL); if (IS_ERR(qf_inode)) { ext4_error(sb, "Bad quota inode # %lu", qf_inums[type]); return PTR_ERR(qf_inode);
From: Theodore Ts'o tytso@mit.edu
commit 345c0dbf3a30872d9b204db96b5857cd00808cae upstream.
Add the blocks which belong to the journal inode to block_validity's system zone so attempts to deallocate or overwrite the journal due a corrupted file system where the journal blocks are also claimed by another inode.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=202879 Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@kernel.org Signed-off-by: Ashwin H ashwinh@vmware.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/block_validity.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++ fs/ext4/inode.c | 4 +++ 2 files changed, 52 insertions(+)
--- a/fs/ext4/block_validity.c +++ b/fs/ext4/block_validity.c @@ -136,6 +136,48 @@ static void debug_print_tree(struct ext4 printk("\n"); }
+static int ext4_protect_reserved_inode(struct super_block *sb, u32 ino) +{ + struct inode *inode; + struct ext4_sb_info *sbi = EXT4_SB(sb); + struct ext4_map_blocks map; + u32 i = 0, err = 0, num, n; + + if ((ino < EXT4_ROOT_INO) || + (ino > le32_to_cpu(sbi->s_es->s_inodes_count))) + return -EINVAL; + inode = ext4_iget(sb, ino, EXT4_IGET_SPECIAL); + if (IS_ERR(inode)) + return PTR_ERR(inode); + num = (inode->i_size + sb->s_blocksize - 1) >> sb->s_blocksize_bits; + while (i < num) { + map.m_lblk = i; + map.m_len = num - i; + n = ext4_map_blocks(NULL, inode, &map, 0); + if (n < 0) { + err = n; + break; + } + if (n == 0) { + i++; + } else { + if (!ext4_data_block_valid(sbi, map.m_pblk, n)) { + ext4_error(sb, "blocks %llu-%llu from inode %u " + "overlap system zone", map.m_pblk, + map.m_pblk + map.m_len - 1, ino); + err = -EFSCORRUPTED; + break; + } + err = add_system_zone(sbi, map.m_pblk, n); + if (err < 0) + break; + i += n; + } + } + iput(inode); + return err; +} + int ext4_setup_system_zone(struct super_block *sb) { ext4_group_t ngroups = ext4_get_groups_count(sb); @@ -170,6 +212,12 @@ int ext4_setup_system_zone(struct super_ if (ret) return ret; } + if (ext4_has_feature_journal(sb) && sbi->s_es->s_journal_inum) { + ret = ext4_protect_reserved_inode(sb, + le32_to_cpu(sbi->s_es->s_journal_inum)); + if (ret) + return ret; + }
if (test_opt(sb, DEBUG)) debug_print_tree(EXT4_SB(sb)); --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -377,6 +377,10 @@ static int __check_block_validity(struct unsigned int line, struct ext4_map_blocks *map) { + if (ext4_has_feature_journal(inode->i_sb) && + (inode->i_ino == + le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_journal_inum))) + return 0; if (!ext4_data_block_valid(EXT4_SB(inode->i_sb), map->m_pblk, map->m_len)) { ext4_error_inode(inode, func, line, map->m_pblk,
From: Theodore Ts'o tytso@mit.edu
commit 0a944e8a6c66ca04c7afbaa17e22bf208a8b37f0 upstream.
Since the journal inode is already checked when we added it to the block validity's system zone, if we check it again, we'll just trigger a failure.
This was causing failures like this:
[ 53.897001] EXT4-fs error (device sda): ext4_find_extent:909: inode #8: comm jbd2/sda-8: pblk 121667583 bad header/extent: invalid extent entries - magic f30a, entries 8, max 340(340), depth 0(0) [ 53.931430] jbd2_journal_bmap: journal block not found at offset 49 on sda-8 [ 53.938480] Aborting journal on device sda-8.
... but only if the system was under enough memory pressure that logical->physical mapping for the journal inode gets pushed out of the extent cache. (This is why it wasn't noticed earlier.)
Fixes: 345c0dbf3a30 ("ext4: protect journal inode's blocks using block_validity") Reported-by: Dan Rue dan.rue@linaro.org Signed-off-by: Theodore Ts'o tytso@mit.edu Tested-by: Naresh Kamboju naresh.kamboju@linaro.org Signed-off-by: Ashwin H ashwinh@vmware.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/extents.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
--- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -549,10 +549,14 @@ __read_extent_tree_block(const char *fun } if (buffer_verified(bh) && !(flags & EXT4_EX_FORCE_CACHE)) return bh; - err = __ext4_ext_check(function, line, inode, - ext_block_hdr(bh), depth, pblk); - if (err) - goto errout; + if (!ext4_has_feature_journal(inode->i_sb) || + (inode->i_ino != + le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_journal_inum))) { + err = __ext4_ext_check(function, line, inode, + ext_block_hdr(bh), depth, pblk); + if (err) + goto errout; + } set_buffer_verified(bh); /* * If this is a leaf block, cache all of its entries
From: Theodore Ts'o tytso@mit.edu
commit 170417c8c7bb2cbbdd949bf5c443c0c8f24a203b upstream.
Commit 345c0dbf3a30 ("ext4: protect journal inode's blocks using block_validity") failed to add an exception for the journal inode in ext4_check_blockref(), which is the function used by ext4_get_branch() for indirect blocks. This caused attempts to read from the ext3-style journals to fail with:
[ 848.968550] EXT4-fs error (device sdb7): ext4_get_branch:171: inode #8: block 30343695: comm jbd2/sdb7-8: invalid block
Fix this by adding the missing exception check.
Fixes: 345c0dbf3a30 ("ext4: protect journal inode's blocks using block_validity") Reported-by: Arthur Marsh arthur.marsh@internode.on.net Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Ashwin H ashwinh@vmware.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/block_validity.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/fs/ext4/block_validity.c +++ b/fs/ext4/block_validity.c @@ -274,6 +274,11 @@ int ext4_check_blockref(const char *func __le32 *bref = p; unsigned int blk;
+ if (ext4_has_feature_journal(inode->i_sb) && + (inode->i_ino == + le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_journal_inum))) + return 0; + while (bref < p+max) { blk = le32_to_cpu(*bref++); if (blk &&
From: Colin Ian King colin.king@canonical.com
commit fbbbbd2f28aec991f3fbc248df211550fbdfd58c upstream.
There are two cases where u32 variables n and err are being checked for less than zero error values, the checks is always false because the variables are not signed. Fix this by making the variables ints.
Addresses-Coverity: ("Unsigned compared against 0") Fixes: 345c0dbf3a30 ("ext4: protect journal inode's blocks using block_validity") Signed-off-by: Colin Ian King colin.king@canonical.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Ashwin H ashwinh@vmware.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/block_validity.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/fs/ext4/block_validity.c +++ b/fs/ext4/block_validity.c @@ -141,7 +141,8 @@ static int ext4_protect_reserved_inode(s struct inode *inode; struct ext4_sb_info *sbi = EXT4_SB(sb); struct ext4_map_blocks map; - u32 i = 0, err = 0, num, n; + u32 i = 0, num; + int err = 0, n;
if ((ino < EXT4_ROOT_INO) || (ino > le32_to_cpu(sbi->s_es->s_inodes_count)))
On 01/05/2020 14:20, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.4.221 release. There are 70 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 03 May 2020 13:12:02 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.4.221-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.4.y and the diffstat can be found below.
thanks,
greg k-h
All tests are passing for Tegra ...
Test results for stable-v4.4: 6 builds: 6 pass, 0 fail 12 boots: 12 pass, 0 fail 19 tests: 19 pass, 0 fail
Linux version: 4.4.221-rc1-gbe0a2ec77b53 Boards tested: tegra124-jetson-tk1, tegra20-ventana, tegra30-cardhu-a04
Cheers Jon
On Fri, May 01, 2020 at 03:20:48PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.4.221 release. There are 70 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 03 May 2020 13:12:02 +0000. Anything received after that time might be too late.
Build results: total: 169 pass: 169 fail: 0 Qemu test results: total: 335 pass: 325 fail: 10 Failed tests: ppc64:mac99:ppc64_book3s_defconfig:smp:initrd ppc64:mac99:ppc64_book3s_defconfig:smp:ide:rootfs ppc64:mac99:ppc64_book3s_defconfig:smp:sdhci:mmc:rootfs ppc64:mac99:ppc64_book3s_defconfig:smp:nvme:rootfs ppc64:mac99:ppc64_book3s_defconfig:smp:scsi[DC395]:rootfs ppc64:pseries:pseries_defconfig:initrd ppc64:pseries:pseries_defconfig:scsi:rootfs ppc64:pseries:pseries_defconfig:usb:rootfs ppc64:pseries:pseries_defconfig:sdhci:mmc:rootfs ppc64:pseries:pseries_defconfig:nvme:rootfs
Patch "of: unittest: kmemleak on changeset destroy" results in UAF and must be reverted to fix the problem (this had sneaked in earlier and was dropped at least once).
Guenter
On 5/1/20 7:20 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.4.221 release. There are 70 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 03 May 2020 13:12:02 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.4.221-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.4.y and the diffstat can be found below.
thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks, -- Shuah
linux-stable-mirror@lists.linaro.org