form Linux 4.19.222 to Linux 4.19.227.
some patch with conflicts haven't inclusion yet:
8a8908cb82568 fuse: fix live lock in fuse_iget() 1e1bb4933f1fa fuse: fix bad inode bd6e97e2b6f59 veth: Do not record rx queue hint in veth_xmit 1c3564fca0e7b xfs: map unwritten blocks in XFS_IOC_{ALLOC,FREE}SP just like fallocate f9dfa44be0fb5 f2fs: fix to do sanity check on last xattr entry in __f2fs_setxattr() 9c6159ee8fc9d net: accept UFOv6 packages in virtio_net_hdr_to_skb 57f93eaff49df block, bfq: fix use after free in bfq_bfqq_expire 99ada24490c34 block, bfq: fix queue removal from weights tree 7d0efcc69c75a block, bfq: fix decrement of num_active_groups e867d620470af block, bfq: fix asymmetric scenarios detection e4cd53c650bef block, bfq: improve asymmetric scenarios detection
they will be sent with fixed conflicts by the analyser.
Andrew Cooper (1): x86/pkey: Fix undefined behaviour with PKRU_WD_BIT
Andrey Ryabinin (1): cputime, cpuacct: Include guest time in user time in cpuacct.stat
Antoine Tenart (1): net-sysfs: update the queue counts in the unregistration path
Antony Antony (2): xfrm: interface with if_id 0 should return error xfrm: state and policy should fail if XFRMA_IF_ID 0
Arnd Bergmann (1): dmaengine: pxa/mmp: stop referencing config->slave_id
Bart Van Assche (1): scsi: ufs: Fix race conditions related to driver data
Chen Jun (1): tpm: add request_locality before write TPM_INT_ENABLE
Chengfeng Ye (1): crypto: qce - fix uaf on qce_ahash_register_one
Christoph Hellwig (1): scsi: sr: Don't use GFP_DMA
Coco Li (1): udp: using datalen to cap ipv6 udp max gso segments
David Ahern (4): ipv6: Check attribute length for RTA_GATEWAY in multipath route ipv6: Check attribute length for RTA_GATEWAY when deleting multipath route ipv6: Continue processing multipath route even if gateway attribute is invalid ipv6: Do cleanup if attribute validation fails in multipath route
Doyle, Patrick (1): mtd: nand: bbt: Fix corner case in bad block table handling
Eric Dumazet (3): xfrm: fix a small bug in xfrm_sa_len() af_unix: annote lockless accesses to unix_tot_inflight & gc_in_progress netns: add schedule point in ops_exit_list()
Fernando Fernandez Mancera (1): bonding: fix ad_actor_system option setting to default
Florian Westphal (1): netfilter: bridge: add support for pppoe filtering
Gang Li (1): shmem: fix a race between shmem_unused_huge_shrink and shmem_evict_inode
Hector Martin (1): iommu/io-pgtable-arm: Fix table descriptor paddr formatting
Jan Kara (4): ext4: avoid trim error on fs with small groups ext4: make sure to reset inode lockdep class when quota enabling fails ext4: make sure quota gets properly shutdown on error select: Fix indefinitely sleeping task in poll_schedule_timeout()
Joe Thornber (2): dm btree: add a defensive bounds check to insert_at() dm space map common: add bounds check to sm_ll_lookup_bitmap()
Kyeong Yoo (1): jffs2: GC deadlock reading a page that is used in jffs2_write_begin()
Li Hua (1): sched/rt: Try to restart rt period timer when rt runtime exceeded
Lino Sanfilippo (1): serial: amba-pl011: do not request memory region twice
Lixiaokeng (1): scsi: libiscsi: Fix UAF in iscsi_conn_get_param()/iscsi_conn_teardown()
Lizhi Hou (1): tty: serial: uartlite: allow 64 bit address
Lukas Wunner (1): serial: Fix incorrect rs485 polarity on uart open
Luís Henriques (1): ext4: set csum seed in tmp inode while migrating to extents
Marek Vasut (1): crypto: stm32/crc32 - Fix kernel BUG triggered in probe()
Muchun Song (1): net: fix use-after-free in tw_timer_handler
Naveen N. Rao (2): tracing: Fix check for trace_percpu_buffer validity in get_trace_buf() tracing: Tag trace_percpu_buffer as a percpu pointer
Nicolas Toromanoff (1): crypto: stm32/cryp - fix double pm exit
Paolo Abeni (1): bpf: Do not WARN in bpf_warn_invalid_xdp_action()
Pavel Skripkin (1): net: mcs7830: handle usb read errors properly
Rafael J. Wysocki (2): ACPICA: Utilities: Avoid deleting the same object twice in a row ACPICA: Executer: Fix the REFCLASS_REFOF case in acpi_ex_opcode_1A_0T_1R()
Suresh Kumar (1): net: bonding: debug: avoid printing debug logs when bond is not notifying peers
Thadeu Lima de Souza Cascardo (2): ipmi: bail out if init_srcu_struct fails ipmi: fix initialization when workqueue allocation fails
Theodore Ts'o (1): ext4: don't use the orphan list when migrating an inode
Thomas Gleixner (1): can: bcm: switch timer to HRTIMER_MODE_SOFT and remove hrtimer_tasklet
Tom Rix (1): selinux: initialize proto variable in selinux_ip_postroute_compat()
Willem de Bruijn (1): net: skip virtio_net_hdr_set_proto if protocol already set
William Zhao (1): ip6_vti: initialize __ip6_tnl_parm struct in vti6_siocdevprivate
Wu Bo (1): ipmi: Fix UAF when uninstall ipmi_si and ipmi_msghandler module
Xin Xiong (1): netfilter: ipt_CLUSTERIP: fix refcount leak in clusterip_tg_check()
Documentation/networking/bonding.txt | 11 +- arch/x86/include/asm/pgtable.h | 4 +- drivers/acpi/acpica/exoparg1.c | 3 +- drivers/acpi/acpica/utdelete.c | 1 + drivers/char/ipmi/ipmi_msghandler.c | 21 ++- drivers/char/tpm/tpm_tis_core.c | 8 + drivers/crypto/qce/sha.c | 2 +- drivers/crypto/stm32/stm32-cryp.c | 2 - drivers/crypto/stm32/stm32_crc32.c | 4 +- drivers/dma/mmp_pdma.c | 6 - drivers/dma/pxa_dma.c | 7 - drivers/iommu/io-pgtable-arm.c | 9 +- drivers/md/persistent-data/dm-btree.c | 8 +- .../md/persistent-data/dm-space-map-common.c | 5 + drivers/mtd/nand/bbt.c | 2 +- drivers/net/bonding/bond_main.c | 6 +- drivers/net/bonding/bond_options.c | 2 +- drivers/net/usb/mcs7830.c | 12 +- drivers/scsi/libiscsi.c | 6 +- drivers/scsi/sr.c | 2 +- drivers/scsi/sr_vendor.c | 4 +- drivers/scsi/ufs/tc-dwc-g210-pci.c | 1 - drivers/scsi/ufs/ufshcd-pltfrm.c | 2 - drivers/scsi/ufs/ufshcd.c | 7 + drivers/tty/serial/amba-pl011.c | 27 +-- drivers/tty/serial/serial_core.c | 4 +- drivers/tty/serial/uartlite.c | 2 +- fs/ext4/ioctl.c | 2 - fs/ext4/mballoc.c | 8 + fs/ext4/migrate.c | 23 ++- fs/ext4/super.c | 23 ++- fs/jffs2/file.c | 40 +++-- fs/select.c | 63 +++---- include/linux/virtio_net.h | 3 + kernel/sched/cputime.c | 4 +- kernel/sched/rt.c | 23 ++- kernel/trace/trace.c | 6 +- mm/shmem.c | 37 +++-- net/bridge/br_netfilter_hooks.c | 7 +- net/can/bcm.c | 156 ++++++------------ net/core/filter.c | 6 +- net/core/net-sysfs.c | 3 + net/core/net_namespace.c | 4 +- net/ipv4/af_inet.c | 10 +- net/ipv4/netfilter/ipt_CLUSTERIP.c | 5 +- net/ipv6/ip6_vti.c | 2 + net/ipv6/route.c | 28 +++- net/ipv6/udp.c | 2 +- net/unix/garbage.c | 14 +- net/unix/scm.c | 6 +- net/xfrm/xfrm_interface.c | 14 +- net/xfrm/xfrm_user.c | 23 ++- security/selinux/hooks.c | 2 +- 53 files changed, 375 insertions(+), 307 deletions(-)
From: Willem de Bruijn willemb@google.com
stable inclusion from linux-4.19.223 commit 5fefa884a55bd5995e77f4fdd89f0400f42b39f7
--------------------------------
[ Upstream commit 1ed1d592113959f00cc552c3b9f47ca2d157768f ]
virtio_net_hdr_set_proto infers skb->protocol from the virtio_net_hdr gso_type, to avoid packets getting dropped for lack of a proto type.
Its protocol choice is a guess, especially in the case of UFO, where the single VIRTIO_NET_HDR_GSO_UDP label covers both UFOv4 and UFOv6.
Skip this best effort if the field is already initialized. Whether explicitly from userspace, or implicitly based on an earlier call to dev_parse_header_protocol (which is more robust, but was introduced after this patch).
Fixes: 9d2f67e43b73 ("net/packet: fix packet drop as of virtio gso") Signed-off-by: Willem de Bruijn willemb@google.com Link: https://lore.kernel.org/r/20211220145027.2784293-1-willemdebruijn.kernel@gma... Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- include/linux/virtio_net.h | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h index 3e2ee7739c11..a7c197299fc7 100644 --- a/include/linux/virtio_net.h +++ b/include/linux/virtio_net.h @@ -10,6 +10,9 @@ static inline int virtio_net_hdr_set_proto(struct sk_buff *skb, const struct virtio_net_hdr *hdr) { + if (skb->protocol) + return 0; + switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { case VIRTIO_NET_HDR_GSO_TCPV4: case VIRTIO_NET_HDR_GSO_UDP:
From: Wu Bo wubo40@huawei.com
stable inclusion from linux-4.19.223 commit 925229d552724e1bba1abf01d3a0b1318539b012
--------------------------------
[ Upstream commit ffb76a86f8096a8206be03b14adda6092e18e275 ]
Hi,
When testing install and uninstall of ipmi_si.ko and ipmi_msghandler.ko, the system crashed.
The log as follows: [ 141.087026] BUG: unable to handle kernel paging request at ffffffffc09b3a5a [ 141.087241] PGD 8fe4c0d067 P4D 8fe4c0d067 PUD 8fe4c0f067 PMD 103ad89067 PTE 0 [ 141.087464] Oops: 0010 [#1] SMP NOPTI [ 141.087580] CPU: 67 PID: 668 Comm: kworker/67:1 Kdump: loaded Not tainted 4.18.0.x86_64 #47 [ 141.088009] Workqueue: events 0xffffffffc09b3a40 [ 141.088009] RIP: 0010:0xffffffffc09b3a5a [ 141.088009] Code: Bad RIP value. [ 141.088009] RSP: 0018:ffffb9094e2c3e88 EFLAGS: 00010246 [ 141.088009] RAX: 0000000000000000 RBX: ffff9abfdb1f04a0 RCX: 0000000000000000 [ 141.088009] RDX: 0000000000000000 RSI: 0000000000000246 RDI: 0000000000000246 [ 141.088009] RBP: 0000000000000000 R08: ffff9abfffee3cb8 R09: 00000000000002e1 [ 141.088009] R10: ffffb9094cb73d90 R11: 00000000000f4240 R12: ffff9abfffee8700 [ 141.088009] R13: 0000000000000000 R14: ffff9abfdb1f04a0 R15: ffff9abfdb1f04a8 [ 141.088009] FS: 0000000000000000(0000) GS:ffff9abfffec0000(0000) knlGS:0000000000000000 [ 141.088009] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 141.088009] CR2: ffffffffc09b3a30 CR3: 0000008fe4c0a001 CR4: 00000000007606e0 [ 141.088009] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 141.088009] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 141.088009] PKRU: 55555554 [ 141.088009] Call Trace: [ 141.088009] ? process_one_work+0x195/0x390 [ 141.088009] ? worker_thread+0x30/0x390 [ 141.088009] ? process_one_work+0x390/0x390 [ 141.088009] ? kthread+0x10d/0x130 [ 141.088009] ? kthread_flush_work_fn+0x10/0x10 [ 141.088009] ? ret_from_fork+0x35/0x40] BUG: unable to handle kernel paging request at ffffffffc0b28a5a [ 200.223240] PGD 97fe00d067 P4D 97fe00d067 PUD 97fe00f067 PMD a580cbf067 PTE 0 [ 200.223464] Oops: 0010 [#1] SMP NOPTI [ 200.223579] CPU: 63 PID: 664 Comm: kworker/63:1 Kdump: loaded Not tainted 4.18.0.x86_64 #46 [ 200.224008] Workqueue: events 0xffffffffc0b28a40 [ 200.224008] RIP: 0010:0xffffffffc0b28a5a [ 200.224008] Code: Bad RIP value. [ 200.224008] RSP: 0018:ffffbf3c8e2a3e88 EFLAGS: 00010246 [ 200.224008] RAX: 0000000000000000 RBX: ffffa0799ad6bca0 RCX: 0000000000000000 [ 200.224008] RDX: 0000000000000000 RSI: 0000000000000246 RDI: 0000000000000246 [ 200.224008] RBP: 0000000000000000 R08: ffff9fe43fde3cb8 R09: 00000000000000d5 [ 200.224008] R10: ffffbf3c8cb53d90 R11: 00000000000f4240 R12: ffff9fe43fde8700 [ 200.224008] R13: 0000000000000000 R14: ffffa0799ad6bca0 R15: ffffa0799ad6bca8 [ 200.224008] FS: 0000000000000000(0000) GS:ffff9fe43fdc0000(0000) knlGS:0000000000000000 [ 200.224008] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 200.224008] CR2: ffffffffc0b28a30 CR3: 00000097fe00a002 CR4: 00000000007606e0 [ 200.224008] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 200.224008] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 200.224008] PKRU: 55555554 [ 200.224008] Call Trace: [ 200.224008] ? process_one_work+0x195/0x390 [ 200.224008] ? worker_thread+0x30/0x390 [ 200.224008] ? process_one_work+0x390/0x390 [ 200.224008] ? kthread+0x10d/0x130 [ 200.224008] ? kthread_flush_work_fn+0x10/0x10 [ 200.224008] ? ret_from_fork+0x35/0x40 [ 200.224008] kernel fault(0x1) notification starting on CPU 63 [ 200.224008] kernel fault(0x1) notification finished on CPU 63 [ 200.224008] CR2: ffffffffc0b28a5a [ 200.224008] ---[ end trace c82a412d93f57412 ]---
The reason is as follows: T1: rmmod ipmi_si. ->ipmi_unregister_smi() -> ipmi_bmc_unregister() -> __ipmi_bmc_unregister() -> kref_put(&bmc->usecount, cleanup_bmc_device); -> schedule_work(&bmc->remove_work);
T2: rmmod ipmi_msghandler. ipmi_msghander module uninstalled, and the module space will be freed.
T3: bmc->remove_work doing cleanup the bmc resource. -> cleanup_bmc_work() -> platform_device_unregister(&bmc->pdev); -> platform_device_del(pdev); -> device_del(&pdev->dev); -> kobject_uevent(&dev->kobj, KOBJ_REMOVE); -> kobject_uevent_env() -> dev_uevent() -> if (dev->type && dev->type->name)
'dev->type'(bmc_device_type) pointer space has freed when uninstall ipmi_msghander module, 'dev->type->name' cause the system crash.
drivers/char/ipmi/ipmi_msghandler.c: 2820 static const struct device_type bmc_device_type = { 2821 .groups = bmc_dev_attr_groups, 2822 };
Steps to reproduce: Add a time delay in cleanup_bmc_work() function, and uninstall ipmi_si and ipmi_msghandler module.
2910 static void cleanup_bmc_work(struct work_struct *work) 2911 { 2912 struct bmc_device *bmc = container_of(work, struct bmc_device, 2913 remove_work); 2914 int id = bmc->pdev.id; /* Unregister overwrites id */ 2915 2916 msleep(3000); <--- 2917 platform_device_unregister(&bmc->pdev); 2918 ida_simple_remove(&ipmi_bmc_ida, id); 2919 }
Use 'remove_work_wq' instead of 'system_wq' to solve this issues.
Fixes: b2cfd8ab4add ("ipmi: Rework device id and guid handling to catch changing BMCs") Signed-off-by: Wu Bo wubo40@huawei.com Message-Id: 1640070034-56671-1-git-send-email-wubo40@huawei.com Signed-off-by: Corey Minyard cminyard@mvista.com Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- drivers/char/ipmi/ipmi_msghandler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 272c34102875..19c33a86c1b8 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -2863,7 +2863,7 @@ cleanup_bmc_device(struct kref *ref) * with removing the device attributes while reading a device * attribute. */ - schedule_work(&bmc->remove_work); + queue_work(remove_work_wq, &bmc->remove_work); }
/*
From: Fernando Fernandez Mancera ffmancera@riseup.net
stable inclusion from linux-4.19.223 commit 4e4591490f8a930e11131514db4cce4201ffc8a5
--------------------------------
[ Upstream commit 1c15b05baea71a5ff98235783e3e4ad227760876 ]
When 802.3ad bond mode is configured the ad_actor_system option is set to "00:00:00:00:00:00". But when trying to set the all-zeroes MAC as actors' system address it was failing with EINVAL.
An all-zeroes ethernet address is valid, only multicast addresses are not valid values.
Fixes: 171a42c38c6e ("bonding: add netlink support for sys prio, actor sys mac, and port key") Signed-off-by: Fernando Fernandez Mancera ffmancera@riseup.net Acked-by: Jay Vosburgh jay.vosburgh@canonical.com Link: https://lore.kernel.org/r/20211221111345.2462-1-ffmancera@riseup.net Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- Documentation/networking/bonding.txt | 11 ++++++----- drivers/net/bonding/bond_options.c | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt index e3abfbd32f71..b020e6ce6dd4 100644 --- a/Documentation/networking/bonding.txt +++ b/Documentation/networking/bonding.txt @@ -191,11 +191,12 @@ ad_actor_sys_prio ad_actor_system
In an AD system, this specifies the mac-address for the actor in - protocol packet exchanges (LACPDUs). The value cannot be NULL or - multicast. It is preferred to have the local-admin bit set for this - mac but driver does not enforce it. If the value is not given then - system defaults to using the masters' mac address as actors' system - address. + protocol packet exchanges (LACPDUs). The value cannot be a multicast + address. If the all-zeroes MAC is specified, bonding will internally + use the MAC of the bond itself. It is preferred to have the + local-admin bit set for this mac but driver does not enforce it. If + the value is not given then system defaults to using the masters' + mac address as actors' system address.
This parameter has effect only in 802.3ad mode and is available through SysFs interface. diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index 7e07e213f4c2..1745cba04c18 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c @@ -1458,7 +1458,7 @@ static int bond_option_ad_actor_system_set(struct bonding *bond, mac = (u8 *)&newval->value; }
- if (!is_valid_ether_addr(mac)) + if (is_multicast_ether_addr(mac)) goto err;
netdev_dbg(bond->dev, "Setting ad_actor_system to %pM\n", mac);
From: Thadeu Lima de Souza Cascardo cascardo@canonical.com
stable inclusion from linux-4.19.223 commit db0d90490674c297a2e15a1ca3e40cd6975c30dc
--------------------------------
commit 2b5160b12091285c5aca45980f100a9294af7b04 upstream.
In case, init_srcu_struct fails (because of memory allocation failure), we might proceed with the driver initialization despite srcu_struct not being entirely initialized.
Fixes: 913a89f009d9 ("ipmi: Don't initialize anything in the core until something uses it") Signed-off-by: Thadeu Lima de Souza Cascardo cascardo@canonical.com Cc: Corey Minyard cminyard@mvista.com Cc: stable@vger.kernel.org Message-Id: 20211217154410.1228673-1-cascardo@canonical.com Signed-off-by: Corey Minyard cminyard@mvista.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- drivers/char/ipmi/ipmi_msghandler.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 19c33a86c1b8..9b66afeb1237 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -5083,7 +5083,9 @@ static int ipmi_init_msghandler(void) if (initialized) goto out;
- init_srcu_struct(&ipmi_interfaces_srcu); + rv = init_srcu_struct(&ipmi_interfaces_srcu); + if (rv) + goto out;
timer_setup(&ipmi_timer, ipmi_timeout, 0); mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
From: Thadeu Lima de Souza Cascardo cascardo@canonical.com
stable inclusion from linux-4.19.223 commit eb84855d3e8799b67cdbadc7a5c53997cbfc3580
--------------------------------
commit 75d70d76cb7b927cace2cb34265d68ebb3306b13 upstream.
If the workqueue allocation fails, the driver is marked as not initialized, and timer and panic_notifier will be left registered.
Instead of removing those when workqueue allocation fails, do the workqueue initialization before doing it, and cleanup srcu_struct if it fails.
Fixes: 1d49eb91e86e ("ipmi: Move remove_work to dedicated workqueue") Signed-off-by: Thadeu Lima de Souza Cascardo cascardo@canonical.com Cc: Corey Minyard cminyard@mvista.com Cc: Ioanna Alifieraki ioanna-maria.alifieraki@canonical.com Cc: stable@vger.kernel.org Message-Id: 20211217154410.1228673-2-cascardo@canonical.com Signed-off-by: Corey Minyard cminyard@mvista.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- drivers/char/ipmi/ipmi_msghandler.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 9b66afeb1237..83eaab66d2f6 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -5087,20 +5087,23 @@ static int ipmi_init_msghandler(void) if (rv) goto out;
- timer_setup(&ipmi_timer, ipmi_timeout, 0); - mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES); - - atomic_notifier_chain_register(&panic_notifier_list, &panic_block); - remove_work_wq = create_singlethread_workqueue("ipmi-msghandler-remove-wq"); if (!remove_work_wq) { pr_err("unable to create ipmi-msghandler-remove-wq workqueue"); rv = -ENOMEM; - goto out; + goto out_wq; }
+ timer_setup(&ipmi_timer, ipmi_timeout, 0); + mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES); + + atomic_notifier_chain_register(&panic_notifier_list, &panic_block); + initialized = true;
+out_wq: + if (rv) + cleanup_srcu_struct(&ipmi_interfaces_srcu); out: mutex_unlock(&ipmi_interfaces_mutex); return rv;
From: Andrew Cooper andrew.cooper3@citrix.com
stable inclusion from linux-4.19.223 commit 94cc1e8331973ee7a2b4336f7ba67f48c2877d0a
--------------------------------
commit 57690554abe135fee81d6ac33cc94d75a7e224bb upstream.
Both __pkru_allows_write() and arch_set_user_pkey_access() shift PKRU_WD_BIT (a signed constant) by up to 30 bits, hitting the sign bit.
Use unsigned constants instead.
Clearly pkey 15 has not been used in combination with UBSAN yet.
Noticed by code inspection only. I can't actually provoke the compiler into generating incorrect logic as far as this shift is concerned.
[ dhansen: add stable@ tag, plus minor changelog massaging,
For anyone doing backports, these #defines were in arch/x86/include/asm/pgtable.h before 784a46618f6. ]
Fixes: 33a709b25a76 ("mm/gup, x86/mm/pkeys: Check VMAs and PTEs for protection keys") Signed-off-by: Andrew Cooper andrew.cooper3@citrix.com Signed-off-by: Dave Hansen dave.hansen@linux.intel.com Signed-off-by: Borislav Petkov bp@suse.de Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/20211216000856.4480-1-andrew.cooper3@citrix.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- arch/x86/include/asm/pgtable.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index fe6f9e7f15bb..1d79485ae972 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -1353,8 +1353,8 @@ static inline pmd_t pmd_swp_clear_soft_dirty(pmd_t pmd) #endif #endif
-#define PKRU_AD_BIT 0x1 -#define PKRU_WD_BIT 0x2 +#define PKRU_AD_BIT 0x1u +#define PKRU_WD_BIT 0x2u #define PKRU_BITS_PER_PKEY 2
static inline bool __pkru_allows_read(u32 pkru, u16 pkey)
From: Tom Rix trix@redhat.com
stable inclusion from linux-4.19.224 commit c34a0b5b3bf01062eb5f2a47870c5ab57256bdfc
--------------------------------
commit 732bc2ff080c447f8524f40c970c481f5da6eed3 upstream.
Clang static analysis reports this warning
hooks.c:5765:6: warning: 4th function call argument is an uninitialized value if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto)) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
selinux_parse_skb() can return ok without setting proto. The later call to selinux_xfrm_postroute_last() does an early check of proto and can return ok if the garbage proto value matches. So initialize proto.
Cc: stable@vger.kernel.org Fixes: eef9b41622f2 ("selinux: cleanup selinux_xfrm_sock_rcv_skb() and selinux_xfrm_postroute_last()") Signed-off-by: Tom Rix trix@redhat.com [PM: typo/spelling and checkpatch.pl description fixes] Signed-off-by: Paul Moore paul@paul-moore.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- security/selinux/hooks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 1b611c068669..25353b4975c9 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -5799,7 +5799,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, struct common_audit_data ad; struct lsm_network_audit net = {0,}; char *addrp; - u8 proto; + u8 proto = 0;
if (sk == NULL) return NF_ACCEPT;
From: Coco Li lixiaoyan@google.com
stable inclusion from linux-4.19.224 commit bbd9c7120c31c1aff6dcffdcce122773d163df72
--------------------------------
[ Upstream commit 736ef37fd9a44f5966e25319d08ff7ea99ac79e8 ]
The max number of UDP gso segments is intended to cap to UDP_MAX_SEGMENTS, this is checked in udp_send_skb().
skb->len contains network and transport header len here, we should use only data len instead.
This is the ipv6 counterpart to the below referenced commit, which missed the ipv6 change
Fixes: 158390e45612 ("udp: using datalen to cap max gso segments") Signed-off-by: Coco Li lixiaoyan@google.com Reviewed-by: Willem de Bruijn willemb@google.com Link: https://lore.kernel.org/r/20211223222441.2975883-1-lixiaoyan@google.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- net/ipv6/udp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 581763d6df12..3ed5fe0055af 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -1069,7 +1069,7 @@ static int udp_v6_send_skb(struct sk_buff *skb, struct flowi6 *fl6, kfree_skb(skb); return -EINVAL; } - if (skb->len > cork->gso_size * UDP_MAX_SEGMENTS) { + if (datalen > cork->gso_size * UDP_MAX_SEGMENTS) { kfree_skb(skb); return -EINVAL; }
From: Muchun Song songmuchun@bytedance.com
stable inclusion from linux-4.19.224 commit a8e1944b44f94f5c5f530e434c5eaee787254566
--------------------------------
commit e22e45fc9e41bf9fcc1e92cfb78eb92786728ef0 upstream.
A real world panic issue was found as follow in Linux 5.4.
BUG: unable to handle page fault for address: ffffde49a863de28 PGD 7e6fe62067 P4D 7e6fe62067 PUD 7e6fe63067 PMD f51e064067 PTE 0 RIP: 0010:tw_timer_handler+0x20/0x40 Call Trace: <IRQ> call_timer_fn+0x2b/0x120 run_timer_softirq+0x1ef/0x450 __do_softirq+0x10d/0x2b8 irq_exit+0xc7/0xd0 smp_apic_timer_interrupt+0x68/0x120 apic_timer_interrupt+0xf/0x20
This issue was also reported since 2017 in the thread [1], unfortunately, the issue was still can be reproduced after fixing DCCP.
The ipv4_mib_exit_net is called before tcp_sk_exit_batch when a net namespace is destroyed since tcp_sk_ops is registered befrore ipv4_mib_ops, which means tcp_sk_ops is in the front of ipv4_mib_ops in the list of pernet_list. There will be a use-after-free on net->mib.net_statistics in tw_timer_handler after ipv4_mib_exit_net if there are some inflight time-wait timers.
This bug is not introduced by commit f2bf415cfed7 ("mib: add net to NET_ADD_STATS_BH") since the net_statistics is a global variable instead of dynamic allocation and freeing. Actually, commit 61a7e26028b9 ("mib: put net statistics on struct net") introduces the bug since it put net statistics on struct net and free it when net namespace is destroyed.
Moving init_ipv4_mibs() to the front of tcp_init() to fix this bug and replace pr_crit() with panic() since continuing is meaningless when init_ipv4_mibs() fails.
[1] https://groups.google.com/g/syzkaller/c/p1tn-_Kc6l4/m/smuL_FMAAgAJ?pli=1
Fixes: 61a7e26028b9 ("mib: put net statistics on struct net") Signed-off-by: Muchun Song songmuchun@bytedance.com Cc: Cong Wang cong.wang@bytedance.com Cc: Fam Zheng fam.zheng@bytedance.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20211228104145.9426-1-songmuchun@bytedance.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- net/ipv4/af_inet.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 14e10214cf87..84ce4f86bc19 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1955,6 +1955,10 @@ static int __init inet_init(void)
ip_init();
+ /* Initialise per-cpu ipv4 mibs */ + if (init_ipv4_mibs()) + panic("%s: Cannot init ipv4 mibs\n", __func__); + /* Setup TCP slab cache for open requests. */ tcp_init();
@@ -1985,12 +1989,6 @@ static int __init inet_init(void)
if (init_inet_pernet_ops()) pr_crit("%s: Cannot init ipv4 inet pernet ops\n", __func__); - /* - * Initialise per-cpu ipv4 mibs - */ - - if (init_ipv4_mibs()) - pr_crit("%s: Cannot init ipv4 mibs\n", __func__);
ipv4_proc_init();
From: "Naveen N. Rao" naveen.n.rao@linux.vnet.ibm.com
stable inclusion from linux-4.19.225 commit 24bb91f9536f79a13f85cfaae59be41fc8d9380d
--------------------------------
commit 823e670f7ed616d0ce993075c8afe0217885f79d upstream.
With the new osnoise tracer, we are seeing the below splat: Kernel attempted to read user page (c7d880000) - exploit attempt? (uid: 0) BUG: Unable to handle kernel data access on read at 0xc7d880000 Faulting instruction address: 0xc0000000002ffa10 Oops: Kernel access of bad area, sig: 11 [#1] LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA pSeries ... NIP [c0000000002ffa10] __trace_array_vprintk.part.0+0x70/0x2f0 LR [c0000000002ff9fc] __trace_array_vprintk.part.0+0x5c/0x2f0 Call Trace: [c0000008bdd73b80] [c0000000001c49cc] put_prev_task_fair+0x3c/0x60 (unreliable) [c0000008bdd73be0] [c000000000301430] trace_array_printk_buf+0x70/0x90 [c0000008bdd73c00] [c0000000003178b0] trace_sched_switch_callback+0x250/0x290 [c0000008bdd73c90] [c000000000e70d60] __schedule+0x410/0x710 [c0000008bdd73d40] [c000000000e710c0] schedule+0x60/0x130 [c0000008bdd73d70] [c000000000030614] interrupt_exit_user_prepare_main+0x264/0x270 [c0000008bdd73de0] [c000000000030a70] syscall_exit_prepare+0x150/0x180 [c0000008bdd73e10] [c00000000000c174] system_call_vectored_common+0xf4/0x278
osnoise tracer on ppc64le is triggering osnoise_taint() for negative duration in get_int_safe_duration() called from trace_sched_switch_callback()->thread_exit().
The problem though is that the check for a valid trace_percpu_buffer is incorrect in get_trace_buf(). The check is being done after calculating the pointer for the current cpu, rather than on the main percpu pointer. Fix the check to be against trace_percpu_buffer.
Link: https://lkml.kernel.org/r/a920e4272e0b0635cf20c444707cbce1b2c8973d.164025530...
Cc: stable@vger.kernel.org Fixes: e2ace001176dc9 ("tracing: Choose static tp_printk buffer by explicit nesting count") Signed-off-by: Naveen N. Rao naveen.n.rao@linux.vnet.ibm.com Signed-off-by: Steven Rostedt rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- kernel/trace/trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 8f20a658dabb..5bd5eff5e0e0 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -2796,7 +2796,7 @@ static char *get_trace_buf(void) { struct trace_buffer_struct *buffer = this_cpu_ptr(trace_percpu_buffer);
- if (!buffer || buffer->nesting >= 4) + if (!trace_percpu_buffer || buffer->nesting >= 4) return NULL;
buffer->nesting++;
From: "Naveen N. Rao" naveen.n.rao@linux.vnet.ibm.com
stable inclusion from linux-4.19.225 commit e9c3f28e2b9eaff371db65e4bd7ee170616147b4
--------------------------------
commit f28439db470cca8b6b082239314e9fd10bd39034 upstream.
Tag trace_percpu_buffer as a percpu pointer to resolve warnings reported by sparse: /linux/kernel/trace/trace.c:3218:46: warning: incorrect type in initializer (different address spaces) /linux/kernel/trace/trace.c:3218:46: expected void const [noderef] __percpu *__vpp_verify /linux/kernel/trace/trace.c:3218:46: got struct trace_buffer_struct * /linux/kernel/trace/trace.c:3234:9: warning: incorrect type in initializer (different address spaces) /linux/kernel/trace/trace.c:3234:9: expected void const [noderef] __percpu *__vpp_verify /linux/kernel/trace/trace.c:3234:9: got int *
Link: https://lkml.kernel.org/r/ebabd3f23101d89cb75671b68b6f819f5edc830b.164025530...
Cc: stable@vger.kernel.org Reported-by: kernel test robot lkp@intel.com Fixes: 07d777fe8c398 ("tracing: Add percpu buffers for trace_printk()") Signed-off-by: Naveen N. Rao naveen.n.rao@linux.vnet.ibm.com Signed-off-by: Steven Rostedt rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- kernel/trace/trace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 5bd5eff5e0e0..119dd5fd5840 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -2786,7 +2786,7 @@ struct trace_buffer_struct { char buffer[4][TRACE_BUF_SIZE]; };
-static struct trace_buffer_struct *trace_percpu_buffer; +static struct trace_buffer_struct __percpu *trace_percpu_buffer;
/* * Thise allows for lockless recording. If we're nested too deeply, then @@ -2815,7 +2815,7 @@ static void put_trace_buf(void)
static int alloc_percpu_trace_buffer(void) { - struct trace_buffer_struct *buffers; + struct trace_buffer_struct __percpu *buffers;
buffers = alloc_percpu(struct trace_buffer_struct); if (WARN(!buffers, "Could not allocate percpu trace_printk buffer"))
From: David Ahern dsahern@kernel.org
stable inclusion from linux-4.19.225 commit 44c90b4e6bcbb10f4066b91e8da9c58d4609768c
--------------------------------
commit 4619bcf91399f00a40885100fb61d594d8454033 upstream.
Commit referenced in the Fixes tag used nla_memcpy for RTA_GATEWAY as does the current nla_get_in6_addr. nla_memcpy protects against accessing memory greater than what is in the attribute, but there is no check requiring the attribute to have an IPv6 address. Add it.
Fixes: 51ebd3181572 ("ipv6: add support of equal cost multipath (ECMP)") Signed-off-by: David Ahern dsahern@kernel.org Cc: Nicolas Dichtel nicolas.dichtel@6wind.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- net/ipv6/route.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 01f8e62302fa..a680498b1178 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -4424,6 +4424,19 @@ static void ip6_route_mpath_notify(struct fib6_info *rt, inet6_rt_notify(RTM_NEWROUTE, rt, info, nlflags); }
+static int fib6_gw_from_attr(struct in6_addr *gw, struct nlattr *nla, + struct netlink_ext_ack *extack) +{ + if (nla_len(nla) < sizeof(*gw)) { + NL_SET_ERR_MSG(extack, "Invalid IPv6 address in RTA_GATEWAY"); + return -EINVAL; + } + + *gw = nla_get_in6_addr(nla); + + return 0; +} + static int ip6_route_multipath_add(struct fib6_config *cfg, struct netlink_ext_ack *extack) { @@ -4464,7 +4477,13 @@ static int ip6_route_multipath_add(struct fib6_config *cfg,
nla = nla_find(attrs, attrlen, RTA_GATEWAY); if (nla) { - r_cfg.fc_gateway = nla_get_in6_addr(nla); + int ret; + + ret = fib6_gw_from_attr(&r_cfg.fc_gateway, nla, + extack); + if (ret) + return ret; + r_cfg.fc_flags |= RTF_GATEWAY; } r_cfg.fc_encap = nla_find(attrs, attrlen, RTA_ENCAP);
From: David Ahern dsahern@kernel.org
stable inclusion from linux-4.19.225 commit e30dead00aaa5a575b10117dad8edc126efc1873
--------------------------------
commit 1ff15a710a862db1101b97810af14aedc835a86a upstream.
Make sure RTA_GATEWAY for IPv6 multipath route has enough bytes to hold an IPv6 address.
Fixes: 6b9ea5a64ed5 ("ipv6: fix multipath route replace error recovery") Signed-off-by: David Ahern dsahern@kernel.org Cc: Roopa Prabhu roopa@nvidia.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- net/ipv6/route.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index a680498b1178..0db7a3ca668a 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -4617,7 +4617,11 @@ static int ip6_route_multipath_del(struct fib6_config *cfg,
nla = nla_find(attrs, attrlen, RTA_GATEWAY); if (nla) { - nla_memcpy(&r_cfg.fc_gateway, nla, 16); + err = fib6_gw_from_attr(&r_cfg.fc_gateway, nla, + extack); + if (err) + return err; + r_cfg.fc_flags |= RTF_GATEWAY; } }
From: David Ahern dsahern@kernel.org
stable inclusion from linux-4.19.225 commit e183929b7db0e84a48fdc009a7bcbf9137ad9061
--------------------------------
[ Upstream commit e30a845b0376eb51c9c94f56bbd53b2e08ba822f ]
ip6_route_multipath_del loop continues processing the multipath attribute even if delete of a nexthop path fails. For consistency, do the same if the gateway attribute is invalid.
Fixes: 1ff15a710a86 ("ipv6: Check attribute length for RTA_GATEWAY when deleting multipath route") Signed-off-by: David Ahern dsahern@kernel.org Acked-by: Nicolas Dichtel nicolas.dichtel@6wind.com Link: https://lore.kernel.org/r/20220103171911.94739-1-dsahern@kernel.org Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- net/ipv6/route.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 0db7a3ca668a..e6b021588eb0 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -4619,8 +4619,10 @@ static int ip6_route_multipath_del(struct fib6_config *cfg, if (nla) { err = fib6_gw_from_attr(&r_cfg.fc_gateway, nla, extack); - if (err) - return err; + if (err) { + last_err = err; + goto next_rtnh; + }
r_cfg.fc_flags |= RTF_GATEWAY; } @@ -4629,6 +4631,7 @@ static int ip6_route_multipath_del(struct fib6_config *cfg, if (err) last_err = err;
+next_rtnh: rtnh = rtnh_next(rtnh, &remaining); }
From: David Ahern dsahern@kernel.org
stable inclusion from linux-4.19.225 commit dd74b4e027324219e51d9821c0db4368c9f8526a
--------------------------------
[ Upstream commit 95bdba23b5b4aa75fe3e6c84335e638641c707bb ]
As Nicolas noted, if gateway validation fails walking the multipath attribute the code should jump to the cleanup to free previously allocated memory.
Fixes: 1ff15a710a86 ("ipv6: Check attribute length for RTA_GATEWAY when deleting multipath route") Signed-off-by: David Ahern dsahern@kernel.org Acked-by: Nicolas Dichtel nicolas.dichtel@6wind.com Link: https://lore.kernel.org/r/20220103170555.94638-1-dsahern@kernel.org Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- net/ipv6/route.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index e6b021588eb0..80dd55c436fa 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -4477,12 +4477,10 @@ static int ip6_route_multipath_add(struct fib6_config *cfg,
nla = nla_find(attrs, attrlen, RTA_GATEWAY); if (nla) { - int ret; - - ret = fib6_gw_from_attr(&r_cfg.fc_gateway, nla, + err = fib6_gw_from_attr(&r_cfg.fc_gateway, nla, extack); - if (ret) - return ret; + if (err) + goto cleanup;
r_cfg.fc_flags |= RTF_GATEWAY; }
From: Lixiaokeng lixiaokeng@huawei.com
stable inclusion from linux-4.19.225 commit f5596fdc65ce280cb4debb507c0c5877d1a89936
--------------------------------
[ Upstream commit 1b8d0300a3e9f216ae4901bab886db7299899ec6 ]
|- iscsi_if_destroy_conn |-dev_attr_show |-iscsi_conn_teardown |-spin_lock_bh |-iscsi_sw_tcp_conn_get_param
|-kfree(conn->persistent_address) |-iscsi_conn_get_param |-kfree(conn->local_ipaddr) ==>|-read persistent_address ==>|-read local_ipaddr |-spin_unlock_bh
When iscsi_conn_teardown() and iscsi_conn_get_param() happen in parallel, a UAF may be triggered.
Link: https://lore.kernel.org/r/046ec8a0-ce95-d3fc-3235-666a7c65b224@huawei.com Reported-by: Lu Tixiong lutianxiong@huawei.com Reviewed-by: Mike Christie michael.christie@oracle.com Reviewed-by: Lee Duncan lduncan@suse.com Signed-off-by: Lixiaokeng lixiaokeng@huawei.com Signed-off-by: Linfeilong linfeilong@huawei.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- drivers/scsi/libiscsi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 02060aec08bf..a93a47d4931f 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -3133,6 +3133,8 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) { struct iscsi_conn *conn = cls_conn->dd_data; struct iscsi_session *session = conn->session; + char *tmp_persistent_address = conn->persistent_address; + char *tmp_local_ipaddr = conn->local_ipaddr;
del_timer_sync(&conn->transport_timer);
@@ -3156,8 +3158,6 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) spin_lock_bh(&session->frwd_lock); free_pages((unsigned long) conn->data, get_order(ISCSI_DEF_MAX_RECV_SEG_LEN)); - kfree(conn->persistent_address); - kfree(conn->local_ipaddr); /* regular RX path uses back_lock */ spin_lock_bh(&session->back_lock); kfifo_in(&session->cmdpool.queue, (void*)&conn->login_task, @@ -3169,6 +3169,8 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) mutex_unlock(&session->eh_mutex);
iscsi_destroy_conn(cls_conn); + kfree(tmp_persistent_address); + kfree(tmp_local_ipaddr); } EXPORT_SYMBOL_GPL(iscsi_conn_teardown);
From: William Zhao wizhao@redhat.com
stable inclusion from linux-4.19.225 commit 6f1ce654347ad16977afcb315fd9a9114ed9739d
--------------------------------
[ Upstream commit c1833c3964d5bd8c163bd4e01736a38bc473cb8a ]
The "__ip6_tnl_parm" struct was left uninitialized causing an invalid load of random data when the "__ip6_tnl_parm" struct was used elsewhere. As an example, in the function "ip6_tnl_xmit_ctl()", it tries to access the "collect_md" member. With "__ip6_tnl_parm" being uninitialized and containing random data, the UBSAN detected that "collect_md" held a non-boolean value.
The UBSAN issue is as follows:
=============================================================== UBSAN: invalid-load in net/ipv6/ip6_tunnel.c:1025:14 load of value 30 is not a valid value for type '_Bool' CPU: 1 PID: 228 Comm: kworker/1:3 Not tainted 5.16.0-rc4+ #8 Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011 Workqueue: ipv6_addrconf addrconf_dad_work Call Trace: <TASK> dump_stack_lvl+0x44/0x57 ubsan_epilogue+0x5/0x40 __ubsan_handle_load_invalid_value+0x66/0x70 ? __cpuhp_setup_state+0x1d3/0x210 ip6_tnl_xmit_ctl.cold.52+0x2c/0x6f [ip6_tunnel] vti6_tnl_xmit+0x79c/0x1e96 [ip6_vti] ? lock_is_held_type+0xd9/0x130 ? vti6_rcv+0x100/0x100 [ip6_vti] ? lock_is_held_type+0xd9/0x130 ? rcu_read_lock_bh_held+0xc0/0xc0 ? lock_acquired+0x262/0xb10 dev_hard_start_xmit+0x1e6/0x820 __dev_queue_xmit+0x2079/0x3340 ? mark_lock.part.52+0xf7/0x1050 ? netdev_core_pick_tx+0x290/0x290 ? kvm_clock_read+0x14/0x30 ? kvm_sched_clock_read+0x5/0x10 ? sched_clock_cpu+0x15/0x200 ? find_held_lock+0x3a/0x1c0 ? lock_release+0x42f/0xc90 ? lock_downgrade+0x6b0/0x6b0 ? mark_held_locks+0xb7/0x120 ? neigh_connected_output+0x31f/0x470 ? lockdep_hardirqs_on+0x79/0x100 ? neigh_connected_output+0x31f/0x470 ? ip6_finish_output2+0x9b0/0x1d90 ? rcu_read_lock_bh_held+0x62/0xc0 ? ip6_finish_output2+0x9b0/0x1d90 ip6_finish_output2+0x9b0/0x1d90 ? ip6_append_data+0x330/0x330 ? ip6_mtu+0x166/0x370 ? __ip6_finish_output+0x1ad/0xfb0 ? nf_hook_slow+0xa6/0x170 ip6_output+0x1fb/0x710 ? nf_hook.constprop.32+0x317/0x430 ? ip6_finish_output+0x180/0x180 ? __ip6_finish_output+0xfb0/0xfb0 ? lock_is_held_type+0xd9/0x130 ndisc_send_skb+0xb33/0x1590 ? __sk_mem_raise_allocated+0x11cf/0x1560 ? dst_output+0x4a0/0x4a0 ? ndisc_send_rs+0x432/0x610 addrconf_dad_completed+0x30c/0xbb0 ? addrconf_rs_timer+0x650/0x650 ? addrconf_dad_work+0x73c/0x10e0 addrconf_dad_work+0x73c/0x10e0 ? addrconf_dad_completed+0xbb0/0xbb0 ? rcu_read_lock_sched_held+0xaf/0xe0 ? rcu_read_lock_bh_held+0xc0/0xc0 process_one_work+0x97b/0x1740 ? pwq_dec_nr_in_flight+0x270/0x270 worker_thread+0x87/0xbf0 ? process_one_work+0x1740/0x1740 kthread+0x3ac/0x490 ? set_kthread_struct+0x100/0x100 ret_from_fork+0x22/0x30 </TASK> ===============================================================
The solution is to initialize "__ip6_tnl_parm" struct to zeros in the "vti6_siocdevprivate()" function.
Signed-off-by: William Zhao wizhao@redhat.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- net/ipv6/ip6_vti.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index 290badfe70e0..866ce815625e 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c @@ -799,6 +799,8 @@ vti6_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) struct net *net = dev_net(dev); struct vti6_net *ip6n = net_generic(net, vti6_net_id);
+ memset(&p1, 0, sizeof(p1)); + switch (cmd) { case SIOCGETTUNNEL: if (dev == ip6n->fb_tnl_dev) {
From: Thomas Gleixner tglx@linutronix.de
stable inclusion from linux-4.19.226 commit 79305a826f872fe446c6fbf8450f515053ef6951
--------------------------------
commit bf74aa86e111aa3b2fbb25db37e3a3fab71b5b68 upstream.
This patch switches the timer to HRTIMER_MODE_SOFT, which executed the timer callback in softirq context and removes the hrtimer_tasklet.
Signed-off-by: Thomas Gleixner tglx@linutronix.de Signed-off-by: Anna-Maria Gleixner anna-maria@linutronix.de Acked-by: Oliver Hartkopp socketcan@hartkopp.net Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Ziyang Xuan william.xuanziyang@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- net/can/bcm.c | 156 +++++++++++++++++--------------------------------- 1 file changed, 52 insertions(+), 104 deletions(-)
diff --git a/net/can/bcm.c b/net/can/bcm.c index e66377e764ba..ffc34e911808 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c @@ -105,7 +105,6 @@ struct bcm_op { unsigned long frames_abs, frames_filtered; struct bcm_timeval ival1, ival2; struct hrtimer timer, thrtimer; - struct tasklet_struct tsklet, thrtsklet; ktime_t rx_stamp, kt_ival1, kt_ival2, kt_lastmsg; int rx_ifindex; int cfsiz; @@ -370,25 +369,34 @@ static void bcm_send_to_user(struct bcm_op *op, struct bcm_msg_head *head, } }
-static void bcm_tx_start_timer(struct bcm_op *op) +static bool bcm_tx_set_expiry(struct bcm_op *op, struct hrtimer *hrt) { + ktime_t ival; + if (op->kt_ival1 && op->count) - hrtimer_start(&op->timer, - ktime_add(ktime_get(), op->kt_ival1), - HRTIMER_MODE_ABS); + ival = op->kt_ival1; else if (op->kt_ival2) - hrtimer_start(&op->timer, - ktime_add(ktime_get(), op->kt_ival2), - HRTIMER_MODE_ABS); + ival = op->kt_ival2; + else + return false; + + hrtimer_set_expires(hrt, ktime_add(ktime_get(), ival)); + return true; }
-static void bcm_tx_timeout_tsklet(unsigned long data) +static void bcm_tx_start_timer(struct bcm_op *op) { - struct bcm_op *op = (struct bcm_op *)data; + if (bcm_tx_set_expiry(op, &op->timer)) + hrtimer_start_expires(&op->timer, HRTIMER_MODE_ABS_SOFT); +} + +/* bcm_tx_timeout_handler - performs cyclic CAN frame transmissions */ +static enum hrtimer_restart bcm_tx_timeout_handler(struct hrtimer *hrtimer) +{ + struct bcm_op *op = container_of(hrtimer, struct bcm_op, timer); struct bcm_msg_head msg_head;
if (op->kt_ival1 && (op->count > 0)) { - op->count--; if (!op->count && (op->flags & TX_COUNTEVT)) {
@@ -406,22 +414,12 @@ static void bcm_tx_timeout_tsklet(unsigned long data) } bcm_can_tx(op);
- } else if (op->kt_ival2) + } else if (op->kt_ival2) { bcm_can_tx(op); + }
- bcm_tx_start_timer(op); -} - -/* - * bcm_tx_timeout_handler - performs cyclic CAN frame transmissions - */ -static enum hrtimer_restart bcm_tx_timeout_handler(struct hrtimer *hrtimer) -{ - struct bcm_op *op = container_of(hrtimer, struct bcm_op, timer); - - tasklet_schedule(&op->tsklet); - - return HRTIMER_NORESTART; + return bcm_tx_set_expiry(op, &op->timer) ? + HRTIMER_RESTART : HRTIMER_NORESTART; }
/* @@ -488,7 +486,7 @@ static void bcm_rx_update_and_send(struct bcm_op *op, /* do not send the saved data - only start throttle timer */ hrtimer_start(&op->thrtimer, ktime_add(op->kt_lastmsg, op->kt_ival2), - HRTIMER_MODE_ABS); + HRTIMER_MODE_ABS_SOFT); return; }
@@ -547,14 +545,21 @@ static void bcm_rx_starttimer(struct bcm_op *op) return;
if (op->kt_ival1) - hrtimer_start(&op->timer, op->kt_ival1, HRTIMER_MODE_REL); + hrtimer_start(&op->timer, op->kt_ival1, HRTIMER_MODE_REL_SOFT); }
-static void bcm_rx_timeout_tsklet(unsigned long data) +/* bcm_rx_timeout_handler - when the (cyclic) CAN frame reception timed out */ +static enum hrtimer_restart bcm_rx_timeout_handler(struct hrtimer *hrtimer) { - struct bcm_op *op = (struct bcm_op *)data; + struct bcm_op *op = container_of(hrtimer, struct bcm_op, timer); struct bcm_msg_head msg_head;
+ /* if user wants to be informed, when cyclic CAN-Messages come back */ + if ((op->flags & RX_ANNOUNCE_RESUME) && op->last_frames) { + /* clear received CAN frames to indicate 'nothing received' */ + memset(op->last_frames, 0, op->nframes * op->cfsiz); + } + /* create notification to user */ memset(&msg_head, 0, sizeof(msg_head)); msg_head.opcode = RX_TIMEOUT; @@ -566,25 +571,6 @@ static void bcm_rx_timeout_tsklet(unsigned long data) msg_head.nframes = 0;
bcm_send_to_user(op, &msg_head, NULL, 0); -} - -/* - * bcm_rx_timeout_handler - when the (cyclic) CAN frame reception timed out - */ -static enum hrtimer_restart bcm_rx_timeout_handler(struct hrtimer *hrtimer) -{ - struct bcm_op *op = container_of(hrtimer, struct bcm_op, timer); - - /* schedule before NET_RX_SOFTIRQ */ - tasklet_hi_schedule(&op->tsklet); - - /* no restart of the timer is done here! */ - - /* if user wants to be informed, when cyclic CAN-Messages come back */ - if ((op->flags & RX_ANNOUNCE_RESUME) && op->last_frames) { - /* clear received CAN frames to indicate 'nothing received' */ - memset(op->last_frames, 0, op->nframes * op->cfsiz); - }
return HRTIMER_NORESTART; } @@ -592,14 +578,12 @@ static enum hrtimer_restart bcm_rx_timeout_handler(struct hrtimer *hrtimer) /* * bcm_rx_do_flush - helper for bcm_rx_thr_flush */ -static inline int bcm_rx_do_flush(struct bcm_op *op, int update, - unsigned int index) +static inline int bcm_rx_do_flush(struct bcm_op *op, unsigned int index) { struct canfd_frame *lcf = op->last_frames + op->cfsiz * index;
if ((op->last_frames) && (lcf->flags & RX_THR)) { - if (update) - bcm_rx_changed(op, lcf); + bcm_rx_changed(op, lcf); return 1; } return 0; @@ -607,11 +591,8 @@ static inline int bcm_rx_do_flush(struct bcm_op *op, int update,
/* * bcm_rx_thr_flush - Check for throttled data and send it to the userspace - * - * update == 0 : just check if throttled data is available (any irq context) - * update == 1 : check and send throttled data to userspace (soft_irq context) */ -static int bcm_rx_thr_flush(struct bcm_op *op, int update) +static int bcm_rx_thr_flush(struct bcm_op *op) { int updated = 0;
@@ -620,24 +601,16 @@ static int bcm_rx_thr_flush(struct bcm_op *op, int update)
/* for MUX filter we start at index 1 */ for (i = 1; i < op->nframes; i++) - updated += bcm_rx_do_flush(op, update, i); + updated += bcm_rx_do_flush(op, i);
} else { /* for RX_FILTER_ID and simple filter */ - updated += bcm_rx_do_flush(op, update, 0); + updated += bcm_rx_do_flush(op, 0); }
return updated; }
-static void bcm_rx_thr_tsklet(unsigned long data) -{ - struct bcm_op *op = (struct bcm_op *)data; - - /* push the changed data to the userspace */ - bcm_rx_thr_flush(op, 1); -} - /* * bcm_rx_thr_handler - the time for blocked content updates is over now: * Check for throttled data and send it to the userspace @@ -646,9 +619,7 @@ static enum hrtimer_restart bcm_rx_thr_handler(struct hrtimer *hrtimer) { struct bcm_op *op = container_of(hrtimer, struct bcm_op, thrtimer);
- tasklet_schedule(&op->thrtsklet); - - if (bcm_rx_thr_flush(op, 0)) { + if (bcm_rx_thr_flush(op)) { hrtimer_forward(hrtimer, ktime_get(), op->kt_ival2); return HRTIMER_RESTART; } else { @@ -744,23 +715,8 @@ static struct bcm_op *bcm_find_op(struct list_head *ops,
static void bcm_remove_op(struct bcm_op *op) { - if (op->tsklet.func) { - while (test_bit(TASKLET_STATE_SCHED, &op->tsklet.state) || - test_bit(TASKLET_STATE_RUN, &op->tsklet.state) || - hrtimer_active(&op->timer)) { - hrtimer_cancel(&op->timer); - tasklet_kill(&op->tsklet); - } - } - - if (op->thrtsklet.func) { - while (test_bit(TASKLET_STATE_SCHED, &op->thrtsklet.state) || - test_bit(TASKLET_STATE_RUN, &op->thrtsklet.state) || - hrtimer_active(&op->thrtimer)) { - hrtimer_cancel(&op->thrtimer); - tasklet_kill(&op->thrtsklet); - } - } + hrtimer_cancel(&op->timer); + hrtimer_cancel(&op->thrtimer);
if ((op->frames) && (op->frames != &op->sframe)) kfree(op->frames); @@ -994,15 +950,13 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, op->ifindex = ifindex;
/* initialize uninitialized (kzalloc) structure */ - hrtimer_init(&op->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hrtimer_init(&op->timer, CLOCK_MONOTONIC, + HRTIMER_MODE_REL_SOFT); op->timer.function = bcm_tx_timeout_handler;
- /* initialize tasklet for tx countevent notification */ - tasklet_init(&op->tsklet, bcm_tx_timeout_tsklet, - (unsigned long) op); - /* currently unused in tx_ops */ - hrtimer_init(&op->thrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hrtimer_init(&op->thrtimer, CLOCK_MONOTONIC, + HRTIMER_MODE_REL_SOFT);
/* add this bcm_op to the list of the tx_ops */ list_add(&op->list, &bo->tx_ops); @@ -1171,20 +1125,14 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, op->rx_ifindex = ifindex;
/* initialize uninitialized (kzalloc) structure */ - hrtimer_init(&op->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hrtimer_init(&op->timer, CLOCK_MONOTONIC, + HRTIMER_MODE_REL_SOFT); op->timer.function = bcm_rx_timeout_handler;
- /* initialize tasklet for rx timeout notification */ - tasklet_init(&op->tsklet, bcm_rx_timeout_tsklet, - (unsigned long) op); - - hrtimer_init(&op->thrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hrtimer_init(&op->thrtimer, CLOCK_MONOTONIC, + HRTIMER_MODE_REL_SOFT); op->thrtimer.function = bcm_rx_thr_handler;
- /* initialize tasklet for rx throttle handling */ - tasklet_init(&op->thrtsklet, bcm_rx_thr_tsklet, - (unsigned long) op); - /* add this bcm_op to the list of the rx_ops */ list_add(&op->list, &bo->rx_ops);
@@ -1230,12 +1178,12 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, */ op->kt_lastmsg = 0; hrtimer_cancel(&op->thrtimer); - bcm_rx_thr_flush(op, 1); + bcm_rx_thr_flush(op); }
if ((op->flags & STARTTIMER) && op->kt_ival1) hrtimer_start(&op->timer, op->kt_ival1, - HRTIMER_MODE_REL); + HRTIMER_MODE_REL_SOFT); }
/* now we can register for can_ids, if we added a new bcm_op */
From: Gang Li ligang.bdlg@bytedance.com
stable inclusion from linux-4.19.226 commit 9a3354fc78b7d7a79026053272bb0b74900c28c1
--------------------------------
commit 62c9827cbb996c2c04f615ecd783ce28bcea894b upstream.
Fix a data race in commit 779750d20b93 ("shmem: split huge pages beyond i_size under memory pressure").
Here are call traces causing race:
Call Trace 1: shmem_unused_huge_shrink+0x3ae/0x410 ? __list_lru_walk_one.isra.5+0x33/0x160 super_cache_scan+0x17c/0x190 shrink_slab.part.55+0x1ef/0x3f0 shrink_node+0x10e/0x330 kswapd+0x380/0x740 kthread+0xfc/0x130 ? mem_cgroup_shrink_node+0x170/0x170 ? kthread_create_on_node+0x70/0x70 ret_from_fork+0x1f/0x30
Call Trace 2: shmem_evict_inode+0xd8/0x190 evict+0xbe/0x1c0 do_unlinkat+0x137/0x330 do_syscall_64+0x76/0x120 entry_SYSCALL_64_after_hwframe+0x3d/0xa2
A simple explanation:
Image there are 3 items in the local list (@list). In the first traversal, A is not deleted from @list.
1) A->B->C ^ | pos (leave)
In the second traversal, B is deleted from @list. Concurrently, A is deleted from @list through shmem_evict_inode() since last reference counter of inode is dropped by other thread. Then the @list is corrupted.
2) A->B->C ^ ^ | | evict pos (drop)
We should make sure the inode is either on the global list or deleted from any local list before iput().
Fixed by moving inodes back to global list before we put them.
[akpm@linux-foundation.org: coding style fixes]
Link: https://lkml.kernel.org/r/20211125064502.99983-1-ligang.bdlg@bytedance.com Fixes: 779750d20b93 ("shmem: split huge pages beyond i_size under memory pressure") Signed-off-by: Gang Li ligang.bdlg@bytedance.com Reviewed-by: Muchun Song songmuchun@bytedance.com Acked-by: Kirill A. Shutemov kirill.shutemov@linux.intel.com Cc: Hugh Dickins hughd@google.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- mm/shmem.c | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-)
diff --git a/mm/shmem.c b/mm/shmem.c index bc62dc732781..4363dbc8d57e 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -541,7 +541,7 @@ static unsigned long shmem_unused_huge_shrink(struct shmem_sb_info *sbinfo, struct shmem_inode_info *info; struct page *page; unsigned long batch = sc ? sc->nr_to_scan : 128; - int removed = 0, split = 0; + int split = 0;
if (list_empty(&sbinfo->shrinklist)) return SHRINK_STOP; @@ -556,7 +556,6 @@ static unsigned long shmem_unused_huge_shrink(struct shmem_sb_info *sbinfo, /* inode is about to be evicted */ if (!inode) { list_del_init(&info->shrinklist); - removed++; goto next; }
@@ -564,12 +563,12 @@ static unsigned long shmem_unused_huge_shrink(struct shmem_sb_info *sbinfo, if (round_up(inode->i_size, PAGE_SIZE) == round_up(inode->i_size, HPAGE_PMD_SIZE)) { list_move(&info->shrinklist, &to_remove); - removed++; goto next; }
list_move(&info->shrinklist, &list); next: + sbinfo->shrinklist_len--; if (!--batch) break; } @@ -589,7 +588,7 @@ static unsigned long shmem_unused_huge_shrink(struct shmem_sb_info *sbinfo, inode = &info->vfs_inode;
if (nr_to_split && split >= nr_to_split) - goto leave; + goto move_back;
page = find_get_page(inode->i_mapping, (inode->i_size & HPAGE_PMD_MASK) >> PAGE_SHIFT); @@ -603,38 +602,44 @@ static unsigned long shmem_unused_huge_shrink(struct shmem_sb_info *sbinfo, }
/* - * Leave the inode on the list if we failed to lock - * the page at this time. + * Move the inode on the list back to shrinklist if we failed + * to lock the page at this time. * * Waiting for the lock may lead to deadlock in the * reclaim path. */ if (!trylock_page(page)) { put_page(page); - goto leave; + goto move_back; }
ret = split_huge_page(page); unlock_page(page); put_page(page);
- /* If split failed leave the inode on the list */ + /* If split failed move the inode on the list back to shrinklist */ if (ret) - goto leave; + goto move_back;
split++; drop: list_del_init(&info->shrinklist); - removed++; -leave: + goto put; +move_back: + /* + * Make sure the inode is either on the global list or deleted + * from any local list before iput() since it could be deleted + * in another thread once we put the inode (then the local list + * is corrupted). + */ + spin_lock(&sbinfo->shrinklist_lock); + list_move(&info->shrinklist, &sbinfo->shrinklist); + sbinfo->shrinklist_len++; + spin_unlock(&sbinfo->shrinklist_lock); +put: iput(inode); }
- spin_lock(&sbinfo->shrinklist_lock); - list_splice_tail(&list, &sbinfo->shrinklist); - sbinfo->shrinklist_len -= removed; - spin_unlock(&sbinfo->shrinklist_lock); - return split; }
From: Chengfeng Ye cyeaa@connect.ust.hk
stable inclusion from linux-4.19.226 commit 1aa6bac2dc1bce5f6afbb095c0ace374cc653947
--------------------------------
[ Upstream commit b4cb4d31631912842eb7dce02b4350cbb7562d5e ]
Pointer base points to sub field of tmpl, it is dereferenced after tmpl is freed. Fix this by accessing base before free tmpl.
Fixes: ec8f5d8f ("crypto: qce - Qualcomm crypto engine driver") Signed-off-by: Chengfeng Ye cyeaa@connect.ust.hk Acked-by: Thara Gopinath thara.gopinath@linaro.org Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- drivers/crypto/qce/sha.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/crypto/qce/sha.c b/drivers/crypto/qce/sha.c index d8a5db11b7ea..bffd4d15145d 100644 --- a/drivers/crypto/qce/sha.c +++ b/drivers/crypto/qce/sha.c @@ -521,8 +521,8 @@ static int qce_ahash_register_one(const struct qce_ahash_def *def,
ret = crypto_register_ahash(alg); if (ret) { - kfree(tmpl); dev_err(qce->dev, "%s registration failed\n", base->cra_name); + kfree(tmpl); return ret; }
From: Florian Westphal fw@strlen.de
stable inclusion from linux-4.19.226 commit 519f563eca1b89965dd406a8f9807ca76562d202
--------------------------------
[ Upstream commit 28b78ecffea8078d81466b2e01bb5a154509f1ba ]
This makes 'bridge-nf-filter-pppoe-tagged' sysctl work for bridged traffic.
Looking at the original commit it doesn't appear this ever worked:
static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb, [..] if (skb->protocol == htons(ETH_P_8021Q)) { skb_pull(skb, VLAN_HLEN); skb->network_header += VLAN_HLEN; + } else if (skb->protocol == htons(ETH_P_PPP_SES)) { + skb_pull(skb, PPPOE_SES_HLEN); + skb->network_header += PPPOE_SES_HLEN; } [..] NF_HOOK(... POST_ROUTING, ...)
... but the adjusted offsets are never restored.
The alternative would be to rip this code out for good, but otoh we'd have to keep this anyway for the vlan handling (which works because vlan tag info is in the skb, not the packet payload).
Reported-and-tested-by: Amish Chana amish@3g.co.za Fixes: 516299d2f5b6f97 ("[NETFILTER]: bridge-nf: filter bridged IPv4/IPv6 encapsulated in pppoe traffic") Signed-off-by: Florian Westphal fw@strlen.de Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- net/bridge/br_netfilter_hooks.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c index a403179eea49..fd5e3470560a 100644 --- a/net/bridge/br_netfilter_hooks.c +++ b/net/bridge/br_netfilter_hooks.c @@ -727,6 +727,9 @@ static int br_nf_dev_queue_xmit(struct net *net, struct sock *sk, struct sk_buff if (nf_bridge->frag_max_size && nf_bridge->frag_max_size < mtu) mtu = nf_bridge->frag_max_size;
+ nf_bridge_update_protocol(skb); + nf_bridge_push_encap_header(skb); + if (skb_is_gso(skb) || skb->len + mtu_reserved <= mtu) { nf_bridge_info_free(skb); return br_dev_queue_push_xmit(net, sk, skb); @@ -744,8 +747,6 @@ static int br_nf_dev_queue_xmit(struct net *net, struct sock *sk, struct sk_buff
IPCB(skb)->frag_max_size = nf_bridge->frag_max_size;
- nf_bridge_update_protocol(skb); - data = this_cpu_ptr(&brnf_frag_data_storage);
data->vlan_tci = skb->vlan_tci; @@ -768,8 +769,6 @@ static int br_nf_dev_queue_xmit(struct net *net, struct sock *sk, struct sk_buff
IP6CB(skb)->frag_max_size = nf_bridge->frag_max_size;
- nf_bridge_update_protocol(skb); - data = this_cpu_ptr(&brnf_frag_data_storage); data->encap_size = nf_bridge_encap_header_len(skb); data->size = ETH_HLEN + data->encap_size;
From: Lizhi Hou lizhi.hou@xilinx.com
stable inclusion from linux-4.19.226 commit 628c2372100a118f5500f596c5c941720adbcc28
--------------------------------
[ Upstream commit 3672fb65155530b5eea6225685c75329b6debec3 ]
The base address of uartlite registers could be 64 bit address which is from device resource. When ulite_probe() calls ulite_assign(), this 64 bit address is casted to 32-bit. The fix is to replace "u32" type with "phys_addr_t" type for the base address in ulite_assign() argument list.
Fixes: 8fa7b6100693 ("[POWERPC] Uartlite: Separate the bus binding from the driver proper") Signed-off-by: Lizhi Hou lizhi.hou@xilinx.com Link: https://lore.kernel.org/r/20211129202302.1319033-1-lizhi.hou@xilinx.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- drivers/tty/serial/uartlite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c index 8df305822668..5d1b7455e627 100644 --- a/drivers/tty/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c @@ -618,7 +618,7 @@ static struct uart_driver ulite_uart_driver = { * * Returns: 0 on success, <0 otherwise */ -static int ulite_assign(struct device *dev, int id, u32 base, int irq, +static int ulite_assign(struct device *dev, int id, phys_addr_t base, int irq, struct uartlite_data *pdata) { struct uart_port *port;
From: Lino Sanfilippo LinoSanfilippo@gmx.de
stable inclusion from linux-4.19.226 commit 0d9a1f0245ed6cadb37fabdf204b67f230160ca0
--------------------------------
[ Upstream commit d1180405c7b5c7a1c6bde79d5fc24fe931430737 ]
With commit 3873e2d7f63a ("drivers: PL011: refactor pl011_probe()") the function devm_ioremap() called from pl011_setup_port() was replaced with devm_ioremap_resource(). Since this function not only remaps but also requests the ports io memory region it now collides with the .config_port() callback which requests the same region at uart port registration.
Since devm_ioremap_resource() already claims the memory successfully, the request in .config_port() fails.
Later at uart port deregistration the attempt to release the unclaimed memory also fails. The failure results in a “Trying to free nonexistent resource" warning.
Fix these issues by removing the callbacks that implement the redundant memory allocation/release. Also make sure that changing the drivers io memory base address via TIOCSSERIAL is not allowed any more.
Fixes: 3873e2d7f63a ("drivers: PL011: refactor pl011_probe()") Signed-off-by: Lino Sanfilippo LinoSanfilippo@gmx.de Link: https://lore.kernel.org/r/20211129174238.8333-1-LinoSanfilippo@gmx.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- drivers/tty/serial/amba-pl011.c | 27 +++------------------------ 1 file changed, 3 insertions(+), 24 deletions(-)
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 1d27e006826d..aae97acd183a 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -2160,32 +2160,13 @@ static const char *pl011_type(struct uart_port *port) return uap->port.type == PORT_AMBA ? uap->type : NULL; }
-/* - * Release the memory region(s) being used by 'port' - */ -static void pl011_release_port(struct uart_port *port) -{ - release_mem_region(port->mapbase, SZ_4K); -} - -/* - * Request the memory region(s) being used by 'port' - */ -static int pl011_request_port(struct uart_port *port) -{ - return request_mem_region(port->mapbase, SZ_4K, "uart-pl011") - != NULL ? 0 : -EBUSY; -} - /* * Configure/autoconfigure the port. */ static void pl011_config_port(struct uart_port *port, int flags) { - if (flags & UART_CONFIG_TYPE) { + if (flags & UART_CONFIG_TYPE) port->type = PORT_AMBA; - pl011_request_port(port); - } }
/* @@ -2200,6 +2181,8 @@ static int pl011_verify_port(struct uart_port *port, struct serial_struct *ser) ret = -EINVAL; if (ser->baud_base < 9600) ret = -EINVAL; + if (port->mapbase != (unsigned long) ser->iomem_base) + ret = -EINVAL; return ret; }
@@ -2217,8 +2200,6 @@ static const struct uart_ops amba_pl011_pops = { .flush_buffer = pl011_dma_flush_buffer, .set_termios = pl011_set_termios, .type = pl011_type, - .release_port = pl011_release_port, - .request_port = pl011_request_port, .config_port = pl011_config_port, .verify_port = pl011_verify_port, #ifdef CONFIG_CONSOLE_POLL @@ -2248,8 +2229,6 @@ static const struct uart_ops sbsa_uart_pops = { .shutdown = sbsa_uart_shutdown, .set_termios = sbsa_uart_set_termios, .type = pl011_type, - .release_port = pl011_release_port, - .request_port = pl011_request_port, .config_port = pl011_config_port, .verify_port = pl011_verify_port, #ifdef CONFIG_CONSOLE_POLL
From: Li Hua hucool.lihua@huawei.com
stable inclusion from linux-4.19.226 commit e6bc7279b16517fab9ed3cdbd58ad7b08060c246
--------------------------------
[ Upstream commit 9b58e976b3b391c0cf02e038d53dd0478ed3013c ]
When rt_runtime is modified from -1 to a valid control value, it may cause the task to be throttled all the time. Operations like the following will trigger the bug. E.g:
1. echo -1 > /proc/sys/kernel/sched_rt_runtime_us 2. Run a FIFO task named A that executes while(1) 3. echo 950000 > /proc/sys/kernel/sched_rt_runtime_us
When rt_runtime is -1, The rt period timer will not be activated when task A enqueued. And then the task will be throttled after setting rt_runtime to 950,000. The task will always be throttled because the rt period timer is not activated.
Fixes: d0b27fa77854 ("sched: rt-group: synchonised bandwidth period") Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Li Hua hucool.lihua@huawei.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/20211203033618.11895-1-hucool.lihua@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- kernel/sched/rt.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-)
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index 5a9c27956792..301ba04d9130 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c @@ -50,11 +50,8 @@ void init_rt_bandwidth(struct rt_bandwidth *rt_b, u64 period, u64 runtime) rt_b->rt_period_timer.function = sched_rt_period_timer; }
-static void start_rt_bandwidth(struct rt_bandwidth *rt_b) +static inline void do_start_rt_bandwidth(struct rt_bandwidth *rt_b) { - if (!rt_bandwidth_enabled() || rt_b->rt_runtime == RUNTIME_INF) - return; - raw_spin_lock(&rt_b->rt_runtime_lock); if (!rt_b->rt_period_active) { rt_b->rt_period_active = 1; @@ -72,6 +69,14 @@ static void start_rt_bandwidth(struct rt_bandwidth *rt_b) raw_spin_unlock(&rt_b->rt_runtime_lock); }
+static void start_rt_bandwidth(struct rt_bandwidth *rt_b) +{ + if (!rt_bandwidth_enabled() || rt_b->rt_runtime == RUNTIME_INF) + return; + + do_start_rt_bandwidth(rt_b); +} + void init_rt_rq(struct rt_rq *rt_rq) { struct rt_prio_array *array; @@ -979,13 +984,17 @@ static void update_curr_rt(struct rq *rq)
for_each_sched_rt_entity(rt_se) { struct rt_rq *rt_rq = rt_rq_of_se(rt_se); + int exceeded;
if (sched_rt_runtime(rt_rq) != RUNTIME_INF) { raw_spin_lock(&rt_rq->rt_runtime_lock); rt_rq->rt_time += delta_exec; - if (sched_rt_runtime_exceeded(rt_rq)) + exceeded = sched_rt_runtime_exceeded(rt_rq); + if (exceeded) resched_curr(rq); raw_spin_unlock(&rt_rq->rt_runtime_lock); + if (exceeded) + do_start_rt_bandwidth(sched_rt_bandwidth(rt_rq)); } } } @@ -2654,8 +2663,12 @@ static int sched_rt_global_validate(void)
static void sched_rt_do_global(void) { + unsigned long flags; + + raw_spin_lock_irqsave(&def_rt_bandwidth.rt_runtime_lock, flags); def_rt_bandwidth.rt_runtime = global_rt_runtime(); def_rt_bandwidth.rt_period = ns_to_ktime(global_rt_period()); + raw_spin_unlock_irqrestore(&def_rt_bandwidth.rt_runtime_lock, flags); }
int sched_rt_handler(struct ctl_table *table, int write,
From: Eric Dumazet edumazet@google.com
stable inclusion from linux-4.19.226 commit fcb8f503d607d18b9fc69613e38358aae9f9fa99
--------------------------------
[ Upstream commit 7770a39d7c63faec6c4f33666d49a8cb664d0482 ]
copy_user_offload() will actually push a struct struct xfrm_user_offload, which is different than (struct xfrm_state *)->xso (struct xfrm_state_offload)
Fixes: d77e38e612a01 ("xfrm: Add an IPsec hardware offloading API") Signed-off-by: Eric Dumazet edumazet@google.com Cc: Steffen Klassert steffen.klassert@secunet.com Signed-off-by: Steffen Klassert steffen.klassert@secunet.com Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- net/xfrm/xfrm_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index f94abe1fdd58..87932f6ad9d7 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -2813,7 +2813,7 @@ static inline unsigned int xfrm_sa_len(struct xfrm_state *x) if (x->props.extra_flags) l += nla_total_size(sizeof(x->props.extra_flags)); if (x->xso.dev) - l += nla_total_size(sizeof(x->xso)); + l += nla_total_size(sizeof(struct xfrm_user_offload)); if (x->props.smark.v | x->props.smark.m) { l += nla_total_size(sizeof(x->props.smark.v)); l += nla_total_size(sizeof(x->props.smark.m));
From: Nicolas Toromanoff nicolas.toromanoff@foss.st.com
stable inclusion from linux-4.19.226 commit a803ac39fb163677b4eaf5317894a3dd62912b56
--------------------------------
[ Upstream commit 6c12e742785bf9333faf60bfb96575bdd763448e ]
Delete extraneous lines in probe error handling code: pm was disabled twice.
Fixes: 65f9aa36ee47 ("crypto: stm32/cryp - Add power management support")
Reported-by: Marek Vasut marex@denx.de Signed-off-by: Nicolas Toromanoff nicolas.toromanoff@foss.st.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- drivers/crypto/stm32/stm32-cryp.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/drivers/crypto/stm32/stm32-cryp.c b/drivers/crypto/stm32/stm32-cryp.c index 23b0b7bd64c7..b3b49dce1136 100644 --- a/drivers/crypto/stm32/stm32-cryp.c +++ b/drivers/crypto/stm32/stm32-cryp.c @@ -2036,8 +2036,6 @@ static int stm32_cryp_probe(struct platform_device *pdev) list_del(&cryp->list); spin_unlock(&cryp_list.lock);
- pm_runtime_disable(dev); - pm_runtime_put_noidle(dev); pm_runtime_disable(dev); pm_runtime_put_noidle(dev);
From: Antony Antony antony.antony@secunet.com
stable inclusion from linux-4.19.226 commit f7594c07fb0270c5414460432d3344b8831789c2
--------------------------------
[ Upstream commit 8dce43919566f06e865f7e8949f5c10d8c2493f5 ]
xfrm interface if_id = 0 would cause xfrm policy lookup errors since Commit 9f8550e4bd9d.
Now explicitly fail to create an xfrm interface when if_id = 0
With this commit: ip link add ipsec0 type xfrm dev lo if_id 0 Error: if_id must be non zero.
v1->v2 change: - add Fixes: tag
Fixes: 9f8550e4bd9d ("xfrm: fix disable_xfrm sysctl when used on xfrm interfaces") Signed-off-by: Antony Antony antony.antony@secunet.com Reviewed-by: Eyal Birger eyal.birger@gmail.com Signed-off-by: Steffen Klassert steffen.klassert@secunet.com Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- net/xfrm/xfrm_interface.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/net/xfrm/xfrm_interface.c b/net/xfrm/xfrm_interface.c index 9dd43319b2c0..6bfd7b8249da 100644 --- a/net/xfrm/xfrm_interface.c +++ b/net/xfrm/xfrm_interface.c @@ -662,11 +662,16 @@ static int xfrmi_newlink(struct net *src_net, struct net_device *dev, struct netlink_ext_ack *extack) { struct net *net = dev_net(dev); - struct xfrm_if_parms p; + struct xfrm_if_parms p = {}; struct xfrm_if *xi; int err;
xfrmi_netlink_parms(data, &p); + if (!p.if_id) { + NL_SET_ERR_MSG(extack, "if_id must be non zero"); + return -EINVAL; + } + xi = xfrmi_locate(net, &p); if (xi) return -EEXIST; @@ -691,7 +696,12 @@ static int xfrmi_changelink(struct net_device *dev, struct nlattr *tb[], { struct xfrm_if *xi = netdev_priv(dev); struct net *net = xi->net; - struct xfrm_if_parms p; + struct xfrm_if_parms p = {}; + + if (!p.if_id) { + NL_SET_ERR_MSG(extack, "if_id must be non zero"); + return -EINVAL; + }
xfrmi_netlink_parms(data, &p); xi = xfrmi_locate(net, &p);
From: Antony Antony antony.antony@secunet.com
stable inclusion from linux-4.19.226 commit a6ea2625df628d4d18b86f6ee21835c8962c8f23
--------------------------------
[ Upstream commit 68ac0f3810e76a853b5f7b90601a05c3048b8b54 ]
xfrm ineterface does not allow xfrm if_id = 0 fail to create or update xfrm state and policy.
With this commit: ip xfrm policy add src 192.0.2.1 dst 192.0.2.2 dir out if_id 0 RTNETLINK answers: Invalid argument
ip xfrm state add src 192.0.2.1 dst 192.0.2.2 proto esp spi 1 \ reqid 1 mode tunnel aead 'rfc4106(gcm(aes))' \ 0x1111111111111111111111111111111111111111 96 if_id 0 RTNETLINK answers: Invalid argument
v1->v2 change: - add Fixes: tag
Fixes: 9f8550e4bd9d ("xfrm: fix disable_xfrm sysctl when used on xfrm interfaces") Signed-off-by: Antony Antony antony.antony@secunet.com Signed-off-by: Steffen Klassert steffen.klassert@secunet.com Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- net/xfrm/xfrm_user.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 87932f6ad9d7..8d8f9e778cd4 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -620,8 +620,13 @@ static struct xfrm_state *xfrm_state_construct(struct net *net,
xfrm_smark_init(attrs, &x->props.smark);
- if (attrs[XFRMA_IF_ID]) + if (attrs[XFRMA_IF_ID]) { x->if_id = nla_get_u32(attrs[XFRMA_IF_ID]); + if (!x->if_id) { + err = -EINVAL; + goto error; + } + }
err = __xfrm_init_state(x, false, attrs[XFRMA_OFFLOAD_DEV]); if (err) @@ -1327,8 +1332,13 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
mark = xfrm_mark_get(attrs, &m);
- if (attrs[XFRMA_IF_ID]) + if (attrs[XFRMA_IF_ID]) { if_id = nla_get_u32(attrs[XFRMA_IF_ID]); + if (!if_id) { + err = -EINVAL; + goto out_noput; + } + }
if (p->info.seq) { x = xfrm_find_acq_byseq(net, mark, p->info.seq); @@ -1630,8 +1640,13 @@ static struct xfrm_policy *xfrm_policy_construct(struct net *net, struct xfrm_us
xfrm_mark_get(attrs, &xp->mark);
- if (attrs[XFRMA_IF_ID]) + if (attrs[XFRMA_IF_ID]) { xp->if_id = nla_get_u32(attrs[XFRMA_IF_ID]); + if (!xp->if_id) { + err = -EINVAL; + goto error; + } + }
return xp; error:
From: Xin Xiong xiongx18@fudan.edu.cn
stable inclusion from linux-4.19.226 commit f0351a2178fa64f87e609c341f07bf4260b10daf
--------------------------------
[ Upstream commit d94a69cb2cfa77294921aae9afcfb866e723a2da ]
The issue takes place in one error path of clusterip_tg_check(). When memcmp() returns nonzero, the function simply returns the error code, forgetting to decrease the reference count of a clusterip_config object, which is bumped earlier by clusterip_config_find_get(). This may incur reference count leak.
Fix this issue by decrementing the refcount of the object in specific error path.
Fixes: 06aa151ad1fc74 ("netfilter: ipt_CLUSTERIP: check MAC address when duplicate config is set") Signed-off-by: Xin Xiong xiongx18@fudan.edu.cn Signed-off-by: Xiyu Yang xiyuyang19@fudan.edu.cn Signed-off-by: Xin Tan tanxin.ctf@gmail.com Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- net/ipv4/netfilter/ipt_CLUSTERIP.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index 2c11050d679b..08297d3504cf 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c @@ -509,8 +509,11 @@ static int clusterip_tg_check(const struct xt_tgchk_param *par) if (IS_ERR(config)) return PTR_ERR(config); } - } else if (memcmp(&config->clustermac, &cipinfo->clustermac, ETH_ALEN)) + } else if (memcmp(&config->clustermac, &cipinfo->clustermac, ETH_ALEN)) { + clusterip_config_entry_put(config); + clusterip_config_put(config); return -EINVAL; + }
ret = nf_ct_netns_get(par->net, par->family); if (ret < 0) {
From: Chen Jun chenjun102@huawei.com
stable inclusion from linux-4.19.226 commit f155b0fbde518857ee2d42f1fbfda6bdf0123363
--------------------------------
[ Upstream commit 0ef333f5ba7f24f5d8478425c163d3097f1c7afd ]
Locality is not appropriately requested before writing the int mask. Add the missing boilerplate.
Fixes: e6aef069b6e9 ("tpm_tis: convert to using locality callbacks") Signed-off-by: Chen Jun chenjun102@huawei.com Reviewed-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- drivers/char/tpm/tpm_tis_core.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index 0aade05f47fa..a8e8289e0b35 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -918,7 +918,15 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT; intmask &= ~TPM_GLOBAL_INT_ENABLE; + + rc = request_locality(chip, 0); + if (rc < 0) { + rc = -ENODEV; + goto out_err; + } + tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask); + release_locality(chip, 0);
rc = tpm2_probe(chip); if (rc)
From: Pavel Skripkin paskripkin@gmail.com
stable inclusion from linux-4.19.226 commit e0b2cd310d0859907a9a7b4e4ef9a5bcce9d3d6d
--------------------------------
[ Upstream commit d668769eb9c52b150753f1653f7f5a0aeb8239d2 ]
Syzbot reported uninit value in mcs7830_bind(). The problem was in missing validation check for bytes read via usbnet_read_cmd().
usbnet_read_cmd() internally calls usb_control_msg(), that returns number of bytes read. Code should validate that requested number of bytes was actually read.
So, this patch adds missing size validation check inside mcs7830_get_reg() to prevent uninit value bugs
Reported-and-tested-by: syzbot+003c0a286b9af5412510@syzkaller.appspotmail.com Fixes: 2a36d7083438 ("USB: driver for mcs7830 (aka DeLOCK) USB ethernet adapter") Signed-off-by: Pavel Skripkin paskripkin@gmail.com Reviewed-by: Arnd Bergmann arnd@arndb.de Link: https://lore.kernel.org/r/20220106225716.7425-1-paskripkin@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- drivers/net/usb/mcs7830.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c index 5a47e5510ca8..c0f52a622964 100644 --- a/drivers/net/usb/mcs7830.c +++ b/drivers/net/usb/mcs7830.c @@ -121,8 +121,16 @@ static const char driver_name[] = "MOSCHIP usb-ethernet driver";
static int mcs7830_get_reg(struct usbnet *dev, u16 index, u16 size, void *data) { - return usbnet_read_cmd(dev, MCS7830_RD_BREQ, MCS7830_RD_BMREQ, - 0x0000, index, data, size); + int ret; + + ret = usbnet_read_cmd(dev, MCS7830_RD_BREQ, MCS7830_RD_BMREQ, + 0x0000, index, data, size); + if (ret < 0) + return ret; + else if (ret < size) + return -ENODATA; + + return ret; }
static int mcs7830_set_reg(struct usbnet *dev, u16 index, u16 size, const void *data)
From: Jan Kara jack@suse.cz
stable inclusion from linux-4.19.226 commit 1105c2dac8cb45c297401e32884cbefc0f123301
--------------------------------
[ Upstream commit 173b6e383d2a204c9921ffc1eca3b87aa2106c33 ]
A user reported FITRIM ioctl failing for him on ext4 on some devices without apparent reason. After some debugging we've found out that these devices (being LVM volumes) report rather large discard granularity of 42MB and the filesystem had 1k blocksize and thus group size of 8MB. Because ext4 FITRIM implementation puts discard granularity into minlen, ext4_trim_fs() declared the trim request as invalid. However just silently doing nothing seems to be a more appropriate reaction to such combination of parameters since user did not specify anything wrong.
CC: Lukas Czerner lczerner@redhat.com Fixes: 5c2ed62fd447 ("ext4: Adjust minlen with discard_granularity in the FITRIM ioctl") Signed-off-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20211112152202.26614-1-jack@suse.cz Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- fs/ext4/ioctl.c | 2 -- fs/ext4/mballoc.c | 8 ++++++++ 2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index c6cac2d40f71..3c8324715e65 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c @@ -1056,8 +1056,6 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) sizeof(range))) return -EFAULT;
- range.minlen = max((unsigned int)range.minlen, - q->limits.discard_granularity); ret = ext4_trim_fs(sb, &range); if (ret < 0) return ret; diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 69ed137d07a9..990fe7eed6bf 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -5262,6 +5262,7 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group, */ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) { + struct request_queue *q = bdev_get_queue(sb->s_bdev); struct ext4_group_info *grp; ext4_group_t group, first_group, last_group; ext4_grpblk_t cnt = 0, first_cluster, last_cluster; @@ -5280,6 +5281,13 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) start >= max_blks || range->len < sb->s_blocksize) return -EINVAL; + /* No point to try to trim less than discard granularity */ + if (range->minlen < q->limits.discard_granularity) { + minlen = EXT4_NUM_B2C(EXT4_SB(sb), + q->limits.discard_granularity >> sb->s_blocksize_bits); + if (minlen > EXT4_CLUSTERS_PER_GROUP(sb)) + goto out; + } if (end >= max_blks) end = max_blks - 1; if (end <= first_data_blk)
From: Hector Martin marcan@marcan.st
stable inclusion from linux-4.19.226 commit 4208239d748b5a8f32d5c2323d6f385dcb7f9b9e
--------------------------------
[ Upstream commit 9abe2ac834851a7d0b0756e295cf7a292c45ca53 ]
Table descriptors were being installed without properly formatting the address using paddr_to_iopte, which does not match up with the iopte_deref in __arm_lpae_map. This is incorrect for the LPAE pte format, as it does not handle the high bits properly.
This was found on Apple T6000 DARTs, which require a new pte format (different shift); adding support for that to paddr_to_iopte/iopte_to_paddr caused it to break badly, as even <48-bit addresses would end up incorrect in that case.
Fixes: 6c89928ff7a0 ("iommu/io-pgtable-arm: Support 52-bit physical address") Acked-by: Robin Murphy robin.murphy@arm.com Signed-off-by: Hector Martin marcan@marcan.st Link: https://lore.kernel.org/r/20211120031343.88034-1-marcan@marcan.st Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- drivers/iommu/io-pgtable-arm.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index efd6e994678f..3f99077b3611 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -299,11 +299,12 @@ static int arm_lpae_init_pte(struct arm_lpae_io_pgtable *data, static arm_lpae_iopte arm_lpae_install_table(arm_lpae_iopte *table, arm_lpae_iopte *ptep, arm_lpae_iopte curr, - struct io_pgtable_cfg *cfg) + struct arm_lpae_io_pgtable *data) { arm_lpae_iopte old, new; + struct io_pgtable_cfg *cfg = &data->iop.cfg;
- new = __pa(table) | ARM_LPAE_PTE_TYPE_TABLE; + new = paddr_to_iopte(__pa(table), data) | ARM_LPAE_PTE_TYPE_TABLE; if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS) new |= ARM_LPAE_PTE_NSTABLE;
@@ -354,7 +355,7 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova, if (!cptep) return -ENOMEM;
- pte = arm_lpae_install_table(cptep, ptep, 0, cfg); + pte = arm_lpae_install_table(cptep, ptep, 0, data); if (pte) __arm_lpae_free_pages(cptep, tblsz, cfg); } else if (!cfg->coherent_walk && !(pte & ARM_LPAE_PTE_SW_SYNC)) { @@ -513,7 +514,7 @@ static size_t arm_lpae_split_blk_unmap(struct arm_lpae_io_pgtable *data, __arm_lpae_init_pte(data, blk_paddr, pte, lvl, &tablep[i]); }
- pte = arm_lpae_install_table(tablep, ptep, blk_pte, cfg); + pte = arm_lpae_install_table(tablep, ptep, blk_pte, data); if (pte != blk_pte) { __arm_lpae_free_pages(tablep, tablesz, cfg); /*
From: Bart Van Assche bvanassche@acm.org
stable inclusion from linux-4.19.226 commit 5e7fb994ccc7200e20d7f394aa3f082f4efb49ab
--------------------------------
[ Upstream commit 21ad0e49085deb22c094f91f9da57319a97188e4 ]
The driver data pointer must be set before any callbacks are registered that use that pointer. Hence move the initialization of that pointer from after the ufshcd_init() call to inside ufshcd_init().
Link: https://lore.kernel.org/r/20211203231950.193369-7-bvanassche@acm.org Fixes: 3b1d05807a9a ("[SCSI] ufs: Segregate PCI Specific Code") Reported-by: Alexey Dobriyan adobriyan@gmail.com Tested-by: Bean Huo beanhuo@micron.com Reviewed-by: Bean Huo beanhuo@micron.com Signed-off-by: Bart Van Assche bvanassche@acm.org Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- drivers/scsi/ufs/tc-dwc-g210-pci.c | 1 - drivers/scsi/ufs/ufshcd-pltfrm.c | 2 -- drivers/scsi/ufs/ufshcd.c | 7 +++++++ 3 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/ufs/tc-dwc-g210-pci.c b/drivers/scsi/ufs/tc-dwc-g210-pci.c index 2f41722a8c28..2c6cb7f6b61a 100644 --- a/drivers/scsi/ufs/tc-dwc-g210-pci.c +++ b/drivers/scsi/ufs/tc-dwc-g210-pci.c @@ -138,7 +138,6 @@ tc_dwc_g210_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) return err; }
- pci_set_drvdata(pdev, hba); pm_runtime_put_noidle(&pdev->dev); pm_runtime_allow(&pdev->dev);
diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index 30c22e16b1e3..57985841a879 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -348,8 +348,6 @@ int ufshcd_pltfrm_init(struct platform_device *pdev, goto dealloc_host; }
- platform_set_drvdata(pdev, hba); - pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev);
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 3d9bfa520768..2082907bea50 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -8032,6 +8032,13 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) struct Scsi_Host *host = hba->host; struct device *dev = hba->dev;
+ /* + * dev_set_drvdata() must be called before any callbacks are registered + * that use dev_get_drvdata() (frequency scaling, clock scaling, hwmon, + * sysfs). + */ + dev_set_drvdata(dev, hba); + if (!mmio_base) { dev_err(hba->dev, "Invalid memory reference for mmio_base is NULL\n");
From: Arnd Bergmann arnd@arndb.de
stable inclusion from linux-4.19.226 commit c976850fa06cca6675f24fdd5b44cb13ea9d7189
--------------------------------
[ Upstream commit 134c37fa250a87a7e77c80a7c59ae16c462e46e0 ]
The last driver referencing the slave_id on Marvell PXA and MMP platforms was the SPI driver, but this stopped doing so a long time ago, so the TODO from the earlier patch can no be removed.
Fixes: b729bf34535e ("spi/pxa2xx: Don't use slave_id of dma_slave_config") Fixes: 13b3006b8ebd ("dma: mmp_pdma: add filter function") Signed-off-by: Arnd Bergmann arnd@arndb.de Acked-by: Mark Brown broonie@kernel.org Link: https://lore.kernel.org/r/20211122222203.4103644-7-arnd@kernel.org Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- drivers/dma/mmp_pdma.c | 6 ------ drivers/dma/pxa_dma.c | 7 ------- 2 files changed, 13 deletions(-)
diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c index eb3a1f42ab06..e8b2d3e31de8 100644 --- a/drivers/dma/mmp_pdma.c +++ b/drivers/dma/mmp_pdma.c @@ -722,12 +722,6 @@ static int mmp_pdma_config(struct dma_chan *dchan,
chan->dir = cfg->direction; chan->dev_addr = addr; - /* FIXME: drivers should be ported over to use the filter - * function. Once that's done, the following two lines can - * be removed. - */ - if (cfg->slave_id) - chan->drcmr = cfg->slave_id;
return 0; } diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c index b31c28b67ad3..c54986902b9d 100644 --- a/drivers/dma/pxa_dma.c +++ b/drivers/dma/pxa_dma.c @@ -960,13 +960,6 @@ static void pxad_get_config(struct pxad_chan *chan, *dcmd |= PXA_DCMD_BURST16; else if (maxburst == 32) *dcmd |= PXA_DCMD_BURST32; - - /* FIXME: drivers should be ported over to use the filter - * function. Once that's done, the following two lines can - * be removed. - */ - if (chan->cfg.slave_id) - chan->drcmr = chan->cfg.slave_id; }
static struct dma_async_tx_descriptor *
From: Antoine Tenart atenart@kernel.org
stable inclusion from linux-4.19.226 commit 35cad2003b6447932cfe91f795090586306738e8
--------------------------------
[ Upstream commit d7dac083414eb5bb99a6d2ed53dc2c1b405224e5 ]
When updating Rx and Tx queue kobjects, the queue count should always be updated to match the queue kobjects count. This was not done in the net device unregistration path, fix it. Tracking all queue count updates will allow in a following up patch to detect illegal updates.
Signed-off-by: Antoine Tenart atenart@kernel.org Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- net/core/net-sysfs.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index fe0d255d66c8..e5dc04cb5599 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -1616,6 +1616,9 @@ static void remove_queue_kobjects(struct net_device *dev)
net_rx_queue_update_kobjects(dev, real_rx, 0); netdev_queue_update_kobjects(dev, real_tx, 0); + + dev->real_num_rx_queues = 0; + dev->real_num_tx_queues = 0; #ifdef CONFIG_SYSFS kset_unregister(dev->queues_kset); #endif
From: Suresh Kumar surkumar@redhat.com
stable inclusion from linux-4.19.226 commit 4cca06db20796f60ad83943b80664ef0d652dcac
--------------------------------
[ Upstream commit fee32de284ac277ba434a2d59f8ce46528ff3946 ]
Currently "bond_should_notify_peers: slave ..." messages are printed whenever "bond_should_notify_peers" function is called.
+++ Dec 12 12:33:26 node1 kernel: bond0: bond_should_notify_peers: slave enp0s25 Dec 12 12:33:26 node1 kernel: bond0: bond_should_notify_peers: slave enp0s25 Dec 12 12:33:26 node1 kernel: bond0: bond_should_notify_peers: slave enp0s25 Dec 12 12:33:26 node1 kernel: bond0: (slave enp0s25): Received LACPDU on port 1 Dec 12 12:33:26 node1 kernel: bond0: (slave enp0s25): Rx Machine: Port=1, Last State=6, Curr State=6 Dec 12 12:33:26 node1 kernel: bond0: (slave enp0s25): partner sync=1 Dec 12 12:33:26 node1 kernel: bond0: bond_should_notify_peers: slave enp0s25 Dec 12 12:33:26 node1 kernel: bond0: bond_should_notify_peers: slave enp0s25 Dec 12 12:33:26 node1 kernel: bond0: bond_should_notify_peers: slave enp0s25 ... Dec 12 12:33:30 node1 kernel: bond0: bond_should_notify_peers: slave enp0s25 Dec 12 12:33:30 node1 kernel: bond0: bond_should_notify_peers: slave enp0s25 Dec 12 12:33:30 node1 kernel: bond0: (slave enp4s3): Received LACPDU on port 2 Dec 12 12:33:30 node1 kernel: bond0: (slave enp4s3): Rx Machine: Port=2, Last State=6, Curr State=6 Dec 12 12:33:30 node1 kernel: bond0: (slave enp4s3): partner sync=1 Dec 12 12:33:30 node1 kernel: bond0: bond_should_notify_peers: slave enp0s25 Dec 12 12:33:30 node1 kernel: bond0: bond_should_notify_peers: slave enp0s25 Dec 12 12:33:30 node1 kernel: bond0: bond_should_notify_peers: slave enp0s25 +++
This is confusing and can also clutter up debug logs. Print logs only when the peer notification happens.
Signed-off-by: Suresh Kumar suresh2514@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- drivers/net/bonding/bond_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index c952ab169e4e..f4d40e983e99 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -782,9 +782,6 @@ static bool bond_should_notify_peers(struct bonding *bond) slave = rcu_dereference(bond->curr_active_slave); rcu_read_unlock();
- netdev_dbg(bond->dev, "bond_should_notify_peers: slave %s\n", - slave ? slave->dev->name : "NULL"); - if (!slave || !bond->send_peer_notif || bond->send_peer_notif % max(1, bond->params.peer_notif_delay) != 0 || @@ -792,6 +789,9 @@ static bool bond_should_notify_peers(struct bonding *bond) test_bit(__LINK_STATE_LINKWATCH_PENDING, &slave->dev->state)) return false;
+ netdev_dbg(bond->dev, "bond_should_notify_peers: slave %s\n", + slave ? slave->dev->name : "NULL"); + return true; }
From: Paolo Abeni pabeni@redhat.com
stable inclusion from linux-4.19.226 commit f6d5eb174ee9b9ca4911b98f243f149fbfd19a43
--------------------------------
[ Upstream commit 2cbad989033bff0256675c38f96f5faab852af4b ]
The WARN_ONCE() in bpf_warn_invalid_xdp_action() can be triggered by any bugged program, and even attaching a correct program to a NIC not supporting the given action.
The resulting splat, beyond polluting the logs, fouls automated tools: e.g. a syzkaller reproducers using an XDP program returning an unsupported action will never pass validation.
Replace the WARN_ONCE with a less intrusive pr_warn_once().
Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Toke Høiland-Jørgensen toke@redhat.com Link: https://lore.kernel.org/bpf/016ceec56e4817ebb2a9e35ce794d5c917df572c.1638189... Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- net/core/filter.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/core/filter.c b/net/core/filter.c index 5f24a6b82802..0730395918e0 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -5528,9 +5528,9 @@ void bpf_warn_invalid_xdp_action(u32 act) { const u32 act_max = XDP_REDIRECT;
- WARN_ONCE(1, "%s XDP return value %u, expect packet loss!\n", - act > act_max ? "Illegal" : "Driver unsupported", - act); + pr_warn_once("%s XDP return value %u, expect packet loss!\n", + act > act_max ? "Illegal" : "Driver unsupported", + act); } EXPORT_SYMBOL_GPL(bpf_warn_invalid_xdp_action);
From: Kyeong Yoo kyeong.yoo@alliedtelesis.co.nz
stable inclusion from linux-4.19.226 commit c0b59abaf8effbac022f6d8b526c4b0b620920b3
--------------------------------
[ Upstream commit aa39cc675799bc92da153af9a13d6f969c348e82 ]
GC task can deadlock in read_cache_page() because it may attempt to release a page that is actually allocated by another task in jffs2_write_begin(). The reason is that in jffs2_write_begin() there is a small window a cache page is allocated for use but not set Uptodate yet.
This ends up with a deadlock between two tasks: 1) A task (e.g. file copy) - jffs2_write_begin() locks a cache page - jffs2_write_end() tries to lock "alloc_sem" from jffs2_reserve_space() <-- STUCK 2) GC task (jffs2_gcd_mtd3) - jffs2_garbage_collect_pass() locks "alloc_sem" - try to lock the same cache page in read_cache_page() <-- STUCK
So to avoid this deadlock, hold "alloc_sem" in jffs2_write_begin() while reading data in a cache page.
Signed-off-by: Kyeong Yoo kyeong.yoo@alliedtelesis.co.nz Signed-off-by: Richard Weinberger richard@nod.at Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- fs/jffs2/file.c | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-)
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c index 7d8654a1472e..3047872fdac9 100644 --- a/fs/jffs2/file.c +++ b/fs/jffs2/file.c @@ -135,20 +135,15 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, struct page *pg; struct inode *inode = mapping->host; struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); + struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); pgoff_t index = pos >> PAGE_SHIFT; uint32_t pageofs = index << PAGE_SHIFT; int ret = 0;
- pg = grab_cache_page_write_begin(mapping, index, flags); - if (!pg) - return -ENOMEM; - *pagep = pg; - jffs2_dbg(1, "%s()\n", __func__);
if (pageofs > inode->i_size) { /* Make new hole frag from old EOF to new page */ - struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); struct jffs2_raw_inode ri; struct jffs2_full_dnode *fn; uint32_t alloc_len; @@ -159,7 +154,7 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len, ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); if (ret) - goto out_page; + goto out_err;
mutex_lock(&f->sem); memset(&ri, 0, sizeof(ri)); @@ -189,7 +184,7 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, ret = PTR_ERR(fn); jffs2_complete_reservation(c); mutex_unlock(&f->sem); - goto out_page; + goto out_err; } ret = jffs2_add_full_dnode_to_inode(c, f, fn); if (f->metadata) { @@ -204,13 +199,26 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, jffs2_free_full_dnode(fn); jffs2_complete_reservation(c); mutex_unlock(&f->sem); - goto out_page; + goto out_err; } jffs2_complete_reservation(c); inode->i_size = pageofs; mutex_unlock(&f->sem); }
+ /* + * While getting a page and reading data in, lock c->alloc_sem until + * the page is Uptodate. Otherwise GC task may attempt to read the same + * page in read_cache_page(), which causes a deadlock. + */ + mutex_lock(&c->alloc_sem); + pg = grab_cache_page_write_begin(mapping, index, flags); + if (!pg) { + ret = -ENOMEM; + goto release_sem; + } + *pagep = pg; + /* * Read in the page if it wasn't already present. Cannot optimize away * the whole page write case until jffs2_write_end can handle the @@ -220,15 +228,17 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, mutex_lock(&f->sem); ret = jffs2_do_readpage_nolock(inode, pg); mutex_unlock(&f->sem); - if (ret) - goto out_page; + if (ret) { + unlock_page(pg); + put_page(pg); + goto release_sem; + } } jffs2_dbg(1, "end write_begin(). pg->flags %lx\n", pg->flags); - return ret;
-out_page: - unlock_page(pg); - put_page(pg); +release_sem: + mutex_unlock(&c->alloc_sem); +out_err: return ret; }
From: "Rafael J. Wysocki" rafael.j.wysocki@intel.com
stable inclusion from linux-4.19.226 commit e198165efa9032550f05441c78adee56e16850b4
--------------------------------
[ Upstream commit 1cdfe9e346b4c5509ffe19ccde880fd259d9f7a3 ]
ACPICA commit c11af67d8f7e3d381068ce7771322f2b5324d687
If original_count is 0 in acpi_ut_update_ref_count (), acpi_ut_delete_internal_obj () is invoked for the target object, which is incorrect, because that object has been deleted once already and the memory allocated to store it may have been reclaimed and allocated for a different purpose by the host OS. Moreover, a confusing debug message following the "Reference Count is already zero, cannot decrement" warning is printed in that case.
To fix this issue, make acpi_ut_update_ref_count () return after finding that original_count is 0 and printing the above warning.
Link: https://github.com/acpica/acpica/commit/c11af67d Link: https://github.com/acpica/acpica/pull/652 Reported-by: Mark Asselstine mark.asselstine@windriver.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Bob Moore robert.moore@intel.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- drivers/acpi/acpica/utdelete.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c index 8cc4392c61f3..42e489cfa4d5 100644 --- a/drivers/acpi/acpica/utdelete.c +++ b/drivers/acpi/acpica/utdelete.c @@ -410,6 +410,7 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action) ACPI_WARNING((AE_INFO, "Obj %p, Reference Count is already zero, cannot decrement\n", object)); + return; }
ACPI_DEBUG_PRINT_RAW((ACPI_DB_ALLOCATIONS,
From: "Rafael J. Wysocki" rafael.j.wysocki@intel.com
stable inclusion from linux-4.19.226 commit addda1b65b5dfbbdff0f1e100aed0a72b8af5bb8
--------------------------------
[ Upstream commit 24ea5f90ec9548044a6209685c5010edd66ffe8f ]
ACPICA commit d984f12041392fa4156b52e2f7e5c5e7bc38ad9e
If Operand[0] is a reference of the ACPI_REFCLASS_REFOF class, acpi_ex_opcode_1A_0T_1R () calls acpi_ns_get_attached_object () to obtain return_desc which may require additional resolution with the help of acpi_ex_read_data_from_field (). If the latter fails, the reference counter of the original return_desc is decremented which is incorrect, because acpi_ns_get_attached_object () does not increment the reference counter of the object returned by it.
This issue may lead to premature deletion of the attached object while it is still attached and a use-after-free and crash in the host OS. For example, this may happen when on evaluation of ref_of() a local region field where there is no registered handler for the given Operation Region.
Fix it by making acpi_ex_opcode_1A_0T_1R () return Status right away after a acpi_ex_read_data_from_field () failure.
Link: https://github.com/acpica/acpica/commit/d984f120 Link: https://github.com/acpica/acpica/pull/685 Reported-by: Lenny Szubowicz lszubowi@redhat.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Bob Moore robert.moore@intel.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- drivers/acpi/acpica/exoparg1.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c index ba9fbae0cf91..319f4bc6a839 100644 --- a/drivers/acpi/acpica/exoparg1.c +++ b/drivers/acpi/acpica/exoparg1.c @@ -1007,7 +1007,8 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) (walk_state, return_desc, &temp_desc); if (ACPI_FAILURE(status)) { - goto cleanup; + return_ACPI_STATUS + (status); }
return_desc = temp_desc;
From: Joe Thornber ejt@redhat.com
stable inclusion from linux-4.19.226 commit 716e490c87e4421d5908f7818fc6b61536a17744
--------------------------------
[ Upstream commit 85bca3c05b6cca31625437eedf2060e846c4bbad ]
Corrupt metadata could trigger an out of bounds write.
Signed-off-by: Joe Thornber ejt@redhat.com Signed-off-by: Mike Snitzer snitzer@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- drivers/md/persistent-data/dm-btree.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/md/persistent-data/dm-btree.c b/drivers/md/persistent-data/dm-btree.c index 8aae0624a297..6383afb88f31 100644 --- a/drivers/md/persistent-data/dm-btree.c +++ b/drivers/md/persistent-data/dm-btree.c @@ -83,14 +83,16 @@ void inc_children(struct dm_transaction_manager *tm, struct btree_node *n, }
static int insert_at(size_t value_size, struct btree_node *node, unsigned index, - uint64_t key, void *value) - __dm_written_to_disk(value) + uint64_t key, void *value) + __dm_written_to_disk(value) { uint32_t nr_entries = le32_to_cpu(node->header.nr_entries); + uint32_t max_entries = le32_to_cpu(node->header.max_entries); __le64 key_le = cpu_to_le64(key);
if (index > nr_entries || - index >= le32_to_cpu(node->header.max_entries)) { + index >= max_entries || + nr_entries >= max_entries) { DMERR("too many entries in btree node for insert"); __dm_unbless_for_disk(value); return -ENOMEM;
From: Joe Thornber ejt@redhat.com
stable inclusion from linux-4.19.226 commit 7d585b602a5c054e810b8f47183069872ac2fdf6
--------------------------------
[ Upstream commit cba23ac158db7f3cd48a923d6861bee2eb7a2978 ]
Corrupted metadata could warrant returning error from sm_ll_lookup_bitmap().
Signed-off-by: Joe Thornber ejt@redhat.com Signed-off-by: Mike Snitzer snitzer@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- drivers/md/persistent-data/dm-space-map-common.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/md/persistent-data/dm-space-map-common.c b/drivers/md/persistent-data/dm-space-map-common.c index a284762e548e..5115a2719603 100644 --- a/drivers/md/persistent-data/dm-space-map-common.c +++ b/drivers/md/persistent-data/dm-space-map-common.c @@ -279,6 +279,11 @@ int sm_ll_lookup_bitmap(struct ll_disk *ll, dm_block_t b, uint32_t *result) struct disk_index_entry ie_disk; struct dm_block *blk;
+ if (b >= ll->nr_blocks) { + DMERR_LIMIT("metadata block out of bounds"); + return -EINVAL; + } + b = do_div(index, ll->entries_per_block); r = ll->load_ie(ll, index, &ie_disk); if (r < 0)
From: Christoph Hellwig hch@lst.de
stable inclusion from linux-4.19.226 commit b24ef0a4974a95c9ee1aade3f39b90fc30ac552d
--------------------------------
[ Upstream commit d94d94969a4ba07a43d62429c60372320519c391 ]
The allocated buffers are used as a command payload, for which the block layer and/or DMA API do the proper bounce buffering if needed.
Link: https://lore.kernel.org/r/20211222090842.920724-1-hch@lst.de Reported-by: Baoquan He bhe@redhat.com Reviewed-by: Baoquan He bhe@redhat.com Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- drivers/scsi/sr.c | 2 +- drivers/scsi/sr_vendor.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index be2daf5536ff..180087d1c6cd 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -885,7 +885,7 @@ static void get_capabilities(struct scsi_cd *cd)
/* allocate transfer buffer */ - buffer = kmalloc(512, GFP_KERNEL | GFP_DMA); + buffer = kmalloc(512, GFP_KERNEL); if (!buffer) { sr_printk(KERN_ERR, cd, "out of memory.\n"); return; diff --git a/drivers/scsi/sr_vendor.c b/drivers/scsi/sr_vendor.c index e3b0ce25162b..2887be4316be 100644 --- a/drivers/scsi/sr_vendor.c +++ b/drivers/scsi/sr_vendor.c @@ -119,7 +119,7 @@ int sr_set_blocklength(Scsi_CD *cd, int blocklength) density = (blocklength > 2048) ? 0x81 : 0x83; #endif
- buffer = kmalloc(512, GFP_KERNEL | GFP_DMA); + buffer = kmalloc(512, GFP_KERNEL); if (!buffer) return -ENOMEM;
@@ -167,7 +167,7 @@ int sr_cd_check(struct cdrom_device_info *cdi) if (cd->cdi.mask & CDC_MULTI_SESSION) return 0;
- buffer = kmalloc(512, GFP_KERNEL | GFP_DMA); + buffer = kmalloc(512, GFP_KERNEL); if (!buffer) return -ENOMEM;
From: Lukas Wunner lukas@wunner.de
stable inclusion from linux-4.19.226 commit 510aa43c9928ca38f1210b6c255373727d7ea312
--------------------------------
commit d3b3404df318504ec084213ab1065b73f49b0f1d upstream.
Commit a6845e1e1b78 ("serial: core: Consider rs485 settings to drive RTS") sought to deassert RTS when opening an rs485-enabled uart port. That way, the transceiver does not occupy the bus until it transmits data.
Unfortunately, the commit mixed up the logic and *asserted* RTS instead of *deasserting* it:
The commit amended uart_port_dtr_rts(), which raises DTR and RTS when opening an rs232 port. "Raising" actually means lowering the signal that's coming out of the uart, because an rs232 transceiver not only changes a signal's voltage level, it also *inverts* the signal. See the simplified schematic in the MAX232 datasheet for an example: https://www.ti.com/lit/ds/symlink/max232.pdf
So, to raise RTS on an rs232 port, TIOCM_RTS is *set* in port->mctrl and that results in the signal being driven low.
In contrast to rs232, the signal level for rs485 Transmit Enable is the identity, not the inversion: If the transceiver expects a "high" RTS signal for Transmit Enable, the signal coming out of the uart must also be high, so TIOCM_RTS must be *cleared* in port->mctrl.
The commit did the exact opposite, but it's easy to see why given the confusing semantics of rs232 and rs485. Fix it.
Fixes: a6845e1e1b78 ("serial: core: Consider rs485 settings to drive RTS") Cc: stable@vger.kernel.org # v4.14+ Cc: Rafael Gago Castano rgc@hms.se Cc: Jan Kiszka jan.kiszka@siemens.com Cc: Su Bao Cheng baocheng.su@siemens.com Signed-off-by: Lukas Wunner lukas@wunner.de Link: https://lore.kernel.org/r/9395767847833f2f3193c49cde38501eeb3b5669.163982105... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- drivers/tty/serial/serial_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 4e60045487a8..8d8d63c3ca7d 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -159,7 +159,7 @@ static void uart_port_dtr_rts(struct uart_port *uport, int raise) int RTS_after_send = !!(uport->rs485.flags & SER_RS485_RTS_AFTER_SEND);
if (raise) { - if (rs485_on && !RTS_after_send) { + if (rs485_on && RTS_after_send) { uart_set_mctrl(uport, TIOCM_DTR); uart_clear_mctrl(uport, TIOCM_RTS); } else { @@ -168,7 +168,7 @@ static void uart_port_dtr_rts(struct uart_port *uport, int raise) } else { unsigned int clear = TIOCM_DTR;
- clear |= (!rs485_on || !RTS_after_send) ? TIOCM_RTS : 0; + clear |= (!rs485_on || RTS_after_send) ? TIOCM_RTS : 0; uart_clear_mctrl(uport, clear); } }
From: Andrey Ryabinin arbn@yandex-team.com
stable inclusion from linux-4.19.226 commit 952514c8565cf72a966993b473fae1708c3684f3
--------------------------------
commit 9731698ecb9c851f353ce2496292ff9fcea39dff upstream.
cpuacct.stat in no-root cgroups shows user time without guest time included int it. This doesn't match with user time shown in root cpuacct.stat and /proc/<pid>/stat. This also affects cgroup2's cpu.stat in the same way.
Make account_guest_time() to add user time to cgroup's cpustat to fix this.
Fixes: ef12fefabf94 ("cpuacct: add per-cgroup utime/stime statistics") Signed-off-by: Andrey Ryabinin arbn@yandex-team.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Daniel Jordan daniel.m.jordan@oracle.com Acked-by: Tejun Heo tj@kernel.org Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20211115164607.23784-1-arbn@yandex-team.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- kernel/sched/cputime.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c index 8dd27c1fbb29..0df2448eb5d1 100644 --- a/kernel/sched/cputime.c +++ b/kernel/sched/cputime.c @@ -152,10 +152,10 @@ void account_guest_time(struct task_struct *p, u64 cputime)
/* Add guest time to cpustat. */ if (task_nice(p) > 0) { - cpustat[CPUTIME_NICE] += cputime; + task_group_account_field(p, CPUTIME_NICE, cputime); cpustat[CPUTIME_GUEST_NICE] += cputime; } else { - cpustat[CPUTIME_USER] += cputime; + task_group_account_field(p, CPUTIME_USER, cputime); cpustat[CPUTIME_GUEST] += cputime; } }
From: Jan Kara jack@suse.cz
stable inclusion from linux-4.19.226 commit ef41f72716c469a670b9d556b65e5ed83a3a5fd7
--------------------------------
commit 4013d47a5307fdb5c13370b5392498b00fedd274 upstream.
When we succeed in enabling some quota type but fail to enable another one with quota feature, we correctly disable all enabled quota types. However we forget to reset i_data_sem lockdep class. When the inode gets freed and reused, it will inherit this lockdep class (i_data_sem is initialized only when a slab is created) and thus eventually lockdep barfs about possible deadlocks.
Reported-and-tested-by: syzbot+3b6f9218b1301ddda3e2@syzkaller.appspotmail.com Signed-off-by: Jan Kara jack@suse.cz Cc: stable@kernel.org Link: https://lore.kernel.org/r/20211007155336.12493-3-jack@suse.cz Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- fs/ext4/super.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 8f9d60ec607e..3100f4aa2d59 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -6166,8 +6166,19 @@ static int ext4_enable_quotas(struct super_block *sb) "Failed to enable quota tracking " "(type=%d, err=%d). Please run " "e2fsck to fix.", type, err); - for (type--; type >= 0; type--) + for (type--; type >= 0; type--) { + struct inode *inode; + + inode = sb_dqopt(sb)->files[type]; + if (inode) + inode = igrab(inode); dquot_quota_off(sb, type); + if (inode) { + lockdep_set_quota_inode(inode, + I_DATA_SEM_NORMAL); + iput(inode); + } + }
return err; }
From: Jan Kara jack@suse.cz
stable inclusion from linux-4.19.226 commit 841bba6544e10cab41535b76bbdd37555a6ab9df
--------------------------------
commit 15fc69bbbbbc8c72e5f6cc4e1be0f51283c5448e upstream.
When we hit an error when enabling quotas and setting inode flags, we do not properly shutdown quota subsystem despite returning error from Q_QUOTAON quotactl. This can lead to some odd situations like kernel using quota file while it is still writeable for userspace. Make sure we properly cleanup the quota subsystem in case of error.
Signed-off-by: Jan Kara jack@suse.cz Cc: stable@kernel.org Link: https://lore.kernel.org/r/20211007155336.12493-2-jack@suse.cz Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- fs/ext4/super.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 3100f4aa2d59..f961f7d94a70 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -6080,10 +6080,7 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id,
lockdep_set_quota_inode(path->dentry->d_inode, I_DATA_SEM_QUOTA); err = dquot_quota_on(sb, type, format_id, path); - if (err) { - lockdep_set_quota_inode(path->dentry->d_inode, - I_DATA_SEM_NORMAL); - } else { + if (!err) { struct inode *inode = d_inode(path->dentry); handle_t *handle;
@@ -6103,7 +6100,12 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id, ext4_journal_stop(handle); unlock_inode: inode_unlock(inode); + if (err) + dquot_quota_off(sb, type); } + if (err) + lockdep_set_quota_inode(path->dentry->d_inode, + I_DATA_SEM_NORMAL); return err; }
From: Luís Henriques lhenriques@suse.de
stable inclusion from linux-4.19.226 commit 9103cafdc4531285b6ededd0a3437effd71ff255
--------------------------------
commit e81c9302a6c3c008f5c30beb73b38adb0170ff2d upstream.
When migrating to extents, the temporary inode will have it's own checksum seed. This means that, when swapping the inodes data, the inode checksums will be incorrect.
This can be fixed by recalculating the extents checksums again. Or simply by copying the seed into the temporary inode.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=213357 Reported-by: Jeroen van Wolffelaar jeroen@wolffelaar.nl Signed-off-by: Luís Henriques lhenriques@suse.de Link: https://lore.kernel.org/r/20211214175058.19511-1-lhenriques@suse.de Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- fs/ext4/migrate.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c index 7eb036cd1d93..0b3194b59d12 100644 --- a/fs/ext4/migrate.c +++ b/fs/ext4/migrate.c @@ -457,6 +457,17 @@ int ext4_ext_migrate(struct inode *inode) ext4_journal_stop(handle); goto out_unlock; } + /* + * Use the correct seed for checksum (i.e. the seed from 'inode'). This + * is so that the metadata blocks will have the correct checksum after + * the migration. + * + * Note however that, if a crash occurs during the migration process, + * the recovery process is broken because the tmp_inode checksums will + * be wrong and the orphans cleanup will fail. + */ + ei = EXT4_I(inode); + EXT4_I(tmp_inode)->i_csum_seed = ei->i_csum_seed; i_size_write(tmp_inode, i_size_read(inode)); /* * Set the i_nlink to zero so it will be deleted later @@ -500,7 +511,6 @@ int ext4_ext_migrate(struct inode *inode) goto out_tmp_inode; }
- ei = EXT4_I(inode); i_data = ei->i_data; memset(&lb, 0, sizeof(lb));
From: Theodore Ts'o tytso@mit.edu
stable inclusion from linux-4.19.226 commit 33446496d21753b5ceb55be4d6e593b487a61239
--------------------------------
commit 6eeaf88fd586f05aaf1d48cb3a139d2a5c6eb055 upstream.
We probably want to remove the indirect block to extents migration feature after a deprecation window, but until then, let's fix a potential data loss problem caused by the fact that we put the tmp_inode on the orphan list. In the unlikely case where we crash and do a journal recovery, the data blocks belonging to the inode being migrated are also represented in the tmp_inode on the orphan list --- and so its data blocks will get marked unallocated, and available for reuse.
Instead, stop putting the tmp_inode on the oprhan list. So in the case where we crash while migrating the inode, we'll leak an inode, which is not a disaster. It will be easily fixed the next time we run fsck, and it's better than potentially having blocks getting claimed by two different files, and losing data as a result.
Signed-off-by: Theodore Ts'o tytso@mit.edu Reviewed-by: Lukas Czerner lczerner@redhat.com Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- fs/ext4/migrate.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-)
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c index 0b3194b59d12..75a769634b2b 100644 --- a/fs/ext4/migrate.c +++ b/fs/ext4/migrate.c @@ -435,12 +435,12 @@ int ext4_ext_migrate(struct inode *inode) percpu_down_write(&sbi->s_writepages_rwsem);
/* - * Worst case we can touch the allocation bitmaps, a bgd - * block, and a block to link in the orphan list. We do need - * need to worry about credits for modifying the quota inode. + * Worst case we can touch the allocation bitmaps and a block + * group descriptor block. We do need need to worry about + * credits for modifying the quota inode. */ handle = ext4_journal_start(inode, EXT4_HT_MIGRATE, - 4 + EXT4_MAXQUOTAS_TRANS_BLOCKS(inode->i_sb)); + 3 + EXT4_MAXQUOTAS_TRANS_BLOCKS(inode->i_sb));
if (IS_ERR(handle)) { retval = PTR_ERR(handle); @@ -461,10 +461,6 @@ int ext4_ext_migrate(struct inode *inode) * Use the correct seed for checksum (i.e. the seed from 'inode'). This * is so that the metadata blocks will have the correct checksum after * the migration. - * - * Note however that, if a crash occurs during the migration process, - * the recovery process is broken because the tmp_inode checksums will - * be wrong and the orphans cleanup will fail. */ ei = EXT4_I(inode); EXT4_I(tmp_inode)->i_csum_seed = ei->i_csum_seed; @@ -476,7 +472,6 @@ int ext4_ext_migrate(struct inode *inode) clear_nlink(tmp_inode);
ext4_ext_tree_init(handle, tmp_inode); - ext4_orphan_add(handle, tmp_inode); ext4_journal_stop(handle);
/* @@ -501,12 +496,6 @@ int ext4_ext_migrate(struct inode *inode)
handle = ext4_journal_start(inode, EXT4_HT_MIGRATE, 1); if (IS_ERR(handle)) { - /* - * It is impossible to update on-disk structures without - * a handle, so just rollback in-core changes and live other - * work to orphan_list_cleanup() - */ - ext4_orphan_del(NULL, tmp_inode); retval = PTR_ERR(handle); goto out_tmp_inode; }
From: Marek Vasut marex@denx.de
stable inclusion from linux-4.19.226 commit e670c4b7c1ca134463211b27af69695a3adcb846
--------------------------------
commit 29009604ad4e3ef784fd9b9fef6f23610ddf633d upstream.
The include/linux/crypto.h struct crypto_alg field cra_driver_name description states "Unique name of the transformation provider. " ... " this contains the name of the chip or provider and the name of the transformation algorithm."
In case of the stm32-crc driver, field cra_driver_name is identical for all registered transformation providers and set to the name of the driver itself, which is incorrect. This patch fixes it by assigning a unique cra_driver_name to each registered transformation provider.
The kernel crash is triggered when the driver calls crypto_register_shashes() which calls crypto_register_shash(), which calls crypto_register_alg(), which calls __crypto_register_alg(), which returns -EEXIST, which is propagated back through this call chain. Upon -EEXIST from crypto_register_shash(), the crypto_register_shashes() starts unregistering the providers back, and calls crypto_unregister_shash(), which calls crypto_unregister_alg(), and this is where the BUG() triggers due to incorrect cra_refcnt.
Fixes: b51dbe90912a ("crypto: stm32 - Support for STM32 CRC32 crypto module") Signed-off-by: Marek Vasut marex@denx.de Cc: stable@vger.kernel.org # 4.12+ Cc: Alexandre Torgue alexandre.torgue@foss.st.com Cc: Fabien Dessenne fabien.dessenne@st.com Cc: Herbert Xu herbert@gondor.apana.org.au Cc: Lionel Debieve lionel.debieve@st.com Cc: Nicolas Toromanoff nicolas.toromanoff@st.com Cc: linux-arm-kernel@lists.infradead.org Cc: linux-stm32@st-md-mailman.stormreply.com To: linux-crypto@vger.kernel.org Acked-by: Nicolas Toromanoff nicolas.toromanoff@foss.st.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- drivers/crypto/stm32/stm32_crc32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/crypto/stm32/stm32_crc32.c b/drivers/crypto/stm32/stm32_crc32.c index 29d2095d9dfd..48c4a71d1cb3 100644 --- a/drivers/crypto/stm32/stm32_crc32.c +++ b/drivers/crypto/stm32/stm32_crc32.c @@ -217,7 +217,7 @@ static struct shash_alg algs[] = { .digestsize = CHKSUM_DIGEST_SIZE, .base = { .cra_name = "crc32", - .cra_driver_name = DRIVER_NAME, + .cra_driver_name = "stm32-crc32-crc32", .cra_priority = 200, .cra_flags = CRYPTO_ALG_OPTIONAL_KEY, .cra_blocksize = CHKSUM_BLOCK_SIZE, @@ -239,7 +239,7 @@ static struct shash_alg algs[] = { .digestsize = CHKSUM_DIGEST_SIZE, .base = { .cra_name = "crc32c", - .cra_driver_name = DRIVER_NAME, + .cra_driver_name = "stm32-crc32-crc32c", .cra_priority = 200, .cra_flags = CRYPTO_ALG_OPTIONAL_KEY, .cra_blocksize = CHKSUM_BLOCK_SIZE,
From: Eric Dumazet edumazet@google.com
stable inclusion from linux-4.19.226 commit cf3c4b5912cb208194507a21f6209e8ae4e6c260
--------------------------------
commit 9d6d7f1cb67cdee15f1a0e85aacfb924e0e02435 upstream.
wait_for_unix_gc() reads unix_tot_inflight & gc_in_progress without synchronization.
Adds READ_ONCE()/WRITE_ONCE() and their associated comments to better document the intent.
BUG: KCSAN: data-race in unix_inflight / wait_for_unix_gc
write to 0xffffffff86e2b7c0 of 4 bytes by task 9380 on cpu 0: unix_inflight+0x1e8/0x260 net/unix/scm.c:63 unix_attach_fds+0x10c/0x1e0 net/unix/scm.c:121 unix_scm_to_skb net/unix/af_unix.c:1674 [inline] unix_dgram_sendmsg+0x679/0x16b0 net/unix/af_unix.c:1817 unix_seqpacket_sendmsg+0xcc/0x110 net/unix/af_unix.c:2258 sock_sendmsg_nosec net/socket.c:704 [inline] sock_sendmsg net/socket.c:724 [inline] ____sys_sendmsg+0x39a/0x510 net/socket.c:2409 ___sys_sendmsg net/socket.c:2463 [inline] __sys_sendmmsg+0x267/0x4c0 net/socket.c:2549 __do_sys_sendmmsg net/socket.c:2578 [inline] __se_sys_sendmmsg net/socket.c:2575 [inline] __x64_sys_sendmmsg+0x53/0x60 net/socket.c:2575 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x44/0xd0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x44/0xae
read to 0xffffffff86e2b7c0 of 4 bytes by task 9375 on cpu 1: wait_for_unix_gc+0x24/0x160 net/unix/garbage.c:196 unix_dgram_sendmsg+0x8e/0x16b0 net/unix/af_unix.c:1772 unix_seqpacket_sendmsg+0xcc/0x110 net/unix/af_unix.c:2258 sock_sendmsg_nosec net/socket.c:704 [inline] sock_sendmsg net/socket.c:724 [inline] ____sys_sendmsg+0x39a/0x510 net/socket.c:2409 ___sys_sendmsg net/socket.c:2463 [inline] __sys_sendmmsg+0x267/0x4c0 net/socket.c:2549 __do_sys_sendmmsg net/socket.c:2578 [inline] __se_sys_sendmmsg net/socket.c:2575 [inline] __x64_sys_sendmmsg+0x53/0x60 net/socket.c:2575 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x44/0xd0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x44/0xae
value changed: 0x00000002 -> 0x00000004
Reported by Kernel Concurrency Sanitizer on: CPU: 1 PID: 9375 Comm: syz-executor.1 Not tainted 5.16.0-rc7-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Fixes: 9915672d4127 ("af_unix: limit unix_tot_inflight") Signed-off-by: Eric Dumazet edumazet@google.com Reported-by: syzbot syzkaller@googlegroups.com Link: https://lore.kernel.org/r/20220114164328.2038499-1-eric.dumazet@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- net/unix/garbage.c | 14 +++++++++++--- net/unix/scm.c | 6 ++++-- 2 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 8bbe1b8e4ff7..4d283e26d816 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -197,8 +197,11 @@ void wait_for_unix_gc(void) { /* If number of inflight sockets is insane, * force a garbage collect right now. + * Paired with the WRITE_ONCE() in unix_inflight(), + * unix_notinflight() and gc_in_progress(). */ - if (unix_tot_inflight > UNIX_INFLIGHT_TRIGGER_GC && !gc_in_progress) + if (READ_ONCE(unix_tot_inflight) > UNIX_INFLIGHT_TRIGGER_GC && + !READ_ONCE(gc_in_progress)) unix_gc(); wait_event(unix_gc_wait, gc_in_progress == false); } @@ -218,7 +221,9 @@ void unix_gc(void) if (gc_in_progress) goto out;
- gc_in_progress = true; + /* Paired with READ_ONCE() in wait_for_unix_gc(). */ + WRITE_ONCE(gc_in_progress, true); + /* First, select candidates for garbage collection. Only * in-flight sockets are considered, and from those only ones * which don't have any external reference. @@ -304,7 +309,10 @@ void unix_gc(void)
/* All candidates should have been detached by now. */ BUG_ON(!list_empty(&gc_candidates)); - gc_in_progress = false; + + /* Paired with READ_ONCE() in wait_for_unix_gc(). */ + WRITE_ONCE(gc_in_progress, false); + wake_up(&unix_gc_wait);
out: diff --git a/net/unix/scm.c b/net/unix/scm.c index 8c40f2b32392..ce700b22ecce 100644 --- a/net/unix/scm.c +++ b/net/unix/scm.c @@ -59,7 +59,8 @@ void unix_inflight(struct user_struct *user, struct file *fp) } else { BUG_ON(list_empty(&u->link)); } - unix_tot_inflight++; + /* Paired with READ_ONCE() in wait_for_unix_gc() */ + WRITE_ONCE(unix_tot_inflight, unix_tot_inflight + 1); } user->unix_inflight++; spin_unlock(&unix_gc_lock); @@ -79,7 +80,8 @@ void unix_notinflight(struct user_struct *user, struct file *fp)
if (atomic_long_dec_and_test(&u->inflight)) list_del_init(&u->link); - unix_tot_inflight--; + /* Paired with READ_ONCE() in wait_for_unix_gc() */ + WRITE_ONCE(unix_tot_inflight, unix_tot_inflight - 1); } user->unix_inflight--; spin_unlock(&unix_gc_lock);
From: Eric Dumazet edumazet@google.com
stable inclusion from linux-4.19.226 commit 4048cedfd16a995b2ef4294b9539da17e2fea750
--------------------------------
commit 2836615aa22de55b8fca5e32fe1b27a67cda625e upstream.
When under stress, cleanup_net() can have to dismantle netns in big numbers. ops_exit_list() currently calls many helpers [1] that have no schedule point, and we can end up with soft lockups, particularly on hosts with many cpus.
Even for moderate amount of netns processed by cleanup_net() this patch avoids latency spikes.
[1] Some of these helpers like fib_sync_up() and fib_sync_down_dev() are very slow because net/ipv4/fib_semantics.c uses host-wide hash tables, and ifindex is used as the only input of two hash functions. ifindexes tend to be the same for all netns (lo.ifindex==1 per instance) This will be fixed in a separate patch.
Fixes: 72ad937abd0a ("net: Add support for batching network namespace cleanups") Signed-off-by: Eric Dumazet edumazet@google.com Cc: Eric W. Biederman ebiederm@xmission.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- net/core/net_namespace.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index c60123dff803..f4aacbb76fa5 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -149,8 +149,10 @@ static void ops_exit_list(const struct pernet_operations *ops, { struct net *net; if (ops->exit) { - list_for_each_entry(net, net_exit_list, exit_list) + list_for_each_entry(net, net_exit_list, exit_list) { ops->exit(net); + cond_resched(); + } } if (ops->exit_batch) ops->exit_batch(net_exit_list);
From: "Doyle, Patrick" pdoyle@irobot.com
stable inclusion from linux-4.19.226 commit 1550a97e4a5d8bf29071bd6c17355ca173e90f73
--------------------------------
commit fd0d8d85f7230052e638a56d1bfea170c488e6bc upstream.
In the unlikely event that both blocks 10 and 11 are marked as bad (on a 32 bit machine), then the process of marking block 10 as bad stomps on cached entry for block 11. There are (of course) other examples.
Signed-off-by: Patrick Doyle pdoyle@irobot.com Reviewed-by: Richard Weinberger richard@nod.at Signed-off-by: Yoshio Furuyama ytc-mb-yfuruyama7@kioxia.com [miquel.raynal@bootlin.com: Fixed the title] Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Cc: Frieder Schrempf frieder.schrempf@kontron.de Link: https://lore.kernel.org/linux-mtd/774a92693f311e7de01e5935e720a179fb1b2468.1... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- drivers/mtd/nand/bbt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mtd/nand/bbt.c b/drivers/mtd/nand/bbt.c index 044adf913854..64af6898131d 100644 --- a/drivers/mtd/nand/bbt.c +++ b/drivers/mtd/nand/bbt.c @@ -123,7 +123,7 @@ int nanddev_bbt_set_block_status(struct nand_device *nand, unsigned int entry, unsigned int rbits = bits_per_block + offs - BITS_PER_LONG;
pos[1] &= ~GENMASK(rbits - 1, 0); - pos[1] |= val >> rbits; + pos[1] |= val >> (bits_per_block - rbits); }
return 0;
From: Jan Kara jack@suse.cz
stable inclusion from linux-4.19.227 commit 6717900f775a6129a7b4d03ba4922218d8bf1caa
--------------------------------
commit 68514dacf2715d11b91ca50d88de047c086fea9c upstream.
A task can end up indefinitely sleeping in do_select() -> poll_schedule_timeout() when the following race happens:
TASK1 (thread1) TASK2 TASK1 (thread2) do_select() setup poll_wqueues table with 'fd' write data to 'fd' pollwake() table->triggered = 1 closes 'fd' thread1 is waiting for poll_schedule_timeout() - sees table->triggered table->triggered = 0 return -EINTR loop back in do_select()
But at this point when TASK1 loops back, the fdget() in the setup of poll_wqueues fails. So now so we never find 'fd' is ready for reading and sleep in poll_schedule_timeout() indefinitely.
Treat an fd that got closed as a fd on which some event happened. This makes sure cannot block indefinitely in do_select().
Another option would be to return -EBADF in this case but that has a potential of subtly breaking applications that excercise this behavior and it happens to work for them. So returning fd as active seems like a safer choice.
Suggested-by: Linus Torvalds torvalds@linux-foundation.org CC: stable@vger.kernel.org Signed-off-by: Jan Kara jack@suse.cz Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- fs/select.c | 63 ++++++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 30 deletions(-)
diff --git a/fs/select.c b/fs/select.c index b684f0dd6db8..67e4be14c00c 100644 --- a/fs/select.c +++ b/fs/select.c @@ -458,9 +458,11 @@ static int max_select_fd(unsigned long n, fd_set_bits *fds) return max; }
-#define POLLIN_SET (EPOLLRDNORM | EPOLLRDBAND | EPOLLIN | EPOLLHUP | EPOLLERR) -#define POLLOUT_SET (EPOLLWRBAND | EPOLLWRNORM | EPOLLOUT | EPOLLERR) -#define POLLEX_SET (EPOLLPRI) +#define POLLIN_SET (EPOLLRDNORM | EPOLLRDBAND | EPOLLIN | EPOLLHUP | EPOLLERR |\ + EPOLLNVAL) +#define POLLOUT_SET (EPOLLWRBAND | EPOLLWRNORM | EPOLLOUT | EPOLLERR |\ + EPOLLNVAL) +#define POLLEX_SET (EPOLLPRI | EPOLLNVAL)
static inline void wait_key_set(poll_table *wait, unsigned long in, unsigned long out, unsigned long bit, @@ -527,6 +529,7 @@ static int do_select(int n, fd_set_bits *fds, struct timespec64 *end_time) break; if (!(bit & all_bits)) continue; + mask = EPOLLNVAL; f = fdget(i); if (f.file) { wait_key_set(wait, in, out, bit, @@ -534,34 +537,34 @@ static int do_select(int n, fd_set_bits *fds, struct timespec64 *end_time) mask = vfs_poll(f.file, wait);
fdput(f); - if ((mask & POLLIN_SET) && (in & bit)) { - res_in |= bit; - retval++; - wait->_qproc = NULL; - } - if ((mask & POLLOUT_SET) && (out & bit)) { - res_out |= bit; - retval++; - wait->_qproc = NULL; - } - if ((mask & POLLEX_SET) && (ex & bit)) { - res_ex |= bit; - retval++; - wait->_qproc = NULL; - } - /* got something, stop busy polling */ - if (retval) { - can_busy_loop = false; - busy_flag = 0; - - /* - * only remember a returned - * POLL_BUSY_LOOP if we asked for it - */ - } else if (busy_flag & mask) - can_busy_loop = true; - } + if ((mask & POLLIN_SET) && (in & bit)) { + res_in |= bit; + retval++; + wait->_qproc = NULL; + } + if ((mask & POLLOUT_SET) && (out & bit)) { + res_out |= bit; + retval++; + wait->_qproc = NULL; + } + if ((mask & POLLEX_SET) && (ex & bit)) { + res_ex |= bit; + retval++; + wait->_qproc = NULL; + } + /* got something, stop busy polling */ + if (retval) { + can_busy_loop = false; + busy_flag = 0; + + /* + * only remember a returned + * POLL_BUSY_LOOP if we asked for it + */ + } else if (busy_flag & mask) + can_busy_loop = true; + } if (res_in) *rinp = res_in;