From: Greg Kroah-Hartman Date: Thu, 14 Apr 2022 10:46:33 +0000 (+0200) Subject: 4.19-stable patches X-Git-Tag: v4.19.238~23 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3f732e994de66e4f8c7db93c5f601384aeafe8ae;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: drm-amdgpu-check-if-fd-really-is-an-amdgpu-fd.patch drm-amdkfd-use-drm_priv-to-pass-vm-from-kfd-to-amdgpu.patch xfrm-policy-match-with-both-mark-and-mask-on-user-interfaces.patch --- diff --git a/queue-4.19/drm-amdgpu-check-if-fd-really-is-an-amdgpu-fd.patch b/queue-4.19/drm-amdgpu-check-if-fd-really-is-an-amdgpu-fd.patch new file mode 100644 index 00000000000..a7124498b36 --- /dev/null +++ b/queue-4.19/drm-amdgpu-check-if-fd-really-is-an-amdgpu-fd.patch @@ -0,0 +1,88 @@ +From 021830d24ba55a578f602979274965344c8e6284 Mon Sep 17 00:00:00 2001 +From: Bas Nieuwenhuizen +Date: Wed, 30 Jan 2019 02:53:21 +0100 +Subject: drm/amdgpu: Check if fd really is an amdgpu fd. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Bas Nieuwenhuizen + +commit 021830d24ba55a578f602979274965344c8e6284 upstream. + +Otherwise we interpret the file private data as drm & amdgpu data +while it might not be, possibly allowing one to get memory corruption. + +Signed-off-by: Bas Nieuwenhuizen +Reviewed-by: Christian König +Signed-off-by: Alex Deucher +Signed-off-by: Lee Jones +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 ++ + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 16 ++++++++++++++++ + drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | 10 +++++++--- + 3 files changed, 25 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +@@ -955,6 +955,8 @@ struct amdgpu_gfx { + DECLARE_BITMAP (pipe_reserve_bitmap, AMDGPU_MAX_COMPUTE_QUEUES); + }; + ++int amdgpu_file_to_fpriv(struct file *filp, struct amdgpu_fpriv **fpriv); ++ + int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, + unsigned size, struct amdgpu_ib *ib); + void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib, +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +@@ -1132,6 +1132,22 @@ static const struct file_operations amdg + #endif + }; + ++int amdgpu_file_to_fpriv(struct file *filp, struct amdgpu_fpriv **fpriv) ++{ ++ struct drm_file *file; ++ ++ if (!filp) ++ return -EINVAL; ++ ++ if (filp->f_op != &amdgpu_driver_kms_fops) { ++ return -EINVAL; ++ } ++ ++ file = filp->private_data; ++ *fpriv = file->driver_priv; ++ return 0; ++} ++ + static bool + amdgpu_get_crtc_scanout_position(struct drm_device *dev, unsigned int pipe, + bool in_vblank_irq, int *vpos, int *hpos, +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c +@@ -54,16 +54,20 @@ static int amdgpu_sched_process_priority + enum drm_sched_priority priority) + { + struct file *filp = fget(fd); +- struct drm_file *file; + struct amdgpu_fpriv *fpriv; + struct amdgpu_ctx *ctx; + uint32_t id; ++ int r; + + if (!filp) + return -EINVAL; + +- file = filp->private_data; +- fpriv = file->driver_priv; ++ r = amdgpu_file_to_fpriv(filp, &fpriv); ++ if (r) { ++ fput(filp); ++ return r; ++ } ++ + idr_for_each_entry(&fpriv->ctx_mgr.ctx_handles, ctx, id) + amdgpu_ctx_priority_override(ctx, priority); + diff --git a/queue-4.19/drm-amdkfd-use-drm_priv-to-pass-vm-from-kfd-to-amdgpu.patch b/queue-4.19/drm-amdkfd-use-drm_priv-to-pass-vm-from-kfd-to-amdgpu.patch new file mode 100644 index 00000000000..0a76701af79 --- /dev/null +++ b/queue-4.19/drm-amdkfd-use-drm_priv-to-pass-vm-from-kfd-to-amdgpu.patch @@ -0,0 +1,45 @@ +From b40a6ab2cf9213923bf8e821ce7fa7f6a0a26990 Mon Sep 17 00:00:00 2001 +From: Felix Kuehling +Date: Wed, 7 Apr 2021 18:19:58 -0400 +Subject: drm/amdkfd: Use drm_priv to pass VM from KFD to amdgpu + +From: Felix Kuehling + +commit b40a6ab2cf9213923bf8e821ce7fa7f6a0a26990 upstream. + +amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu needs the drm_priv to allow mmap +to access the BO through the corresponding file descriptor. The VM can +also be extracted from drm_priv, so drm_priv can replace the vm parameter +in the kfd2kgd interface. + +Signed-off-by: Felix Kuehling +Reviewed-by: Philip Yang +Signed-off-by: Alex Deucher +[ This is a partial cherry-pick of the commit. ] +Signed-off-by: Lee Jones +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +@@ -1044,11 +1044,15 @@ int amdgpu_amdkfd_gpuvm_acquire_process_ + struct dma_fence **ef) + { + struct amdgpu_device *adev = get_amdgpu_device(kgd); +- struct drm_file *drm_priv = filp->private_data; +- struct amdgpu_fpriv *drv_priv = drm_priv->driver_priv; +- struct amdgpu_vm *avm = &drv_priv->vm; ++ struct amdgpu_fpriv *drv_priv; ++ struct amdgpu_vm *avm; + int ret; + ++ ret = amdgpu_file_to_fpriv(filp, &drv_priv); ++ if (ret) ++ return ret; ++ avm = &drv_priv->vm; ++ + /* Already a compute VM? */ + if (avm->process_info) + return -EINVAL; diff --git a/queue-4.19/series b/queue-4.19/series index f97c7803e48..cb680610a89 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -333,3 +333,6 @@ cgroup-use-open-time-cgroup-namespace-for-process-migration-perm-checks.patch selftests-cgroup-make-cg_create-use-0755-for-permission-instead-of-0644.patch selftests-cgroup-test-open-time-credential-usage-for-migration-checks.patch selftests-cgroup-test-open-time-cgroup-namespace-usage-for-migration-checks.patch +xfrm-policy-match-with-both-mark-and-mask-on-user-interfaces.patch +drm-amdgpu-check-if-fd-really-is-an-amdgpu-fd.patch +drm-amdkfd-use-drm_priv-to-pass-vm-from-kfd-to-amdgpu.patch diff --git a/queue-4.19/xfrm-policy-match-with-both-mark-and-mask-on-user-interfaces.patch b/queue-4.19/xfrm-policy-match-with-both-mark-and-mask-on-user-interfaces.patch new file mode 100644 index 00000000000..67cd52c3522 --- /dev/null +++ b/queue-4.19/xfrm-policy-match-with-both-mark-and-mask-on-user-interfaces.patch @@ -0,0 +1,231 @@ +From 4f47e8ab6ab796b5380f74866fa5287aca4dcc58 Mon Sep 17 00:00:00 2001 +From: Xin Long +Date: Mon, 22 Jun 2020 16:40:29 +0800 +Subject: xfrm: policy: match with both mark and mask on user interfaces + +From: Xin Long + +commit 4f47e8ab6ab796b5380f74866fa5287aca4dcc58 upstream. + +In commit ed17b8d377ea ("xfrm: fix a warning in xfrm_policy_insert_list"), +it would take 'priority' to make a policy unique, and allow duplicated +policies with different 'priority' to be added, which is not expected +by userland, as Tobias reported in strongswan. + +To fix this duplicated policies issue, and also fix the issue in +commit ed17b8d377ea ("xfrm: fix a warning in xfrm_policy_insert_list"), +when doing add/del/get/update on user interfaces, this patch is to change +to look up a policy with both mark and mask by doing: + + mark.v == pol->mark.v && mark.m == pol->mark.m + +and leave the check: + + (mark & pol->mark.m) == pol->mark.v + +for tx/rx path only. + +As the userland expects an exact mark and mask match to manage policies. + +v1->v2: + - make xfrm_policy_mark_match inline and fix the changelog as + Tobias suggested. + +Fixes: 295fae568885 ("xfrm: Allow user space manipulation of SPD mark") +Fixes: ed17b8d377ea ("xfrm: fix a warning in xfrm_policy_insert_list") +Reported-by: Tobias Brunner +Tested-by: Tobias Brunner +Signed-off-by: Xin Long +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman +--- + include/net/xfrm.h | 11 +++++++---- + net/key/af_key.c | 4 ++-- + net/xfrm/xfrm_policy.c | 32 +++++++++++++------------------- + net/xfrm/xfrm_user.c | 18 +++++++++++------- + 4 files changed, 33 insertions(+), 32 deletions(-) + +--- a/include/net/xfrm.h ++++ b/include/net/xfrm.h +@@ -1739,13 +1739,16 @@ int xfrm_policy_walk(struct net *net, st + void *); + void xfrm_policy_walk_done(struct xfrm_policy_walk *walk, struct net *net); + int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl); +-struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, u32 if_id, +- u8 type, int dir, ++struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, ++ const struct xfrm_mark *mark, ++ u32 if_id, u8 type, int dir, + struct xfrm_selector *sel, + struct xfrm_sec_ctx *ctx, int delete, + int *err); +-struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u32 if_id, u8, +- int dir, u32 id, int delete, int *err); ++struct xfrm_policy *xfrm_policy_byid(struct net *net, ++ const struct xfrm_mark *mark, u32 if_id, ++ u8 type, int dir, u32 id, int delete, ++ int *err); + int xfrm_policy_flush(struct net *net, u8 type, bool task_valid); + void xfrm_policy_hash_rebuild(struct net *net); + u32 xfrm_get_acqseq(void); +--- a/net/key/af_key.c ++++ b/net/key/af_key.c +@@ -2413,7 +2413,7 @@ static int pfkey_spddelete(struct sock * + return err; + } + +- xp = xfrm_policy_bysel_ctx(net, DUMMY_MARK, 0, XFRM_POLICY_TYPE_MAIN, ++ xp = xfrm_policy_bysel_ctx(net, &dummy_mark, 0, XFRM_POLICY_TYPE_MAIN, + pol->sadb_x_policy_dir - 1, &sel, pol_ctx, + 1, &err); + security_xfrm_policy_free(pol_ctx); +@@ -2664,7 +2664,7 @@ static int pfkey_spdget(struct sock *sk, + return -EINVAL; + + delete = (hdr->sadb_msg_type == SADB_X_SPDDELETE2); +- xp = xfrm_policy_byid(net, DUMMY_MARK, 0, XFRM_POLICY_TYPE_MAIN, ++ xp = xfrm_policy_byid(net, &dummy_mark, 0, XFRM_POLICY_TYPE_MAIN, + dir, pol->sadb_x_policy_id, delete, &err); + if (xp == NULL) + return -ENOENT; +--- a/net/xfrm/xfrm_policy.c ++++ b/net/xfrm/xfrm_policy.c +@@ -727,14 +727,10 @@ static void xfrm_policy_requeue(struct x + spin_unlock_bh(&pq->hold_queue.lock); + } + +-static bool xfrm_policy_mark_match(struct xfrm_policy *policy, +- struct xfrm_policy *pol) ++static inline bool xfrm_policy_mark_match(const struct xfrm_mark *mark, ++ struct xfrm_policy *pol) + { +- if (policy->mark.v == pol->mark.v && +- policy->priority == pol->priority) +- return true; +- +- return false; ++ return mark->v == pol->mark.v && mark->m == pol->mark.m; + } + + int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) +@@ -753,7 +749,7 @@ int xfrm_policy_insert(int dir, struct x + if (pol->type == policy->type && + pol->if_id == policy->if_id && + !selector_cmp(&pol->selector, &policy->selector) && +- xfrm_policy_mark_match(policy, pol) && ++ xfrm_policy_mark_match(&policy->mark, pol) && + xfrm_sec_ctx_match(pol->security, policy->security) && + !WARN_ON(delpol)) { + if (excl) { +@@ -803,11 +799,10 @@ int xfrm_policy_insert(int dir, struct x + } + EXPORT_SYMBOL(xfrm_policy_insert); + +-struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, u32 if_id, +- u8 type, int dir, +- struct xfrm_selector *sel, +- struct xfrm_sec_ctx *ctx, int delete, +- int *err) ++struct xfrm_policy * ++xfrm_policy_bysel_ctx(struct net *net, const struct xfrm_mark *mark, u32 if_id, ++ u8 type, int dir, struct xfrm_selector *sel, ++ struct xfrm_sec_ctx *ctx, int delete, int *err) + { + struct xfrm_policy *pol, *ret; + struct hlist_head *chain; +@@ -819,7 +814,7 @@ struct xfrm_policy *xfrm_policy_bysel_ct + hlist_for_each_entry(pol, chain, bydst) { + if (pol->type == type && + pol->if_id == if_id && +- (mark & pol->mark.m) == pol->mark.v && ++ xfrm_policy_mark_match(mark, pol) && + !selector_cmp(sel, &pol->selector) && + xfrm_sec_ctx_match(ctx, pol->security)) { + xfrm_pol_hold(pol); +@@ -844,9 +839,9 @@ struct xfrm_policy *xfrm_policy_bysel_ct + } + EXPORT_SYMBOL(xfrm_policy_bysel_ctx); + +-struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u32 if_id, +- u8 type, int dir, u32 id, int delete, +- int *err) ++struct xfrm_policy * ++xfrm_policy_byid(struct net *net, const struct xfrm_mark *mark, u32 if_id, ++ u8 type, int dir, u32 id, int delete, int *err) + { + struct xfrm_policy *pol, *ret; + struct hlist_head *chain; +@@ -861,8 +856,7 @@ struct xfrm_policy *xfrm_policy_byid(str + ret = NULL; + hlist_for_each_entry(pol, chain, byidx) { + if (pol->type == type && pol->index == id && +- pol->if_id == if_id && +- (mark & pol->mark.m) == pol->mark.v) { ++ pol->if_id == if_id && xfrm_policy_mark_match(mark, pol)) { + xfrm_pol_hold(pol); + if (delete) { + *err = security_xfrm_policy_delete( +--- a/net/xfrm/xfrm_user.c ++++ b/net/xfrm/xfrm_user.c +@@ -1862,7 +1862,6 @@ static int xfrm_get_policy(struct sk_buf + struct km_event c; + int delete; + struct xfrm_mark m; +- u32 mark = xfrm_mark_get(attrs, &m); + u32 if_id = 0; + + p = nlmsg_data(nlh); +@@ -1879,8 +1878,11 @@ static int xfrm_get_policy(struct sk_buf + if (attrs[XFRMA_IF_ID]) + if_id = nla_get_u32(attrs[XFRMA_IF_ID]); + ++ xfrm_mark_get(attrs, &m); ++ + if (p->index) +- xp = xfrm_policy_byid(net, mark, if_id, type, p->dir, p->index, delete, &err); ++ xp = xfrm_policy_byid(net, &m, if_id, type, p->dir, ++ p->index, delete, &err); + else { + struct nlattr *rt = attrs[XFRMA_SEC_CTX]; + struct xfrm_sec_ctx *ctx; +@@ -1897,8 +1899,8 @@ static int xfrm_get_policy(struct sk_buf + if (err) + return err; + } +- xp = xfrm_policy_bysel_ctx(net, mark, if_id, type, p->dir, &p->sel, +- ctx, delete, &err); ++ xp = xfrm_policy_bysel_ctx(net, &m, if_id, type, p->dir, ++ &p->sel, ctx, delete, &err); + security_xfrm_policy_free(ctx); + } + if (xp == NULL) +@@ -2165,7 +2167,6 @@ static int xfrm_add_pol_expire(struct sk + u8 type = XFRM_POLICY_TYPE_MAIN; + int err = -ENOENT; + struct xfrm_mark m; +- u32 mark = xfrm_mark_get(attrs, &m); + u32 if_id = 0; + + err = copy_from_user_policy_type(&type, attrs); +@@ -2179,8 +2180,11 @@ static int xfrm_add_pol_expire(struct sk + if (attrs[XFRMA_IF_ID]) + if_id = nla_get_u32(attrs[XFRMA_IF_ID]); + ++ xfrm_mark_get(attrs, &m); ++ + if (p->index) +- xp = xfrm_policy_byid(net, mark, if_id, type, p->dir, p->index, 0, &err); ++ xp = xfrm_policy_byid(net, &m, if_id, type, p->dir, p->index, ++ 0, &err); + else { + struct nlattr *rt = attrs[XFRMA_SEC_CTX]; + struct xfrm_sec_ctx *ctx; +@@ -2197,7 +2201,7 @@ static int xfrm_add_pol_expire(struct sk + if (err) + return err; + } +- xp = xfrm_policy_bysel_ctx(net, mark, if_id, type, p->dir, ++ xp = xfrm_policy_bysel_ctx(net, &m, if_id, type, p->dir, + &p->sel, ctx, 0, &err); + security_xfrm_policy_free(ctx); + }