commit:     b8fb76f331e61bb279309ae39b860435aa6748c1
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sun Aug 15 20:07:18 2021 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sun Aug 15 20:07:18 2021 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=b8fb76f3

Linux patch 4.19.204

Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>

 0000_README               |   4 +
 1203_linux-4.19.204.patch | 434 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 438 insertions(+)

diff --git a/0000_README b/0000_README
index d01fd15..398311f 100644
--- a/0000_README
+++ b/0000_README
@@ -851,6 +851,10 @@ Patch:  1202_linux-4.19.203.patch
 From:   https://www.kernel.org
 Desc:   Linux 4.19.203
 
+Patch:  1203_linux-4.19.204.patch
+From:   https://www.kernel.org
+Desc:   Linux 4.19.204
+
 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/1203_linux-4.19.204.patch b/1203_linux-4.19.204.patch
new file mode 100644
index 0000000..94c62e8
--- /dev/null
+++ b/1203_linux-4.19.204.patch
@@ -0,0 +1,434 @@
+diff --git a/Documentation/virtual/kvm/mmu.txt 
b/Documentation/virtual/kvm/mmu.txt
+index e507a9e0421ed..851a8abcadce4 100644
+--- a/Documentation/virtual/kvm/mmu.txt
++++ b/Documentation/virtual/kvm/mmu.txt
+@@ -152,8 +152,8 @@ Shadow pages contain the following information:
+     shadow pages) so role.quadrant takes values in the range 0..3.  Each
+     quadrant maps 1GB virtual address space.
+   role.access:
+-    Inherited guest access permissions in the form uwx.  Note execute
+-    permission is positive, not negative.
++    Inherited guest access permissions from the parent ptes in the form uwx.
++    Note execute permission is positive, not negative.
+   role.invalid:
+     The page is invalid and should not be used.  It is a root page that is
+     currently pinned (by a cpu hardware register pointing to it); once it is
+diff --git a/Makefile b/Makefile
+index 6d2670300d470..d4ffcafb8efad 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 4
+ PATCHLEVEL = 19
+-SUBLEVEL = 203
++SUBLEVEL = 204
+ EXTRAVERSION =
+ NAME = "People's Front"
+ 
+diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
+index 8220190b06050..9e15818de9737 100644
+--- a/arch/x86/kvm/paging_tmpl.h
++++ b/arch/x86/kvm/paging_tmpl.h
+@@ -93,8 +93,8 @@ struct guest_walker {
+       gpa_t pte_gpa[PT_MAX_FULL_LEVELS];
+       pt_element_t __user *ptep_user[PT_MAX_FULL_LEVELS];
+       bool pte_writable[PT_MAX_FULL_LEVELS];
+-      unsigned pt_access;
+-      unsigned pte_access;
++      unsigned int pt_access[PT_MAX_FULL_LEVELS];
++      unsigned int pte_access;
+       gfn_t gfn;
+       struct x86_exception fault;
+ };
+@@ -388,13 +388,15 @@ retry_walk:
+               }
+ 
+               walker->ptes[walker->level - 1] = pte;
++
++              /* Convert to ACC_*_MASK flags for struct guest_walker.  */
++              walker->pt_access[walker->level - 1] = 
FNAME(gpte_access)(pt_access ^ walk_nx_mask);
+       } while (!is_last_gpte(mmu, walker->level, pte));
+ 
+       pte_pkey = FNAME(gpte_pkeys)(vcpu, pte);
+       accessed_dirty = have_ad ? pte_access & PT_GUEST_ACCESSED_MASK : 0;
+ 
+       /* Convert to ACC_*_MASK flags for struct guest_walker.  */
+-      walker->pt_access = FNAME(gpte_access)(pt_access ^ walk_nx_mask);
+       walker->pte_access = FNAME(gpte_access)(pte_access ^ walk_nx_mask);
+       errcode = permission_fault(vcpu, mmu, walker->pte_access, pte_pkey, 
access);
+       if (unlikely(errcode))
+@@ -433,7 +435,8 @@ retry_walk:
+       }
+ 
+       pgprintk("%s: pte %llx pte_access %x pt_access %x\n",
+-               __func__, (u64)pte, walker->pte_access, walker->pt_access);
++               __func__, (u64)pte, walker->pte_access,
++               walker->pt_access[walker->level - 1]);
+       return 1;
+ 
+ error:
+@@ -602,7 +605,7 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, gpa_t addr,
+ {
+       struct kvm_mmu_page *sp = NULL;
+       struct kvm_shadow_walk_iterator it;
+-      unsigned direct_access, access = gw->pt_access;
++      unsigned int direct_access, access;
+       int top_level, ret;
+       gfn_t gfn, base_gfn;
+ 
+@@ -634,6 +637,7 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, gpa_t addr,
+               sp = NULL;
+               if (!is_shadow_present_pte(*it.sptep)) {
+                       table_gfn = gw->table_gfn[it.level - 2];
++                      access = gw->pt_access[it.level - 2];
+                       sp = kvm_mmu_get_page(vcpu, table_gfn, addr, it.level-1,
+                                             false, access);
+               }
+diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
+index bd463d6842370..72d729f34437d 100644
+--- a/arch/x86/kvm/svm.c
++++ b/arch/x86/kvm/svm.c
+@@ -1780,7 +1780,7 @@ static void __sev_asid_free(int asid)
+ 
+       for_each_possible_cpu(cpu) {
+               sd = per_cpu(svm_data, cpu);
+-              sd->sev_vmcbs[pos] = NULL;
++              sd->sev_vmcbs[asid] = NULL;
+       }
+ }
+ 
+diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c 
b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+index c77c81eb7ab3b..edb2215f99930 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
++++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+@@ -1177,9 +1177,8 @@ static int xemaclite_of_probe(struct platform_device 
*ofdev)
+       }
+ 
+       dev_info(dev,
+-               "Xilinx EmacLite at 0x%08X mapped to 0x%08X, irq=%d\n",
+-               (unsigned int __force)ndev->mem_start,
+-               (unsigned int __force)lp->base_addr, ndev->irq);
++               "Xilinx EmacLite at 0x%08X mapped to 0x%p, irq=%d\n",
++               (unsigned int __force)ndev->mem_start, lp->base_addr, 
ndev->irq);
+       return 0;
+ 
+ error:
+diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
+index 3e014ecffef8e..1af47aaa7ba57 100644
+--- a/drivers/net/ppp/ppp_generic.c
++++ b/drivers/net/ppp/ppp_generic.c
+@@ -287,7 +287,7 @@ static struct channel *ppp_find_channel(struct ppp_net 
*pn, int unit);
+ static int ppp_connect_channel(struct channel *pch, int unit);
+ static int ppp_disconnect_channel(struct channel *pch);
+ static void ppp_destroy_channel(struct channel *pch);
+-static int unit_get(struct idr *p, void *ptr);
++static int unit_get(struct idr *p, void *ptr, int min);
+ static int unit_set(struct idr *p, void *ptr, int n);
+ static void unit_put(struct idr *p, int n);
+ static void *unit_find(struct idr *p, int n);
+@@ -963,9 +963,20 @@ static int ppp_unit_register(struct ppp *ppp, int unit, 
bool ifname_is_set)
+       mutex_lock(&pn->all_ppp_mutex);
+ 
+       if (unit < 0) {
+-              ret = unit_get(&pn->units_idr, ppp);
++              ret = unit_get(&pn->units_idr, ppp, 0);
+               if (ret < 0)
+                       goto err;
++              if (!ifname_is_set) {
++                      while (1) {
++                              snprintf(ppp->dev->name, IFNAMSIZ, "ppp%i", 
ret);
++                              if (!__dev_get_by_name(ppp->ppp_net, 
ppp->dev->name))
++                                      break;
++                              unit_put(&pn->units_idr, ret);
++                              ret = unit_get(&pn->units_idr, ppp, ret + 1);
++                              if (ret < 0)
++                                      goto err;
++                      }
++              }
+       } else {
+               /* Caller asked for a specific unit number. Fail with -EEXIST
+                * if unavailable. For backward compatibility, return -EEXIST
+@@ -3252,9 +3263,9 @@ static int unit_set(struct idr *p, void *ptr, int n)
+ }
+ 
+ /* get new free unit number and associate pointer with it */
+-static int unit_get(struct idr *p, void *ptr)
++static int unit_get(struct idr *p, void *ptr, int min)
+ {
+-      return idr_alloc(p, ptr, 0, 0, GFP_KERNEL);
++      return idr_alloc(p, ptr, min, 0, GFP_KERNEL);
+ }
+ 
+ /* put unit number back to a pool */
+diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
+index fcfad5c298a9f..56e6fd0f04829 100644
+--- a/drivers/usb/host/ehci-pci.c
++++ b/drivers/usb/host/ehci-pci.c
+@@ -298,6 +298,9 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
+       if (pdev->vendor == PCI_VENDOR_ID_STMICRO
+           && pdev->device == PCI_DEVICE_ID_STMICRO_USB_HOST)
+               ;       /* ConneXT has no sbrn register */
++      else if (pdev->vendor == PCI_VENDOR_ID_HUAWEI
++                       && pdev->device == 0xa239)
++              ;       /* HUAWEI Kunpeng920 USB EHCI has no sbrn register */
+       else
+               pci_read_config_byte(pdev, 0x60, &ehci->sbrn);
+ 
+diff --git a/fs/namespace.c b/fs/namespace.c
+index 741f40cd955ef..edd397fa29913 100644
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -1799,6 +1799,20 @@ void drop_collected_mounts(struct vfsmount *mnt)
+       namespace_unlock();
+ }
+ 
++static bool has_locked_children(struct mount *mnt, struct dentry *dentry)
++{
++      struct mount *child;
++
++      list_for_each_entry(child, &mnt->mnt_mounts, mnt_child) {
++              if (!is_subdir(child->mnt_mountpoint, dentry))
++                      continue;
++
++              if (child->mnt.mnt_flags & MNT_LOCKED)
++                      return true;
++      }
++      return false;
++}
++
+ /**
+  * clone_private_mount - create a private clone of a path
+  *
+@@ -1813,14 +1827,27 @@ struct vfsmount *clone_private_mount(const struct path 
*path)
+       struct mount *old_mnt = real_mount(path->mnt);
+       struct mount *new_mnt;
+ 
++      down_read(&namespace_sem);
+       if (IS_MNT_UNBINDABLE(old_mnt))
+-              return ERR_PTR(-EINVAL);
++              goto invalid;
++
++      if (!check_mnt(old_mnt))
++              goto invalid;
++
++      if (has_locked_children(old_mnt, path->dentry))
++              goto invalid;
+ 
+       new_mnt = clone_mnt(old_mnt, path->dentry, CL_PRIVATE);
++      up_read(&namespace_sem);
++
+       if (IS_ERR(new_mnt))
+               return ERR_CAST(new_mnt);
+ 
+       return &new_mnt->mnt;
++
++invalid:
++      up_read(&namespace_sem);
++      return ERR_PTR(-EINVAL);
+ }
+ EXPORT_SYMBOL_GPL(clone_private_mount);
+ 
+@@ -2136,19 +2163,6 @@ static int do_change_type(struct path *path, int 
ms_flags)
+       return err;
+ }
+ 
+-static bool has_locked_children(struct mount *mnt, struct dentry *dentry)
+-{
+-      struct mount *child;
+-      list_for_each_entry(child, &mnt->mnt_mounts, mnt_child) {
+-              if (!is_subdir(child->mnt_mountpoint, dentry))
+-                      continue;
+-
+-              if (child->mnt.mnt_flags & MNT_LOCKED)
+-                      return true;
+-      }
+-      return false;
+-}
+-
+ /*
+  * do loopback mount.
+  */
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 4ce032c4acd03..2bf83305e5aba 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -2812,6 +2812,27 @@ struct bpf_sanitize_info {
+       bool mask_to_left;
+ };
+ 
++static struct bpf_verifier_state *
++sanitize_speculative_path(struct bpf_verifier_env *env,
++                        const struct bpf_insn *insn,
++                        u32 next_idx, u32 curr_idx)
++{
++      struct bpf_verifier_state *branch;
++      struct bpf_reg_state *regs;
++
++      branch = push_stack(env, next_idx, curr_idx, true);
++      if (branch && insn) {
++              regs = branch->frame[branch->curframe]->regs;
++              if (BPF_SRC(insn->code) == BPF_K) {
++                      mark_reg_unknown(env, regs, insn->dst_reg);
++              } else if (BPF_SRC(insn->code) == BPF_X) {
++                      mark_reg_unknown(env, regs, insn->dst_reg);
++                      mark_reg_unknown(env, regs, insn->src_reg);
++              }
++      }
++      return branch;
++}
++
+ static int sanitize_ptr_alu(struct bpf_verifier_env *env,
+                           struct bpf_insn *insn,
+                           const struct bpf_reg_state *ptr_reg,
+@@ -2895,12 +2916,26 @@ do_sim:
+               tmp = *dst_reg;
+               *dst_reg = *ptr_reg;
+       }
+-      ret = push_stack(env, env->insn_idx + 1, env->insn_idx, true);
++      ret = sanitize_speculative_path(env, NULL, env->insn_idx + 1,
++                                      env->insn_idx);
+       if (!ptr_is_dst_reg && ret)
+               *dst_reg = tmp;
+       return !ret ? REASON_STACK : 0;
+ }
+ 
++static void sanitize_mark_insn_seen(struct bpf_verifier_env *env)
++{
++      struct bpf_verifier_state *vstate = env->cur_state;
++
++      /* If we simulate paths under speculation, we don't update the
++       * insn as 'seen' such that when we verify unreachable paths in
++       * the non-speculative domain, sanitize_dead_code() can still
++       * rewrite/sanitize them.
++       */
++      if (!vstate->speculative)
++              env->insn_aux_data[env->insn_idx].seen = true;
++}
++
+ static int sanitize_err(struct bpf_verifier_env *env,
+                       const struct bpf_insn *insn, int reason,
+                       const struct bpf_reg_state *off_reg,
+@@ -4275,14 +4310,28 @@ static int check_cond_jmp_op(struct bpf_verifier_env 
*env,
+                tnum_is_const(src_reg->var_off))
+               pred = is_branch_taken(dst_reg, src_reg->var_off.value,
+                                      opcode);
++
+       if (pred == 1) {
+-              /* only follow the goto, ignore fall-through */
++              /* Only follow the goto, ignore fall-through. If needed, push
++               * the fall-through branch for simulation under speculative
++               * execution.
++               */
++              if (!env->allow_ptr_leaks &&
++                  !sanitize_speculative_path(env, insn, *insn_idx + 1,
++                                             *insn_idx))
++                      return -EFAULT;
+               *insn_idx += insn->off;
+               return 0;
+       } else if (pred == 0) {
+-              /* only follow fall-through branch, since
+-               * that's where the program will go
++              /* Only follow the fall-through branch, since that's where the
++               * program will go. If needed, push the goto branch for
++               * simulation under speculative execution.
+                */
++              if (!env->allow_ptr_leaks &&
++                  !sanitize_speculative_path(env, insn,
++                                             *insn_idx + insn->off + 1,
++                                             *insn_idx))
++                      return -EFAULT;
+               return 0;
+       }
+ 
+@@ -5254,7 +5303,7 @@ static int do_check(struct bpf_verifier_env *env)
+               }
+ 
+               regs = cur_regs(env);
+-              env->insn_aux_data[env->insn_idx].seen = true;
++              sanitize_mark_insn_seen(env);
+ 
+               if (class == BPF_ALU || class == BPF_ALU64) {
+                       err = check_alu_op(env, insn);
+@@ -5472,7 +5521,7 @@ process_bpf_exit:
+                                       return err;
+ 
+                               env->insn_idx++;
+-                              env->insn_aux_data[env->insn_idx].seen = true;
++                              sanitize_mark_insn_seen(env);
+                       } else {
+                               verbose(env, "invalid BPF_LD mode\n");
+                               return -EINVAL;
+@@ -5690,6 +5739,7 @@ static int adjust_insn_aux_data(struct bpf_verifier_env 
*env, u32 prog_len,
+                               u32 off, u32 cnt)
+ {
+       struct bpf_insn_aux_data *new_data, *old_data = env->insn_aux_data;
++      bool old_seen = old_data[off].seen;
+       int i;
+ 
+       if (cnt == 1)
+@@ -5701,8 +5751,10 @@ static int adjust_insn_aux_data(struct bpf_verifier_env 
*env, u32 prog_len,
+       memcpy(new_data, old_data, sizeof(struct bpf_insn_aux_data) * off);
+       memcpy(new_data + off + cnt - 1, old_data + off,
+              sizeof(struct bpf_insn_aux_data) * (prog_len - off - cnt + 1));
+-      for (i = off; i < off + cnt - 1; i++)
+-              new_data[i].seen = true;
++      for (i = off; i < off + cnt - 1; i++) {
++              /* Expand insni[off]'s seen count to the patched range. */
++              new_data[i].seen = old_seen;
++      }
+       env->insn_aux_data = new_data;
+       vfree(old_data);
+       return 0;
+diff --git a/kernel/trace/trace_events_hist.c 
b/kernel/trace/trace_events_hist.c
+index 6d2a69652c391..bbde8d3d6c8ae 100644
+--- a/kernel/trace/trace_events_hist.c
++++ b/kernel/trace/trace_events_hist.c
+@@ -2790,6 +2790,12 @@ static struct hist_field *parse_unary(struct 
hist_trigger_data *hist_data,
+               ret = PTR_ERR(operand1);
+               goto free;
+       }
++      if (operand1->flags & HIST_FIELD_FL_STRING) {
++              /* String type can not be the operand of unary operator. */
++              destroy_hist_field(operand1, 0);
++              ret = -EINVAL;
++              goto free;
++      }
+ 
+       expr->flags |= operand1->flags &
+               (HIST_FIELD_FL_TIMESTAMP | HIST_FIELD_FL_TIMESTAMP_USECS);
+@@ -2890,6 +2896,10 @@ static struct hist_field *parse_expr(struct 
hist_trigger_data *hist_data,
+               operand1 = NULL;
+               goto free;
+       }
++      if (operand1->flags & HIST_FIELD_FL_STRING) {
++              ret = -EINVAL;
++              goto free;
++      }
+ 
+       /* rest of string could be another expression e.g. b+c in a+b+c */
+       operand_flags = 0;
+@@ -2899,6 +2909,10 @@ static struct hist_field *parse_expr(struct 
hist_trigger_data *hist_data,
+               operand2 = NULL;
+               goto free;
+       }
++      if (operand2->flags & HIST_FIELD_FL_STRING) {
++              ret = -EINVAL;
++              goto free;
++      }
+ 
+       ret = check_expr_operands(operand1, operand2);
+       if (ret)
+diff --git a/tools/testing/selftests/bpf/test_verifier.c 
b/tools/testing/selftests/bpf/test_verifier.c
+index b44324530948d..c7d17781dbfee 100644
+--- a/tools/testing/selftests/bpf/test_verifier.c
++++ b/tools/testing/selftests/bpf/test_verifier.c
+@@ -2792,6 +2792,8 @@ static struct bpf_test tests[] = {
+                       BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
+                       BPF_EXIT_INSN(),
+               },
++              .errstr_unpriv = "R7 invalid mem access 'inv'",
++              .result_unpriv = REJECT,
+               .result = ACCEPT,
+               .retval = 0,
+       },

Reply via email to