From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id E658E1382C5 for ; Sat, 13 Feb 2021 15:28:39 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 125F8E0896; Sat, 13 Feb 2021 15:28:39 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id D7F1AE0896 for ; Sat, 13 Feb 2021 15:28:38 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id C6962340CF4 for ; Sat, 13 Feb 2021 15:28:37 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 6279B46B for ; Sat, 13 Feb 2021 15:28:36 +0000 (UTC) From: "Alice Ferrazzi" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Alice Ferrazzi" Message-ID: <1613230099.0ddbad73d58cb0b9a876cbd0b17c9ba4303ac1a5.alicef@gentoo> Subject: [gentoo-commits] proj/linux-patches:4.19 commit in: / X-VCS-Repository: proj/linux-patches X-VCS-Files: 0000_README 1175_linux-4.19.176.patch X-VCS-Directories: / X-VCS-Committer: alicef X-VCS-Committer-Name: Alice Ferrazzi X-VCS-Revision: 0ddbad73d58cb0b9a876cbd0b17c9ba4303ac1a5 X-VCS-Branch: 4.19 Date: Sat, 13 Feb 2021 15:28:36 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply X-Archives-Salt: 9ce4a554-c871-44a2-b25f-3610f51d9ca9 X-Archives-Hash: 9beb1d8edcc08f5772b4245117121931 commit: 0ddbad73d58cb0b9a876cbd0b17c9ba4303ac1a5 Author: Alice Ferrazzi gentoo org> AuthorDate: Sat Feb 13 15:28:11 2021 +0000 Commit: Alice Ferrazzi gentoo org> CommitDate: Sat Feb 13 15:28:19 2021 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=0ddbad73 Linux patch 4.19.176 Signed-off-by: Alice Ferrazzi gentoo.org> 0000_README | 4 + 1175_linux-4.19.176.patch | 1359 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1363 insertions(+) diff --git a/0000_README b/0000_README index d2238ab..4101b37 100644 --- a/0000_README +++ b/0000_README @@ -739,6 +739,10 @@ Patch: 1174_linux-4.19.175.patch From: https://www.kernel.org Desc: Linux 4.19.175 +Patch: 1175_linux-4.19.176.patch +From: https://www.kernel.org +Desc: Linux 4.19.176 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1175_linux-4.19.176.patch b/1175_linux-4.19.176.patch new file mode 100644 index 0000000..b06ab46 --- /dev/null +++ b/1175_linux-4.19.176.patch @@ -0,0 +1,1359 @@ +diff --git a/Makefile b/Makefile +index db37b39fae693..6bebe3b22b452 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 4 + PATCHLEVEL = 19 +-SUBLEVEL = 175 ++SUBLEVEL = 176 + EXTRAVERSION = + NAME = "People's Front" + +diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c +index f1e86051aa5f3..b34d11f22213f 100644 +--- a/arch/x86/kvm/svm.c ++++ b/arch/x86/kvm/svm.c +@@ -1832,6 +1832,8 @@ static struct page **sev_pin_memory(struct kvm *kvm, unsigned long uaddr, + struct page **pages; + unsigned long first, last; + ++ lockdep_assert_held(&kvm->lock); ++ + if (ulen == 0 || uaddr + ulen < uaddr) + return NULL; + +@@ -7084,12 +7086,21 @@ static int svm_register_enc_region(struct kvm *kvm, + if (!region) + return -ENOMEM; + ++ mutex_lock(&kvm->lock); + region->pages = sev_pin_memory(kvm, range->addr, range->size, ®ion->npages, 1); + if (!region->pages) { + ret = -ENOMEM; ++ mutex_unlock(&kvm->lock); + goto e_free; + } + ++ region->uaddr = range->addr; ++ region->size = range->size; ++ ++ mutex_lock(&kvm->lock); ++ list_add_tail(®ion->list, &sev->regions_list); ++ mutex_unlock(&kvm->lock); ++ + /* + * The guest may change the memory encryption attribute from C=0 -> C=1 + * or vice versa for this memory range. Lets make sure caches are +@@ -7098,13 +7109,6 @@ static int svm_register_enc_region(struct kvm *kvm, + */ + sev_clflush_pages(region->pages, region->npages); + +- region->uaddr = range->addr; +- region->size = range->size; +- +- mutex_lock(&kvm->lock); +- list_add_tail(®ion->list, &sev->regions_list); +- mutex_unlock(&kvm->lock); +- + return ret; + + e_free: +diff --git a/block/blk-mq.c b/block/blk-mq.c +index 0df43515ff949..195526b93895e 100644 +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -2324,11 +2324,6 @@ static void blk_mq_map_swqueue(struct request_queue *q) + struct blk_mq_ctx *ctx; + struct blk_mq_tag_set *set = q->tag_set; + +- /* +- * Avoid others reading imcomplete hctx->cpumask through sysfs +- */ +- mutex_lock(&q->sysfs_lock); +- + queue_for_each_hw_ctx(q, hctx, i) { + cpumask_clear(hctx->cpumask); + hctx->nr_ctx = 0; +@@ -2362,8 +2357,6 @@ static void blk_mq_map_swqueue(struct request_queue *q) + hctx->ctxs[hctx->nr_ctx++] = ctx; + } + +- mutex_unlock(&q->sysfs_lock); +- + queue_for_each_hw_ctx(q, hctx, i) { + /* + * If no software queues are mapped to this hardware queue, +diff --git a/block/elevator.c b/block/elevator.c +index fae58b2f906fc..ddbcd36616a8d 100644 +--- a/block/elevator.c ++++ b/block/elevator.c +@@ -980,23 +980,19 @@ int elevator_init_mq(struct request_queue *q) + if (q->nr_hw_queues != 1) + return 0; + +- /* +- * q->sysfs_lock must be held to provide mutual exclusion between +- * elevator_switch() and here. +- */ +- mutex_lock(&q->sysfs_lock); ++ WARN_ON_ONCE(test_bit(QUEUE_FLAG_REGISTERED, &q->queue_flags)); ++ + if (unlikely(q->elevator)) +- goto out_unlock; ++ goto out; + + e = elevator_get(q, "mq-deadline", false); + if (!e) +- goto out_unlock; ++ goto out; + + err = blk_mq_init_sched(q, e); + if (err) + elevator_put(e); +-out_unlock: +- mutex_unlock(&q->sysfs_lock); ++out: + return err; + } + +diff --git a/block/genhd.c b/block/genhd.c +index 2b536ab570ac1..6965dde963736 100644 +--- a/block/genhd.c ++++ b/block/genhd.c +@@ -652,10 +652,12 @@ exit: + kobject_uevent(&part_to_dev(part)->kobj, KOBJ_ADD); + disk_part_iter_exit(&piter); + +- err = sysfs_create_link(&ddev->kobj, +- &disk->queue->backing_dev_info->dev->kobj, +- "bdi"); +- WARN_ON(err); ++ if (disk->queue->backing_dev_info->dev) { ++ err = sysfs_create_link(&ddev->kobj, ++ &disk->queue->backing_dev_info->dev->kobj, ++ "bdi"); ++ WARN_ON(err); ++ } + } + + /** +diff --git a/drivers/crypto/chelsio/chtls/chtls_cm.c b/drivers/crypto/chelsio/chtls/chtls_cm.c +index fd3092a4378e4..08ed3ff8b255f 100644 +--- a/drivers/crypto/chelsio/chtls/chtls_cm.c ++++ b/drivers/crypto/chelsio/chtls/chtls_cm.c +@@ -1051,11 +1051,9 @@ static struct sock *chtls_recv_sock(struct sock *lsk, + tcph = (struct tcphdr *)(iph + 1); + n = dst_neigh_lookup(dst, &iph->saddr); + if (!n || !n->dev) +- goto free_sk; ++ goto free_dst; + + ndev = n->dev; +- if (!ndev) +- goto free_dst; + if (is_vlan_dev(ndev)) + ndev = vlan_dev_real_dev(ndev); + +@@ -1117,7 +1115,8 @@ static struct sock *chtls_recv_sock(struct sock *lsk, + free_csk: + chtls_sock_release(&csk->kref); + free_dst: +- neigh_release(n); ++ if (n) ++ neigh_release(n); + dst_release(dst); + free_sk: + inet_csk_prepare_forced_close(newsk); +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c +index 798605c4f1227..5287f21d7ba63 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c +@@ -520,7 +520,10 @@ static ssize_t iwl_dbgfs_os_device_timediff_read(struct file *file, + const size_t bufsz = sizeof(buf); + int pos = 0; + ++ mutex_lock(&mvm->mutex); + iwl_mvm_get_sync_time(mvm, &curr_gp2, &curr_os); ++ mutex_unlock(&mvm->mutex); ++ + do_div(curr_os, NSEC_PER_USEC); + diff = curr_os - curr_gp2; + pos += scnprintf(buf + pos, bufsz - pos, "diff=%lld\n", diff); +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +index 0e26619fb330b..d932171617e6a 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +@@ -1192,6 +1192,7 @@ static void iwl_mvm_reprobe_wk(struct work_struct *wk) + reprobe = container_of(wk, struct iwl_mvm_reprobe, work); + if (device_reprobe(reprobe->dev)) + dev_err(reprobe->dev, "reprobe failed!\n"); ++ put_device(reprobe->dev); + kfree(reprobe); + module_put(THIS_MODULE); + } +@@ -1242,7 +1243,7 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error) + module_put(THIS_MODULE); + return; + } +- reprobe->dev = mvm->trans->dev; ++ reprobe->dev = get_device(mvm->trans->dev); + INIT_WORK(&reprobe->work, iwl_mvm_reprobe_wk); + schedule_work(&reprobe->work); + } else if (mvm->fwrt.cur_fw_img == IWL_UCODE_REGULAR && +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c +index 6783b20d9681b..a1cecf4a0e820 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c +@@ -159,8 +159,10 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, + /* Allocate IML */ + iml_img = dma_alloc_coherent(trans->dev, trans->iml_len, + &trans_pcie->iml_dma_addr, GFP_KERNEL); +- if (!iml_img) +- return -ENOMEM; ++ if (!iml_img) { ++ ret = -ENOMEM; ++ goto err_free_ctxt_info; ++ } + + memcpy(iml_img, trans->iml, trans->iml_len); + +@@ -177,6 +179,11 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, + + return 0; + ++err_free_ctxt_info: ++ dma_free_coherent(trans->dev, sizeof(*trans_pcie->ctxt_info_gen3), ++ trans_pcie->ctxt_info_gen3, ++ trans_pcie->ctxt_info_dma_addr); ++ trans_pcie->ctxt_info_gen3 = NULL; + err_free_prph_info: + dma_free_coherent(trans->dev, + sizeof(*prph_info), +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +index b73582ec03a08..b1a71539ca3e5 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +@@ -631,6 +631,11 @@ static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id) + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_txq *txq = trans_pcie->txq[txq_id]; + ++ if (!txq) { ++ IWL_ERR(trans, "Trying to free a queue that wasn't allocated?\n"); ++ return; ++ } ++ + spin_lock_bh(&txq->lock); + while (txq->write_ptr != txq->read_ptr) { + IWL_DEBUG_TX_REPLY(trans, "Q %d Free %d\n", +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index 8a6ca06d9c160..65e1cde13d59e 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -1142,17 +1142,6 @@ static int set_machine_constraints(struct regulator_dev *rdev) + } + } + +- /* If the constraints say the regulator should be on at this point +- * and we have control then make sure it is enabled. +- */ +- if (rdev->constraints->always_on || rdev->constraints->boot_on) { +- ret = _regulator_do_enable(rdev); +- if (ret < 0 && ret != -EINVAL) { +- rdev_err(rdev, "failed to enable\n"); +- return ret; +- } +- } +- + if ((rdev->constraints->ramp_delay || rdev->constraints->ramp_disable) + && ops->set_ramp_delay) { + ret = ops->set_ramp_delay(rdev, rdev->constraints->ramp_delay); +@@ -1198,6 +1187,27 @@ static int set_machine_constraints(struct regulator_dev *rdev) + } + } + ++ /* If the constraints say the regulator should be on at this point ++ * and we have control then make sure it is enabled. ++ */ ++ if (rdev->constraints->always_on || rdev->constraints->boot_on) { ++ if (rdev->supply) { ++ ret = regulator_enable(rdev->supply); ++ if (ret < 0) { ++ _regulator_put(rdev->supply); ++ rdev->supply = NULL; ++ return ret; ++ } ++ } ++ ++ ret = _regulator_do_enable(rdev); ++ if (ret < 0 && ret != -EINVAL) { ++ rdev_err(rdev, "failed to enable\n"); ++ return ret; ++ } ++ rdev->use_count++; ++ } ++ + print_constraints(rdev); + return 0; + } +@@ -1567,13 +1577,13 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) + { + struct regulator_dev *r; + struct device *dev = rdev->dev.parent; +- int ret; ++ int ret = 0; + + /* No supply to resovle? */ + if (!rdev->supply_name) + return 0; + +- /* Supply already resolved? */ ++ /* Supply already resolved? (fast-path without locking contention) */ + if (rdev->supply) + return 0; + +@@ -1583,7 +1593,7 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) + + /* Did the lookup explicitly defer for us? */ + if (ret == -EPROBE_DEFER) +- return ret; ++ goto out; + + if (have_full_constraints()) { + r = dummy_regulator_rdev; +@@ -1591,15 +1601,18 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) + } else { + dev_err(dev, "Failed to resolve %s-supply for %s\n", + rdev->supply_name, rdev->desc->name); +- return -EPROBE_DEFER; ++ ret = -EPROBE_DEFER; ++ goto out; + } + } + + if (r == rdev) { + dev_err(dev, "Supply for %s (%s) resolved to itself\n", + rdev->desc->name, rdev->supply_name); +- if (!have_full_constraints()) +- return -EINVAL; ++ if (!have_full_constraints()) { ++ ret = -EINVAL; ++ goto out; ++ } + r = dummy_regulator_rdev; + get_device(&r->dev); + } +@@ -1613,7 +1626,8 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) + if (r->dev.parent && r->dev.parent != rdev->dev.parent) { + if (!device_is_bound(r->dev.parent)) { + put_device(&r->dev); +- return -EPROBE_DEFER; ++ ret = -EPROBE_DEFER; ++ goto out; + } + } + +@@ -1621,26 +1635,48 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) + ret = regulator_resolve_supply(r); + if (ret < 0) { + put_device(&r->dev); +- return ret; ++ goto out; ++ } ++ ++ /* ++ * Recheck rdev->supply with rdev->mutex lock held to avoid a race ++ * between rdev->supply null check and setting rdev->supply in ++ * set_supply() from concurrent tasks. ++ */ ++ regulator_lock(rdev); ++ ++ /* Supply just resolved by a concurrent task? */ ++ if (rdev->supply) { ++ regulator_unlock(rdev); ++ put_device(&r->dev); ++ goto out; + } + + ret = set_supply(rdev, r); + if (ret < 0) { ++ regulator_unlock(rdev); + put_device(&r->dev); +- return ret; ++ goto out; + } + +- /* Cascade always-on state to supply */ +- if (_regulator_is_enabled(rdev)) { ++ regulator_unlock(rdev); ++ ++ /* ++ * In set_machine_constraints() we may have turned this regulator on ++ * but we couldn't propagate to the supply if it hadn't been resolved ++ * yet. Do it now. ++ */ ++ if (rdev->use_count) { + ret = regulator_enable(rdev->supply); + if (ret < 0) { + _regulator_put(rdev->supply); + rdev->supply = NULL; +- return ret; ++ goto out; + } + } + +- return 0; ++out: ++ return ret; + } + + /* Internal regulator request function */ +diff --git a/drivers/remoteproc/qcom_q6v5_pil.c b/drivers/remoteproc/qcom_q6v5_pil.c +index cc475dcbf27f3..604828c04ddfb 100644 +--- a/drivers/remoteproc/qcom_q6v5_pil.c ++++ b/drivers/remoteproc/qcom_q6v5_pil.c +@@ -340,6 +340,12 @@ static int q6v5_load(struct rproc *rproc, const struct firmware *fw) + { + struct q6v5 *qproc = rproc->priv; + ++ /* MBA is restricted to a maximum size of 1M */ ++ if (fw->size > qproc->mba_size || fw->size > SZ_1M) { ++ dev_err(qproc->dev, "MBA firmware load failed\n"); ++ return -EINVAL; ++ } ++ + memcpy(qproc->mba_region, fw->data, fw->size); + + return 0; +@@ -739,14 +745,13 @@ static int q6v5_mpss_load(struct q6v5 *qproc) + + if (phdr->p_filesz) { + snprintf(seg_name, sizeof(seg_name), "modem.b%02d", i); +- ret = request_firmware(&seg_fw, seg_name, qproc->dev); ++ ret = request_firmware_into_buf(&seg_fw, seg_name, qproc->dev, ++ ptr, phdr->p_filesz); + if (ret) { + dev_err(qproc->dev, "failed to load %s\n", seg_name); + goto release_firmware; + } + +- memcpy(ptr, seg_fw->data, seg_fw->size); +- + release_firmware(seg_fw); + } + +diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c +index f2d0c4acb3cbb..a247cb4b00e2d 100644 +--- a/fs/fs-writeback.c ++++ b/fs/fs-writeback.c +@@ -1986,7 +1986,7 @@ void wb_workfn(struct work_struct *work) + struct bdi_writeback, dwork); + long pages_written; + +- set_worker_desc("flush-%s", dev_name(wb->bdi->dev)); ++ set_worker_desc("flush-%s", bdi_dev_name(wb->bdi)); + current->flags |= PF_SWAPWRITE; + + if (likely(!current_is_workqueue_rescuer() || +diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c +index 4b165aa5a2561..55965e8e9a2ed 100644 +--- a/fs/nfs/pnfs.c ++++ b/fs/nfs/pnfs.c +@@ -2301,7 +2301,13 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) + * We got an entirely new state ID. Mark all segments for the + * inode invalid, and retry the layoutget + */ +- pnfs_mark_layout_stateid_invalid(lo, &free_me); ++ struct pnfs_layout_range range = { ++ .iomode = IOMODE_ANY, ++ .length = NFS4_MAX_UINT64, ++ }; ++ pnfs_set_plh_return_info(lo, IOMODE_ANY, 0); ++ pnfs_mark_matching_lsegs_return(lo, &lo->plh_return_segs, ++ &range, 0); + goto out_forget; + } + +diff --git a/fs/squashfs/export.c b/fs/squashfs/export.c +index 8073b6532cf04..d2a806416c3ab 100644 +--- a/fs/squashfs/export.c ++++ b/fs/squashfs/export.c +@@ -54,12 +54,17 @@ static long long squashfs_inode_lookup(struct super_block *sb, int ino_num) + struct squashfs_sb_info *msblk = sb->s_fs_info; + int blk = SQUASHFS_LOOKUP_BLOCK(ino_num - 1); + int offset = SQUASHFS_LOOKUP_BLOCK_OFFSET(ino_num - 1); +- u64 start = le64_to_cpu(msblk->inode_lookup_table[blk]); ++ u64 start; + __le64 ino; + int err; + + TRACE("Entered squashfs_inode_lookup, inode_number = %d\n", ino_num); + ++ if (ino_num == 0 || (ino_num - 1) >= msblk->inodes) ++ return -EINVAL; ++ ++ start = le64_to_cpu(msblk->inode_lookup_table[blk]); ++ + err = squashfs_read_metadata(sb, &ino, &start, &offset, sizeof(ino)); + if (err < 0) + return err; +@@ -124,7 +129,10 @@ __le64 *squashfs_read_inode_lookup_table(struct super_block *sb, + u64 lookup_table_start, u64 next_table, unsigned int inodes) + { + unsigned int length = SQUASHFS_LOOKUP_BLOCK_BYTES(inodes); ++ unsigned int indexes = SQUASHFS_LOOKUP_BLOCKS(inodes); ++ int n; + __le64 *table; ++ u64 start, end; + + TRACE("In read_inode_lookup_table, length %d\n", length); + +@@ -134,20 +142,37 @@ __le64 *squashfs_read_inode_lookup_table(struct super_block *sb, + if (inodes == 0) + return ERR_PTR(-EINVAL); + +- /* length bytes should not extend into the next table - this check +- * also traps instances where lookup_table_start is incorrectly larger +- * than the next table start ++ /* ++ * The computed size of the lookup table (length bytes) should exactly ++ * match the table start and end points + */ +- if (lookup_table_start + length > next_table) ++ if (length != (next_table - lookup_table_start)) + return ERR_PTR(-EINVAL); + + table = squashfs_read_table(sb, lookup_table_start, length); ++ if (IS_ERR(table)) ++ return table; + + /* +- * table[0] points to the first inode lookup table metadata block, +- * this should be less than lookup_table_start ++ * table0], table[1], ... table[indexes - 1] store the locations ++ * of the compressed inode lookup blocks. Each entry should be ++ * less than the next (i.e. table[0] < table[1]), and the difference ++ * between them should be SQUASHFS_METADATA_SIZE or less. ++ * table[indexes - 1] should be less than lookup_table_start, and ++ * again the difference should be SQUASHFS_METADATA_SIZE or less + */ +- if (!IS_ERR(table) && le64_to_cpu(table[0]) >= lookup_table_start) { ++ for (n = 0; n < (indexes - 1); n++) { ++ start = le64_to_cpu(table[n]); ++ end = le64_to_cpu(table[n + 1]); ++ ++ if (start >= end || (end - start) > SQUASHFS_METADATA_SIZE) { ++ kfree(table); ++ return ERR_PTR(-EINVAL); ++ } ++ } ++ ++ start = le64_to_cpu(table[indexes - 1]); ++ if (start >= lookup_table_start || (lookup_table_start - start) > SQUASHFS_METADATA_SIZE) { + kfree(table); + return ERR_PTR(-EINVAL); + } +diff --git a/fs/squashfs/id.c b/fs/squashfs/id.c +index d38ea3dab9515..8ccc0e3f6ea5a 100644 +--- a/fs/squashfs/id.c ++++ b/fs/squashfs/id.c +@@ -48,10 +48,15 @@ int squashfs_get_id(struct super_block *sb, unsigned int index, + struct squashfs_sb_info *msblk = sb->s_fs_info; + int block = SQUASHFS_ID_BLOCK(index); + int offset = SQUASHFS_ID_BLOCK_OFFSET(index); +- u64 start_block = le64_to_cpu(msblk->id_table[block]); ++ u64 start_block; + __le32 disk_id; + int err; + ++ if (index >= msblk->ids) ++ return -EINVAL; ++ ++ start_block = le64_to_cpu(msblk->id_table[block]); ++ + err = squashfs_read_metadata(sb, &disk_id, &start_block, &offset, + sizeof(disk_id)); + if (err < 0) +@@ -69,7 +74,10 @@ __le64 *squashfs_read_id_index_table(struct super_block *sb, + u64 id_table_start, u64 next_table, unsigned short no_ids) + { + unsigned int length = SQUASHFS_ID_BLOCK_BYTES(no_ids); ++ unsigned int indexes = SQUASHFS_ID_BLOCKS(no_ids); ++ int n; + __le64 *table; ++ u64 start, end; + + TRACE("In read_id_index_table, length %d\n", length); + +@@ -80,20 +88,36 @@ __le64 *squashfs_read_id_index_table(struct super_block *sb, + return ERR_PTR(-EINVAL); + + /* +- * length bytes should not extend into the next table - this check +- * also traps instances where id_table_start is incorrectly larger +- * than the next table start ++ * The computed size of the index table (length bytes) should exactly ++ * match the table start and end points + */ +- if (id_table_start + length > next_table) ++ if (length != (next_table - id_table_start)) + return ERR_PTR(-EINVAL); + + table = squashfs_read_table(sb, id_table_start, length); ++ if (IS_ERR(table)) ++ return table; + + /* +- * table[0] points to the first id lookup table metadata block, this +- * should be less than id_table_start ++ * table[0], table[1], ... table[indexes - 1] store the locations ++ * of the compressed id blocks. Each entry should be less than ++ * the next (i.e. table[0] < table[1]), and the difference between them ++ * should be SQUASHFS_METADATA_SIZE or less. table[indexes - 1] ++ * should be less than id_table_start, and again the difference ++ * should be SQUASHFS_METADATA_SIZE or less + */ +- if (!IS_ERR(table) && le64_to_cpu(table[0]) >= id_table_start) { ++ for (n = 0; n < (indexes - 1); n++) { ++ start = le64_to_cpu(table[n]); ++ end = le64_to_cpu(table[n + 1]); ++ ++ if (start >= end || (end - start) > SQUASHFS_METADATA_SIZE) { ++ kfree(table); ++ return ERR_PTR(-EINVAL); ++ } ++ } ++ ++ start = le64_to_cpu(table[indexes - 1]); ++ if (start >= id_table_start || (id_table_start - start) > SQUASHFS_METADATA_SIZE) { + kfree(table); + return ERR_PTR(-EINVAL); + } +diff --git a/fs/squashfs/squashfs_fs_sb.h b/fs/squashfs/squashfs_fs_sb.h +index ef69c31947bf8..5234c19a0eabc 100644 +--- a/fs/squashfs/squashfs_fs_sb.h ++++ b/fs/squashfs/squashfs_fs_sb.h +@@ -77,5 +77,6 @@ struct squashfs_sb_info { + unsigned int inodes; + unsigned int fragments; + int xattr_ids; ++ unsigned int ids; + }; + #endif +diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c +index 40e657386fa52..728b2d72f3f07 100644 +--- a/fs/squashfs/super.c ++++ b/fs/squashfs/super.c +@@ -176,6 +176,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent) + msblk->directory_table = le64_to_cpu(sblk->directory_table_start); + msblk->inodes = le32_to_cpu(sblk->inodes); + msblk->fragments = le32_to_cpu(sblk->fragments); ++ msblk->ids = le16_to_cpu(sblk->no_ids); + flags = le16_to_cpu(sblk->flags); + + TRACE("Found valid superblock on %pg\n", sb->s_bdev); +@@ -187,7 +188,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent) + TRACE("Block size %d\n", msblk->block_size); + TRACE("Number of inodes %d\n", msblk->inodes); + TRACE("Number of fragments %d\n", msblk->fragments); +- TRACE("Number of ids %d\n", le16_to_cpu(sblk->no_ids)); ++ TRACE("Number of ids %d\n", msblk->ids); + TRACE("sblk->inode_table_start %llx\n", msblk->inode_table); + TRACE("sblk->directory_table_start %llx\n", msblk->directory_table); + TRACE("sblk->fragment_table_start %llx\n", +@@ -244,8 +245,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent) + allocate_id_index_table: + /* Allocate and read id index table */ + msblk->id_table = squashfs_read_id_index_table(sb, +- le64_to_cpu(sblk->id_table_start), next_table, +- le16_to_cpu(sblk->no_ids)); ++ le64_to_cpu(sblk->id_table_start), next_table, msblk->ids); + if (IS_ERR(msblk->id_table)) { + ERROR("unable to read id index table\n"); + err = PTR_ERR(msblk->id_table); +diff --git a/fs/squashfs/xattr.h b/fs/squashfs/xattr.h +index afe70f815e3de..86b0a0073e51f 100644 +--- a/fs/squashfs/xattr.h ++++ b/fs/squashfs/xattr.h +@@ -30,8 +30,16 @@ extern int squashfs_xattr_lookup(struct super_block *, unsigned int, int *, + static inline __le64 *squashfs_read_xattr_id_table(struct super_block *sb, + u64 start, u64 *xattr_table_start, int *xattr_ids) + { ++ struct squashfs_xattr_id_table *id_table; ++ ++ id_table = squashfs_read_table(sb, start, sizeof(*id_table)); ++ if (IS_ERR(id_table)) ++ return (__le64 *) id_table; ++ ++ *xattr_table_start = le64_to_cpu(id_table->xattr_table_start); ++ kfree(id_table); ++ + ERROR("Xattrs in filesystem, these will be ignored\n"); +- *xattr_table_start = start; + return ERR_PTR(-ENOTSUPP); + } + +diff --git a/fs/squashfs/xattr_id.c b/fs/squashfs/xattr_id.c +index c89607d690c48..3a655d879600c 100644 +--- a/fs/squashfs/xattr_id.c ++++ b/fs/squashfs/xattr_id.c +@@ -44,10 +44,15 @@ int squashfs_xattr_lookup(struct super_block *sb, unsigned int index, + struct squashfs_sb_info *msblk = sb->s_fs_info; + int block = SQUASHFS_XATTR_BLOCK(index); + int offset = SQUASHFS_XATTR_BLOCK_OFFSET(index); +- u64 start_block = le64_to_cpu(msblk->xattr_id_table[block]); ++ u64 start_block; + struct squashfs_xattr_id id; + int err; + ++ if (index >= msblk->xattr_ids) ++ return -EINVAL; ++ ++ start_block = le64_to_cpu(msblk->xattr_id_table[block]); ++ + err = squashfs_read_metadata(sb, &id, &start_block, &offset, + sizeof(id)); + if (err < 0) +@@ -63,13 +68,17 @@ int squashfs_xattr_lookup(struct super_block *sb, unsigned int index, + /* + * Read uncompressed xattr id lookup table indexes from disk into memory + */ +-__le64 *squashfs_read_xattr_id_table(struct super_block *sb, u64 start, ++__le64 *squashfs_read_xattr_id_table(struct super_block *sb, u64 table_start, + u64 *xattr_table_start, int *xattr_ids) + { +- unsigned int len; ++ struct squashfs_sb_info *msblk = sb->s_fs_info; ++ unsigned int len, indexes; + struct squashfs_xattr_id_table *id_table; ++ __le64 *table; ++ u64 start, end; ++ int n; + +- id_table = squashfs_read_table(sb, start, sizeof(*id_table)); ++ id_table = squashfs_read_table(sb, table_start, sizeof(*id_table)); + if (IS_ERR(id_table)) + return (__le64 *) id_table; + +@@ -83,13 +92,52 @@ __le64 *squashfs_read_xattr_id_table(struct super_block *sb, u64 start, + if (*xattr_ids == 0) + return ERR_PTR(-EINVAL); + +- /* xattr_table should be less than start */ +- if (*xattr_table_start >= start) ++ len = SQUASHFS_XATTR_BLOCK_BYTES(*xattr_ids); ++ indexes = SQUASHFS_XATTR_BLOCKS(*xattr_ids); ++ ++ /* ++ * The computed size of the index table (len bytes) should exactly ++ * match the table start and end points ++ */ ++ start = table_start + sizeof(*id_table); ++ end = msblk->bytes_used; ++ ++ if (len != (end - start)) + return ERR_PTR(-EINVAL); + +- len = SQUASHFS_XATTR_BLOCK_BYTES(*xattr_ids); ++ table = squashfs_read_table(sb, start, len); ++ if (IS_ERR(table)) ++ return table; ++ ++ /* table[0], table[1], ... table[indexes - 1] store the locations ++ * of the compressed xattr id blocks. Each entry should be less than ++ * the next (i.e. table[0] < table[1]), and the difference between them ++ * should be SQUASHFS_METADATA_SIZE or less. table[indexes - 1] ++ * should be less than table_start, and again the difference ++ * shouls be SQUASHFS_METADATA_SIZE or less. ++ * ++ * Finally xattr_table_start should be less than table[0]. ++ */ ++ for (n = 0; n < (indexes - 1); n++) { ++ start = le64_to_cpu(table[n]); ++ end = le64_to_cpu(table[n + 1]); ++ ++ if (start >= end || (end - start) > SQUASHFS_METADATA_SIZE) { ++ kfree(table); ++ return ERR_PTR(-EINVAL); ++ } ++ } ++ ++ start = le64_to_cpu(table[indexes - 1]); ++ if (start >= table_start || (table_start - start) > SQUASHFS_METADATA_SIZE) { ++ kfree(table); ++ return ERR_PTR(-EINVAL); ++ } + +- TRACE("In read_xattr_index_table, length %d\n", len); ++ if (*xattr_table_start >= le64_to_cpu(table[0])) { ++ kfree(table); ++ return ERR_PTR(-EINVAL); ++ } + +- return squashfs_read_table(sb, start + sizeof(*id_table), len); ++ return table; + } +diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h +index c28a47cbe355e..1ef4aca7b953f 100644 +--- a/include/linux/backing-dev.h ++++ b/include/linux/backing-dev.h +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -498,4 +499,13 @@ static inline int bdi_rw_congested(struct backing_dev_info *bdi) + (1 << WB_async_congested)); + } + ++extern const char *bdi_unknown_name; ++ ++static inline const char *bdi_dev_name(struct backing_dev_info *bdi) ++{ ++ if (!bdi || !bdi->dev) ++ return bdi_unknown_name; ++ return dev_name(bdi->dev); ++} ++ + #endif /* _LINUX_BACKING_DEV_H */ +diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h +index 9f22652d69bb0..c28204e22b544 100644 +--- a/include/linux/kprobes.h ++++ b/include/linux/kprobes.h +@@ -245,7 +245,7 @@ extern void kprobes_inc_nmissed_count(struct kprobe *p); + extern bool arch_within_kprobe_blacklist(unsigned long addr); + extern int arch_populate_kprobe_blacklist(void); + extern bool arch_kprobe_on_func_entry(unsigned long offset); +-extern bool kprobe_on_func_entry(kprobe_opcode_t *addr, const char *sym, unsigned long offset); ++extern int kprobe_on_func_entry(kprobe_opcode_t *addr, const char *sym, unsigned long offset); + + extern bool within_kprobe_blacklist(unsigned long addr); + extern int kprobe_add_ksym_blacklist(unsigned long entry); +diff --git a/include/linux/string.h b/include/linux/string.h +index 4db285b83f44e..1e0c442b941e2 100644 +--- a/include/linux/string.h ++++ b/include/linux/string.h +@@ -31,6 +31,10 @@ size_t strlcpy(char *, const char *, size_t); + #ifndef __HAVE_ARCH_STRSCPY + ssize_t strscpy(char *, const char *, size_t); + #endif ++ ++/* Wraps calls to strscpy()/memset(), no arch specific code required */ ++ssize_t strscpy_pad(char *dest, const char *src, size_t count); ++ + #ifndef __HAVE_ARCH_STRCAT + extern char * strcat(char *, const char *); + #endif +diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h +index 2bd68177a442e..33580cc72a43d 100644 +--- a/include/linux/sunrpc/xdr.h ++++ b/include/linux/sunrpc/xdr.h +@@ -26,8 +26,7 @@ struct rpc_rqst; + #define XDR_QUADLEN(l) (((l) + 3) >> 2) + + /* +- * Generic opaque `network object.' At the kernel level, this type +- * is used only by lockd. ++ * Generic opaque `network object.' + */ + #define XDR_MAX_NETOBJ 1024 + struct xdr_netobj { +diff --git a/include/trace/events/writeback.h b/include/trace/events/writeback.h +index 146e7b3faa856..300afa559f467 100644 +--- a/include/trace/events/writeback.h ++++ b/include/trace/events/writeback.h +@@ -65,8 +65,9 @@ TRACE_EVENT(writeback_dirty_page, + ), + + TP_fast_assign( +- strncpy(__entry->name, +- mapping ? dev_name(inode_to_bdi(mapping->host)->dev) : "(unknown)", 32); ++ strscpy_pad(__entry->name, ++ bdi_dev_name(mapping ? inode_to_bdi(mapping->host) : ++ NULL), 32); + __entry->ino = mapping ? mapping->host->i_ino : 0; + __entry->index = page->index; + ), +@@ -95,8 +96,7 @@ DECLARE_EVENT_CLASS(writeback_dirty_inode_template, + struct backing_dev_info *bdi = inode_to_bdi(inode); + + /* may be called for files on pseudo FSes w/ unregistered bdi */ +- strncpy(__entry->name, +- bdi->dev ? dev_name(bdi->dev) : "(unknown)", 32); ++ strscpy_pad(__entry->name, bdi_dev_name(bdi), 32); + __entry->ino = inode->i_ino; + __entry->state = inode->i_state; + __entry->flags = flags; +@@ -175,8 +175,8 @@ DECLARE_EVENT_CLASS(writeback_write_inode_template, + ), + + TP_fast_assign( +- strncpy(__entry->name, +- dev_name(inode_to_bdi(inode)->dev), 32); ++ strscpy_pad(__entry->name, ++ bdi_dev_name(inode_to_bdi(inode)), 32); + __entry->ino = inode->i_ino; + __entry->sync_mode = wbc->sync_mode; + __entry->cgroup_ino = __trace_wbc_assign_cgroup(wbc); +@@ -219,8 +219,7 @@ DECLARE_EVENT_CLASS(writeback_work_class, + __field(unsigned int, cgroup_ino) + ), + TP_fast_assign( +- strncpy(__entry->name, +- wb->bdi->dev ? dev_name(wb->bdi->dev) : "(unknown)", 32); ++ strscpy_pad(__entry->name, bdi_dev_name(wb->bdi), 32); + __entry->nr_pages = work->nr_pages; + __entry->sb_dev = work->sb ? work->sb->s_dev : 0; + __entry->sync_mode = work->sync_mode; +@@ -273,7 +272,7 @@ DECLARE_EVENT_CLASS(writeback_class, + __field(unsigned int, cgroup_ino) + ), + TP_fast_assign( +- strncpy(__entry->name, dev_name(wb->bdi->dev), 32); ++ strscpy_pad(__entry->name, bdi_dev_name(wb->bdi), 32); + __entry->cgroup_ino = __trace_wb_assign_cgroup(wb); + ), + TP_printk("bdi %s: cgroup_ino=%u", +@@ -295,7 +294,7 @@ TRACE_EVENT(writeback_bdi_register, + __array(char, name, 32) + ), + TP_fast_assign( +- strncpy(__entry->name, dev_name(bdi->dev), 32); ++ strscpy_pad(__entry->name, bdi_dev_name(bdi), 32); + ), + TP_printk("bdi %s", + __entry->name +@@ -320,7 +319,7 @@ DECLARE_EVENT_CLASS(wbc_class, + ), + + TP_fast_assign( +- strncpy(__entry->name, dev_name(bdi->dev), 32); ++ strscpy_pad(__entry->name, bdi_dev_name(bdi), 32); + __entry->nr_to_write = wbc->nr_to_write; + __entry->pages_skipped = wbc->pages_skipped; + __entry->sync_mode = wbc->sync_mode; +@@ -371,7 +370,7 @@ TRACE_EVENT(writeback_queue_io, + __field(unsigned int, cgroup_ino) + ), + TP_fast_assign( +- strncpy(__entry->name, dev_name(wb->bdi->dev), 32); ++ strscpy_pad(__entry->name, bdi_dev_name(wb->bdi), 32); + __entry->older = dirtied_before; + __entry->age = (jiffies - dirtied_before) * 1000 / HZ; + __entry->moved = moved; +@@ -456,7 +455,7 @@ TRACE_EVENT(bdi_dirty_ratelimit, + ), + + TP_fast_assign( +- strlcpy(__entry->bdi, dev_name(wb->bdi->dev), 32); ++ strscpy_pad(__entry->bdi, bdi_dev_name(wb->bdi), 32); + __entry->write_bw = KBps(wb->write_bandwidth); + __entry->avg_write_bw = KBps(wb->avg_write_bandwidth); + __entry->dirty_rate = KBps(dirty_rate); +@@ -521,7 +520,7 @@ TRACE_EVENT(balance_dirty_pages, + + TP_fast_assign( + unsigned long freerun = (thresh + bg_thresh) / 2; +- strlcpy(__entry->bdi, dev_name(wb->bdi->dev), 32); ++ strscpy_pad(__entry->bdi, bdi_dev_name(wb->bdi), 32); + + __entry->limit = global_wb_domain.dirty_limit; + __entry->setpoint = (global_wb_domain.dirty_limit + +@@ -581,8 +580,8 @@ TRACE_EVENT(writeback_sb_inodes_requeue, + ), + + TP_fast_assign( +- strncpy(__entry->name, +- dev_name(inode_to_bdi(inode)->dev), 32); ++ strscpy_pad(__entry->name, ++ bdi_dev_name(inode_to_bdi(inode)), 32); + __entry->ino = inode->i_ino; + __entry->state = inode->i_state; + __entry->dirtied_when = inode->dirtied_when; +@@ -655,8 +654,8 @@ DECLARE_EVENT_CLASS(writeback_single_inode_template, + ), + + TP_fast_assign( +- strncpy(__entry->name, +- dev_name(inode_to_bdi(inode)->dev), 32); ++ strscpy_pad(__entry->name, ++ bdi_dev_name(inode_to_bdi(inode)), 32); + __entry->ino = inode->i_ino; + __entry->state = inode->i_state; + __entry->dirtied_when = inode->dirtied_when; +diff --git a/init/init_task.c b/init/init_task.c +index 5aebe3be4d7cd..994ffe0181208 100644 +--- a/init/init_task.c ++++ b/init/init_task.c +@@ -168,7 +168,8 @@ struct task_struct init_task + .lockdep_recursion = 0, + #endif + #ifdef CONFIG_FUNCTION_GRAPH_TRACER +- .ret_stack = NULL, ++ .ret_stack = NULL, ++ .tracing_graph_pause = ATOMIC_INIT(0), + #endif + #if defined(CONFIG_TRACING) && defined(CONFIG_PREEMPT) + .trace_recursion = 0, +diff --git a/kernel/kprobes.c b/kernel/kprobes.c +index 6d02b78fde01e..d4435fd6fc8bc 100644 +--- a/kernel/kprobes.c ++++ b/kernel/kprobes.c +@@ -1921,29 +1921,45 @@ bool __weak arch_kprobe_on_func_entry(unsigned long offset) + return !offset; + } + +-bool kprobe_on_func_entry(kprobe_opcode_t *addr, const char *sym, unsigned long offset) ++/** ++ * kprobe_on_func_entry() -- check whether given address is function entry ++ * @addr: Target address ++ * @sym: Target symbol name ++ * @offset: The offset from the symbol or the address ++ * ++ * This checks whether the given @addr+@offset or @sym+@offset is on the ++ * function entry address or not. ++ * This returns 0 if it is the function entry, or -EINVAL if it is not. ++ * And also it returns -ENOENT if it fails the symbol or address lookup. ++ * Caller must pass @addr or @sym (either one must be NULL), or this ++ * returns -EINVAL. ++ */ ++int kprobe_on_func_entry(kprobe_opcode_t *addr, const char *sym, unsigned long offset) + { + kprobe_opcode_t *kp_addr = _kprobe_addr(addr, sym, offset); + + if (IS_ERR(kp_addr)) +- return false; ++ return PTR_ERR(kp_addr); + +- if (!kallsyms_lookup_size_offset((unsigned long)kp_addr, NULL, &offset) || +- !arch_kprobe_on_func_entry(offset)) +- return false; ++ if (!kallsyms_lookup_size_offset((unsigned long)kp_addr, NULL, &offset)) ++ return -ENOENT; + +- return true; ++ if (!arch_kprobe_on_func_entry(offset)) ++ return -EINVAL; ++ ++ return 0; + } + + int register_kretprobe(struct kretprobe *rp) + { +- int ret = 0; ++ int ret; + struct kretprobe_instance *inst; + int i; + void *addr; + +- if (!kprobe_on_func_entry(rp->kp.addr, rp->kp.symbol_name, rp->kp.offset)) +- return -EINVAL; ++ ret = kprobe_on_func_entry(rp->kp.addr, rp->kp.symbol_name, rp->kp.offset); ++ if (ret) ++ return ret; + + /* If only rp->kp.addr is specified, check reregistering kprobes */ + if (rp->kp.addr && check_kprobe_rereg(&rp->kp)) +diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c +index cce526755471f..3492202762c73 100644 +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -6875,7 +6875,6 @@ static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list) + } + + if (t->ret_stack == NULL) { +- atomic_set(&t->tracing_graph_pause, 0); + atomic_set(&t->trace_overrun, 0); + t->curr_ret_stack = -1; + t->curr_ret_depth = -1; +@@ -7088,7 +7087,6 @@ static DEFINE_PER_CPU(struct ftrace_ret_stack *, idle_ret_stack); + static void + graph_init_task(struct task_struct *t, struct ftrace_ret_stack *ret_stack) + { +- atomic_set(&t->tracing_graph_pause, 0); + atomic_set(&t->trace_overrun, 0); + t->ftrace_timestamp = 0; + /* make curr_ret_stack visible before we add the ret_stack */ +diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c +index 5c17f70c7f2d2..61eff45653f57 100644 +--- a/kernel/trace/trace_kprobe.c ++++ b/kernel/trace/trace_kprobe.c +@@ -112,9 +112,9 @@ bool trace_kprobe_on_func_entry(struct trace_event_call *call) + { + struct trace_kprobe *tk = (struct trace_kprobe *)call->data; + +- return kprobe_on_func_entry(tk->rp.kp.addr, ++ return (kprobe_on_func_entry(tk->rp.kp.addr, + tk->rp.kp.addr ? NULL : tk->rp.kp.symbol_name, +- tk->rp.kp.addr ? 0 : tk->rp.kp.offset); ++ tk->rp.kp.addr ? 0 : tk->rp.kp.offset) == 0); + } + + bool trace_kprobe_error_injectable(struct trace_event_call *call) +diff --git a/lib/string.c b/lib/string.c +index edf4907ec946f..f7f7770444bf5 100644 +--- a/lib/string.c ++++ b/lib/string.c +@@ -158,11 +158,9 @@ EXPORT_SYMBOL(strlcpy); + * @src: Where to copy the string from + * @count: Size of destination buffer + * +- * Copy the string, or as much of it as fits, into the dest buffer. +- * The routine returns the number of characters copied (not including +- * the trailing NUL) or -E2BIG if the destination buffer wasn't big enough. +- * The behavior is undefined if the string buffers overlap. +- * The destination buffer is always NUL terminated, unless it's zero-sized. ++ * Copy the string, or as much of it as fits, into the dest buffer. The ++ * behavior is undefined if the string buffers overlap. The destination ++ * buffer is always NUL terminated, unless it's zero-sized. + * + * Preferred to strlcpy() since the API doesn't require reading memory + * from the src string beyond the specified "count" bytes, and since +@@ -172,8 +170,10 @@ EXPORT_SYMBOL(strlcpy); + * + * Preferred to strncpy() since it always returns a valid string, and + * doesn't unnecessarily force the tail of the destination buffer to be +- * zeroed. If the zeroing is desired, it's likely cleaner to use strscpy() +- * with an overflow test, then just memset() the tail of the dest buffer. ++ * zeroed. If zeroing is desired please use strscpy_pad(). ++ * ++ * Return: The number of characters copied (not including the trailing ++ * %NUL) or -E2BIG if the destination buffer wasn't big enough. + */ + ssize_t strscpy(char *dest, const char *src, size_t count) + { +@@ -260,6 +260,39 @@ char *stpcpy(char *__restrict__ dest, const char *__restrict__ src) + } + EXPORT_SYMBOL(stpcpy); + ++/** ++ * strscpy_pad() - Copy a C-string into a sized buffer ++ * @dest: Where to copy the string to ++ * @src: Where to copy the string from ++ * @count: Size of destination buffer ++ * ++ * Copy the string, or as much of it as fits, into the dest buffer. The ++ * behavior is undefined if the string buffers overlap. The destination ++ * buffer is always %NUL terminated, unless it's zero-sized. ++ * ++ * If the source string is shorter than the destination buffer, zeros ++ * the tail of the destination buffer. ++ * ++ * For full explanation of why you may want to consider using the ++ * 'strscpy' functions please see the function docstring for strscpy(). ++ * ++ * Return: The number of characters copied (not including the trailing ++ * %NUL) or -E2BIG if the destination buffer wasn't big enough. ++ */ ++ssize_t strscpy_pad(char *dest, const char *src, size_t count) ++{ ++ ssize_t written; ++ ++ written = strscpy(dest, src, count); ++ if (written < 0 || written == count - 1) ++ return written; ++ ++ memset(dest + written + 1, 0, count - written - 1); ++ ++ return written; ++} ++EXPORT_SYMBOL(strscpy_pad); ++ + #ifndef __HAVE_ARCH_STRCAT + /** + * strcat - Append one %NUL-terminated string to another +diff --git a/mm/backing-dev.c b/mm/backing-dev.c +index 72e6d0c55cfad..0a970be24a28d 100644 +--- a/mm/backing-dev.c ++++ b/mm/backing-dev.c +@@ -19,6 +19,7 @@ struct backing_dev_info noop_backing_dev_info = { + EXPORT_SYMBOL_GPL(noop_backing_dev_info); + + static struct class *bdi_class; ++const char *bdi_unknown_name = "(unknown)"; + + /* + * bdi_lock protects updates to bdi_list. bdi_list has RCU reader side +diff --git a/net/key/af_key.c b/net/key/af_key.c +index e340e97224c3a..c7d5a6015389b 100644 +--- a/net/key/af_key.c ++++ b/net/key/af_key.c +@@ -2908,7 +2908,7 @@ static int count_ah_combs(const struct xfrm_tmpl *t) + break; + if (!aalg->pfkey_supported) + continue; +- if (aalg_tmpl_set(t, aalg) && aalg->available) ++ if (aalg_tmpl_set(t, aalg)) + sz += sizeof(struct sadb_comb); + } + return sz + sizeof(struct sadb_prop); +@@ -2926,7 +2926,7 @@ static int count_esp_combs(const struct xfrm_tmpl *t) + if (!ealg->pfkey_supported) + continue; + +- if (!(ealg_tmpl_set(t, ealg) && ealg->available)) ++ if (!(ealg_tmpl_set(t, ealg))) + continue; + + for (k = 1; ; k++) { +@@ -2937,7 +2937,7 @@ static int count_esp_combs(const struct xfrm_tmpl *t) + if (!aalg->pfkey_supported) + continue; + +- if (aalg_tmpl_set(t, aalg) && aalg->available) ++ if (aalg_tmpl_set(t, aalg)) + sz += sizeof(struct sadb_comb); + } + } +diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c +index 8cb7d812ccb82..e61c48c1b37d6 100644 +--- a/net/sunrpc/auth_gss/auth_gss.c ++++ b/net/sunrpc/auth_gss/auth_gss.c +@@ -53,6 +53,7 @@ + #include + #include + ++#include "auth_gss_internal.h" + #include "../netns.h" + + static const struct rpc_authops authgss_ops; +@@ -147,35 +148,6 @@ gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx) + clear_bit(RPCAUTH_CRED_NEW, &cred->cr_flags); + } + +-static const void * +-simple_get_bytes(const void *p, const void *end, void *res, size_t len) +-{ +- const void *q = (const void *)((const char *)p + len); +- if (unlikely(q > end || q < p)) +- return ERR_PTR(-EFAULT); +- memcpy(res, p, len); +- return q; +-} +- +-static inline const void * +-simple_get_netobj(const void *p, const void *end, struct xdr_netobj *dest) +-{ +- const void *q; +- unsigned int len; +- +- p = simple_get_bytes(p, end, &len, sizeof(len)); +- if (IS_ERR(p)) +- return p; +- q = (const void *)((const char *)p + len); +- if (unlikely(q > end || q < p)) +- return ERR_PTR(-EFAULT); +- dest->data = kmemdup(p, len, GFP_NOFS); +- if (unlikely(dest->data == NULL)) +- return ERR_PTR(-ENOMEM); +- dest->len = len; +- return q; +-} +- + static struct gss_cl_ctx * + gss_cred_get_ctx(struct rpc_cred *cred) + { +diff --git a/net/sunrpc/auth_gss/auth_gss_internal.h b/net/sunrpc/auth_gss/auth_gss_internal.h +new file mode 100644 +index 0000000000000..f6d9631bd9d00 +--- /dev/null ++++ b/net/sunrpc/auth_gss/auth_gss_internal.h +@@ -0,0 +1,45 @@ ++// SPDX-License-Identifier: BSD-3-Clause ++/* ++ * linux/net/sunrpc/auth_gss/auth_gss_internal.h ++ * ++ * Internal definitions for RPCSEC_GSS client authentication ++ * ++ * Copyright (c) 2000 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ */ ++#include ++#include ++#include ++ ++static inline const void * ++simple_get_bytes(const void *p, const void *end, void *res, size_t len) ++{ ++ const void *q = (const void *)((const char *)p + len); ++ if (unlikely(q > end || q < p)) ++ return ERR_PTR(-EFAULT); ++ memcpy(res, p, len); ++ return q; ++} ++ ++static inline const void * ++simple_get_netobj(const void *p, const void *end, struct xdr_netobj *dest) ++{ ++ const void *q; ++ unsigned int len; ++ ++ p = simple_get_bytes(p, end, &len, sizeof(len)); ++ if (IS_ERR(p)) ++ return p; ++ q = (const void *)((const char *)p + len); ++ if (unlikely(q > end || q < p)) ++ return ERR_PTR(-EFAULT); ++ if (len) { ++ dest->data = kmemdup(p, len, GFP_NOFS); ++ if (unlikely(dest->data == NULL)) ++ return ERR_PTR(-ENOMEM); ++ } else ++ dest->data = NULL; ++ dest->len = len; ++ return q; ++} +diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c +index 7bb2514aadd9d..14f2823ad6c20 100644 +--- a/net/sunrpc/auth_gss/gss_krb5_mech.c ++++ b/net/sunrpc/auth_gss/gss_krb5_mech.c +@@ -46,6 +46,8 @@ + #include + #include + ++#include "auth_gss_internal.h" ++ + #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) + # define RPCDBG_FACILITY RPCDBG_AUTH + #endif +@@ -187,35 +189,6 @@ get_gss_krb5_enctype(int etype) + return NULL; + } + +-static const void * +-simple_get_bytes(const void *p, const void *end, void *res, int len) +-{ +- const void *q = (const void *)((const char *)p + len); +- if (unlikely(q > end || q < p)) +- return ERR_PTR(-EFAULT); +- memcpy(res, p, len); +- return q; +-} +- +-static const void * +-simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res) +-{ +- const void *q; +- unsigned int len; +- +- p = simple_get_bytes(p, end, &len, sizeof(len)); +- if (IS_ERR(p)) +- return p; +- q = (const void *)((const char *)p + len); +- if (unlikely(q > end || q < p)) +- return ERR_PTR(-EFAULT); +- res->data = kmemdup(p, len, GFP_NOFS); +- if (unlikely(res->data == NULL)) +- return ERR_PTR(-ENOMEM); +- res->len = len; +- return q; +-} +- + static inline const void * + get_key(const void *p, const void *end, + struct krb5_ctx *ctx, struct crypto_skcipher **res)