diff --git a/SOURCES/CVE-2021-0920.patch b/SOURCES/CVE-2021-0920.patch new file mode 100644 index 0000000..43430e5 --- /dev/null +++ b/SOURCES/CVE-2021-0920.patch @@ -0,0 +1,160 @@ +From 18c390171a63c1be8df1a62172214efbd9e84813 Mon Sep 17 00:00:00 2001 +From: Joe Lawrence +Date: Thu, 20 Jan 2022 14:39:19 -0500 +Subject: [KPATCH CVE-2021-0920] af_unix: kpatch fixes for CVE-2021-0920 + +Kernels: +4.18.0-348.el8 +4.18.0-348.2.1.el8_5 +4.18.0-348.7.1.el8_5 +4.18.0-348.12.2.el8_5 + +Changes since last build: +arches: x86_64 ppc64le +af_unix.o: changed function: unix_dgram_recvmsg +af_unix.o: changed function: unix_stream_read_generic +--------------------------- + +Kpatch-MR: https://gitlab.com/redhat/prdsc/rhel/src/kpatch/rhel-8/-/merge_requests/17 +Approved-by: Yannick Cote (@ycote1) +Approved-by: Artem Savkov (@artem.savkov) +Kernels: +4.18.0-348.el8 +4.18.0-348.2.1.el8_5 +4.18.0-348.7.1.el8_5 +4.18.0-348.12.2.el8_5 + +Modifications: none + +commit 49c79494c048e940be91a9454c2f507bc33680fc +Author: Patrick Talbert +Date: Mon Jan 10 13:13:05 2022 +0100 + + af_unix: fix garbage collect vs MSG_PEEK + + Bugzilla: https://bugzilla.redhat.com/2031974 + CVE: CVE-2021-0920 + Y-Commit: 35c0f6eeb4644e87e7f3c1198a9f31b76220053d + + O-CVE: CVE-2021-0920 + O-Bugzilla: https://bugzilla.redhat.com/2031975 + Upstream status: main + Testing: Sanity only + + commit cbcf01128d0a92e131bd09f1688fe032480b65ca + Author: Miklos Szeredi + Date: Wed Jul 28 14:47:20 2021 +0200 + + af_unix: fix garbage collect vs MSG_PEEK + + unix_gc() assumes that candidate sockets can never gain an external + reference (i.e. be installed into an fd) while the unix_gc_lock is + held. Except for MSG_PEEK this is guaranteed by modifying inflight + count under the unix_gc_lock. + + MSG_PEEK does not touch any variable protected by unix_gc_lock (file + count is not), yet it needs to be serialized with garbage collection. + Do this by locking/unlocking unix_gc_lock: + + 1) increment file count + + 2) lock/unlock barrier to make sure incremented file count is visible + to garbage collection + + 3) install file into fd + + This is a lock barrier (unlike smp_mb()) that ensures that garbage + collection is run completely before or completely after the barrier. + + Cc: + Signed-off-by: Greg Kroah-Hartman + Signed-off-by: Miklos Szeredi + Signed-off-by: Linus Torvalds + + Signed-off-by: Patrick Talbert + +Signed-off-by: Joe Lawrence +--- + net/unix/af_unix.c | 51 ++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 49 insertions(+), 2 deletions(-) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 247e3138d1ef..d9c968caaf20 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -1498,6 +1498,53 @@ static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int peer) + return err; + } + ++static void unix_peek_fds(struct scm_cookie *scm, struct sk_buff *skb) ++{ ++ scm->fp = scm_fp_dup(UNIXCB(skb).fp); ++ ++ /* ++ * Garbage collection of unix sockets starts by selecting a set of ++ * candidate sockets which have reference only from being in flight ++ * (total_refs == inflight_refs). This condition is checked once during ++ * the candidate collection phase, and candidates are marked as such, so ++ * that non-candidates can later be ignored. While inflight_refs is ++ * protected by unix_gc_lock, total_refs (file count) is not, hence this ++ * is an instantaneous decision. ++ * ++ * Once a candidate, however, the socket must not be reinstalled into a ++ * file descriptor while the garbage collection is in progress. ++ * ++ * If the above conditions are met, then the directed graph of ++ * candidates (*) does not change while unix_gc_lock is held. ++ * ++ * Any operations that changes the file count through file descriptors ++ * (dup, close, sendmsg) does not change the graph since candidates are ++ * not installed in fds. ++ * ++ * Dequeing a candidate via recvmsg would install it into an fd, but ++ * that takes unix_gc_lock to decrement the inflight count, so it's ++ * serialized with garbage collection. ++ * ++ * MSG_PEEK is special in that it does not change the inflight count, ++ * yet does install the socket into an fd. The following lock/unlock ++ * pair is to ensure serialization with garbage collection. It must be ++ * done between incrementing the file count and installing the file into ++ * an fd. ++ * ++ * If garbage collection starts after the barrier provided by the ++ * lock/unlock, then it will see the elevated refcount and not mark this ++ * as a candidate. If a garbage collection is already in progress ++ * before the file count was incremented, then the lock/unlock pair will ++ * ensure that garbage collection is finished before progressing to ++ * installing the fd. ++ * ++ * (*) A -> B where B is on the queue of A or B is on the queue of C ++ * which is on the queue of listening socket A. ++ */ ++ spin_lock(&unix_gc_lock); ++ spin_unlock(&unix_gc_lock); ++} ++ + static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds) + { + int err = 0; +@@ -2124,7 +2171,7 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, + sk_peek_offset_fwd(sk, size); + + if (UNIXCB(skb).fp) +- scm.fp = scm_fp_dup(UNIXCB(skb).fp); ++ unix_peek_fds(&scm, skb); + } + err = (flags & MSG_TRUNC) ? skb->len - skip : size; + +@@ -2365,7 +2412,7 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state, + /* It is questionable, see note in unix_dgram_recvmsg. + */ + if (UNIXCB(skb).fp) +- scm.fp = scm_fp_dup(UNIXCB(skb).fp); ++ unix_peek_fds(&scm, skb); + + sk_peek_offset_fwd(sk, chunk); + +-- +2.34.1 + + diff --git a/SOURCES/CVE-2021-4154.patch b/SOURCES/CVE-2021-4154.patch new file mode 100644 index 0000000..40d5f3b --- /dev/null +++ b/SOURCES/CVE-2021-4154.patch @@ -0,0 +1,110 @@ +From 7d389a33490309d15530e3372c3045110b3031ab Mon Sep 17 00:00:00 2001 +From: Artem Savkov +Date: Tue, 4 Jan 2022 10:40:56 +0100 +Subject: [KPATCH CVE-2021-4154] cgroup: verify that source is a string + +Kernels: +4.18.0-348.el8 +4.18.0-348.2.1.el8_5 +4.18.0-348.7.1.el8_5 + +Changes since last build: +arches: x86_64 ppc64le +cgroup-v1.o: changed function: cgroup1_parse_param +--------------------------- + +Kpatch-MR: https://gitlab.com/redhat/prdsc/rhel/src/kpatch/rhel-8/-/merge_requests/9 +Approved-by: Yannick Cote (@ycote1) +Approved-by: Joe Lawrence (@joe.lawrence) +Kernels: +4.18.0-348.el8 +4.18.0-348.2.1.el8_5 +4.18.0-348.7.1.el8_5 +4.18.0-348.12.2.el8_5 + +Modifications: none +Z-MR: https://gitlab.com/redhat/rhel/src/kernel/rhel-8/-/merge_requests/1865 +CVE: CVE-2021-4154 + +commit e1ee4bc6e6d8fd36b493fca941b7d5b6e987ae3c +Author: Waiman Long +Date: Tue Dec 21 09:47:25 2021 -0500 + + cgroup: verify that source is a string + + Bugzilla: https://bugzilla.redhat.com/2034608 + Y-Commit: b6d2fff23b0eee0e82d128f23c4ebd99a30299c3 + + O-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2034609 + + commit 3b0462726e7ef281c35a7a4ae33e93ee2bc9975b + Author: Christian Brauner + Date: Wed, 14 Jul 2021 15:47:49 +0200 + + cgroup: verify that source is a string + + The following sequence can be used to trigger a UAF: + + int fscontext_fd = fsopen("cgroup"); + int fd_null = open("/dev/null, O_RDONLY); + int fsconfig(fscontext_fd, FSCONFIG_SET_FD, "source", fd_null); + close_range(3, ~0U, 0); + + The cgroup v1 specific fs parser expects a string for the "source" + parameter. However, it is perfectly legitimate to e.g. specify a file + descriptor for the "source" parameter. The fs parser doesn't know what + a filesystem allows there. So it's a bug to assume that "source" is + always of type fs_value_is_string when it can reasonably also be + fs_value_is_file. + + This assumption in the cgroup code causes a UAF because struct + fs_parameter uses a union for the actual value. Access to that union is + guarded by the param->type member. Since the cgroup paramter parser + didn't check param->type but unconditionally moved param->string into + fc->source a close on the fscontext_fd would trigger a UAF during + put_fs_context() which frees fc->source thereby freeing the file stashed + in param->file causing a UAF during a close of the fd_null. + + Fix this by verifying that param->type is actually a string and report + an error if not. + + In follow up patches I'll add a new generic helper that can be used here + and by other filesystems instead of this error-prone copy-pasta fix. + But fixing it in here first makes backporting a it to stable a lot + easier. + + Fixes: 8d2451f4994f ("cgroup1: switch to option-by-option parsing") + Reported-by: syzbot+283ce5a46486d6acdbaf@syzkaller.appspotmail.com + Cc: Christoph Hellwig + Cc: Alexander Viro + Cc: Dmitry Vyukov + Cc: + Cc: syzkaller-bugs + Signed-off-by: Christian Brauner + Signed-off-by: Linus Torvalds + + Signed-off-by: Waiman Long + Signed-off-by: Bruno Meneguele + +Signed-off-by: Artem Savkov +--- + kernel/cgroup/cgroup-v1.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c +index 852f1349f9d9..291754068ec6 100644 +--- a/kernel/cgroup/cgroup-v1.c ++++ b/kernel/cgroup/cgroup-v1.c +@@ -907,6 +907,8 @@ int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param) + opt = fs_parse(fc, cgroup1_fs_parameters, param, &result); + if (opt == -ENOPARAM) { + if (strcmp(param->key, "source") == 0) { ++ if (param->type != fs_value_is_string) ++ return invalf(fc, "Non-string source"); + if (fc->source) + return invalf(fc, "Multiple sources not supported"); + fc->source = param->string; +-- +2.34.1 + + diff --git a/SOURCES/CVE-2022-0330.patch b/SOURCES/CVE-2022-0330.patch new file mode 100644 index 0000000..74715f0 --- /dev/null +++ b/SOURCES/CVE-2022-0330.patch @@ -0,0 +1,373 @@ +From e314ba42cb4dccd4d9edb2ffcb2295b4c4e2d00d Mon Sep 17 00:00:00 2001 +From: Yannick Cote +Date: Tue, 1 Mar 2022 19:54:52 -0500 +Subject: [KPATCH CVE-2022-0330] drm/i915: kpatch fixes for CVE-2022-0330 + +Kernels: +4.18.0-348.el8 +4.18.0-348.2.1.el8_5 +4.18.0-348.7.1.el8_5 +4.18.0-348.12.2.el8_5 + +Changes since last build: +arches: x86_64 +i915_drv.o: changed function: i915_driver_release +i915_vma.o: changed function: i915_vma_bind +intel_gt.o: new function: intel_gt_invalidate_tlbs +intel_gt.o: new function: tlb_invalidate_lock_ctor +intel_uncore.o: changed function: __intel_uncore_forcewake_put +intel_uncore.o: changed function: __intel_wait_for_register +intel_uncore.o: changed function: i915_pmic_bus_access_notifier +intel_uncore.o: changed function: intel_uncore_forcewake_put +intel_uncore.o: changed function: intel_uncore_forcewake_put__locked +intel_uncore.o: changed function: intel_uncore_forcewake_user_put +intel_uncore.o: new function: intel_uncore_forcewake_put_delayed +--------------------------- + +Kpatch-MR: https://gitlab.com/redhat/prdsc/rhel/src/kpatch/rhel-8/-/merge_requests/33 +Approved-by: Joe Lawrence (@joe.lawrence) +Kernels: +4.18.0-348.el8 +4.18.0-348.2.1.el8_5 +4.18.0-348.7.1.el8_5 +4.18.0-348.12.2.el8_5 + +Modifications: +- Move new bit definition to .c files avoiding changes to .h files. +- Redefine tlb_invalidate_lock as a klp shadow variable and avoid +changes to global structure definition (struct intel_gt). + +commit 01dfa79afb751b4fec242c7d05ee2e0f78fe9a78 +Author: Patrick Talbert +Date: Mon Jan 31 10:33:24 2022 +0100 + + drm/i915: Flush TLBs before releasing backing store + + Bugzilla: https://bugzilla.redhat.com/2044328 + CVE: CVE-2022-0330 + Y-Commit: 5dfb7de610e0b38a03d4d71bdc6cb23a8af0161d + + commit 7938d61591d33394a21bdd7797a245b65428f44c + Author: Tvrtko Ursulin + Date: Tue Oct 19 13:27:10 2021 +0100 + + drm/i915: Flush TLBs before releasing backing store + + We need to flush TLBs before releasing backing store otherwise userspace + is able to encounter stale entries if a) it is not declaring GPU access to + certain buffers and b) this GPU execution then races with the backing + store release getting triggered asynchronously. + + Approach taken is to mark any buffer objects which were ever bound to the + GPU and triggering a serialized TLB flush when their backing store is + released. + + Alternatively the flushing could be done on VMA unbind, at which point we + would be able to ascertain whether there is potential parallel GPU + execution (which could race), but choice essentially boils down to paying + the cost of TLB flushes maybe needlessly at VMA unbind time (when the + backing store is not known to be definitely going away, so flushing not + always required for safety), versus potentially needlessly at backing + store relase time since at that point cannot tell whether there is a + parallel GPU execution happening. + + Therefore simplicity of implementation has been chosen for now, with scope + to benchmark and refine later as required. + + Signed-off-by: Tvrtko Ursulin + Reported-by: Sushma Venkatesh Reddy + Cc: Daniel Vetter + Cc: Jon Bloomfield + Cc: Joonas Lahtinen + Cc: Jani Nikula + Cc: stable@vger.kernel.org + + Signed-off-by: Patrick Talbert + +Signed-off-by: Yannick Cote +--- + drivers/gpu/drm/i915/gem/i915_gem_pages.c | 13 +++ + drivers/gpu/drm/i915/gt/intel_gt.c | 130 ++++++++++++++++++++++ + drivers/gpu/drm/i915/i915_drv.c | 5 + + drivers/gpu/drm/i915/i915_vma.c | 6 + + drivers/gpu/drm/i915/intel_uncore.c | 26 ++++- + 5 files changed, 176 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c +index 76574e245916..ba7fce675ee7 100644 +--- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c ++++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c +@@ -173,6 +173,11 @@ static void unmap_object(struct drm_i915_gem_object *obj, void *ptr) + vunmap(ptr); + } + ++/* CVE-2022-0330 - kpatch gathered definitions */ ++#define I915_BO_WAS_BOUND_BIT 4 ++ ++void intel_gt_invalidate_tlbs(struct intel_gt *gt); ++ + struct sg_table * + __i915_gem_object_unset_pages(struct drm_i915_gem_object *obj) + { +@@ -195,6 +200,14 @@ __i915_gem_object_unset_pages(struct drm_i915_gem_object *obj) + __i915_gem_object_reset_page_iter(obj); + obj->mm.page_sizes.phys = obj->mm.page_sizes.sg = 0; + ++ if (test_and_clear_bit(I915_BO_WAS_BOUND_BIT, &obj->flags)) { ++ struct drm_i915_private *i915 = to_i915(obj->base.dev); ++ intel_wakeref_t wakeref; ++ ++ with_intel_runtime_pm_if_active(&i915->runtime_pm, wakeref) ++ intel_gt_invalidate_tlbs(&i915->gt); ++ } ++ + return pages; + } + +diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c +index d8e1ab412634..da0b144ea418 100644 +--- a/drivers/gpu/drm/i915/gt/intel_gt.c ++++ b/drivers/gpu/drm/i915/gt/intel_gt.c +@@ -662,3 +662,133 @@ void intel_gt_info_print(const struct intel_gt_info *info, + + intel_sseu_dump(&info->sseu, p); + } ++ ++struct reg_and_bit { ++ i915_reg_t reg; ++ u32 bit; ++}; ++ ++static struct reg_and_bit ++get_reg_and_bit(const struct intel_engine_cs *engine, const bool gen8, ++ const i915_reg_t *regs, const unsigned int num) ++{ ++ const unsigned int class = engine->class; ++ struct reg_and_bit rb = { }; ++ ++ if (drm_WARN_ON_ONCE(&engine->i915->drm, ++ class >= num || !regs[class].reg)) ++ return rb; ++ ++ rb.reg = regs[class]; ++ if (gen8 && class == VIDEO_DECODE_CLASS) ++ rb.reg.reg += 4 * engine->instance; /* GEN8_M2TCR */ ++ else ++ rb.bit = engine->instance; ++ ++ rb.bit = BIT(rb.bit); ++ ++ return rb; ++} ++ ++/* CVE-2022-0330 - kpatch gathered definitions */ ++#include ++#define KLP_CVE_2022_0330_MUTEX 0x2022033000000001 ++#define GEN8_RTCR _MMIO(0x4260) ++#define GEN8_M1TCR _MMIO(0x4264) ++#define GEN8_M2TCR _MMIO(0x4268) ++#define GEN8_BTCR _MMIO(0x426c) ++#define GEN8_VTCR _MMIO(0x4270) ++#define GEN12_GFX_TLB_INV_CR _MMIO(0xced8) ++#define GEN12_VD_TLB_INV_CR _MMIO(0xcedc) ++#define GEN12_VE_TLB_INV_CR _MMIO(0xcee0) ++#define GEN12_BLT_TLB_INV_CR _MMIO(0xcee4) ++ ++void intel_uncore_forcewake_put_delayed(struct intel_uncore *uncore, ++ enum forcewake_domains domains); ++ ++static int tlb_invalidate_lock_ctor(void *obj, void *shadow_data, void *ctor_data) ++{ ++ struct mutex *m = shadow_data; ++ mutex_init(m); ++ ++ return 0; ++} ++ ++void intel_gt_invalidate_tlbs(struct intel_gt *gt) ++{ ++ static const i915_reg_t gen8_regs[] = { ++ [RENDER_CLASS] = GEN8_RTCR, ++ [VIDEO_DECODE_CLASS] = GEN8_M1TCR, /* , GEN8_M2TCR */ ++ [VIDEO_ENHANCEMENT_CLASS] = GEN8_VTCR, ++ [COPY_ENGINE_CLASS] = GEN8_BTCR, ++ }; ++ static const i915_reg_t gen12_regs[] = { ++ [RENDER_CLASS] = GEN12_GFX_TLB_INV_CR, ++ [VIDEO_DECODE_CLASS] = GEN12_VD_TLB_INV_CR, ++ [VIDEO_ENHANCEMENT_CLASS] = GEN12_VE_TLB_INV_CR, ++ [COPY_ENGINE_CLASS] = GEN12_BLT_TLB_INV_CR, ++ }; ++ struct drm_i915_private *i915 = gt->i915; ++ struct intel_uncore *uncore = gt->uncore; ++ struct intel_engine_cs *engine; ++ enum intel_engine_id id; ++ const i915_reg_t *regs; ++ unsigned int num = 0; ++ struct mutex *tlb_invalidate_lock; ++ ++ if (I915_SELFTEST_ONLY(gt->awake == -ENODEV)) ++ return; ++ ++ if (INTEL_GEN(i915) == 12) { ++ regs = gen12_regs; ++ num = ARRAY_SIZE(gen12_regs); ++ } else if (INTEL_GEN(i915) >= 8 && INTEL_GEN(i915) <= 11) { ++ regs = gen8_regs; ++ num = ARRAY_SIZE(gen8_regs); ++ } else if (INTEL_GEN(i915) < 8) { ++ return; ++ } ++ ++ if (drm_WARN_ONCE(&i915->drm, !num, ++ "Platform does not implement TLB invalidation!")) ++ return; ++ ++ GEM_TRACE("\n"); ++ ++ assert_rpm_wakelock_held(&i915->runtime_pm); ++ ++ tlb_invalidate_lock = klp_shadow_get_or_alloc(i915, KLP_CVE_2022_0330_MUTEX, ++ sizeof(*tlb_invalidate_lock), GFP_KERNEL, ++ tlb_invalidate_lock_ctor, NULL); ++ if (tlb_invalidate_lock) { ++ mutex_lock(tlb_invalidate_lock); ++ intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL); ++ ++ for_each_engine(engine, gt, id) { ++ /* ++ * HW architecture suggest typical invalidation time at 40us, ++ * with pessimistic cases up to 100us and a recommendation to ++ * cap at 1ms. We go a bit higher just in case. ++ */ ++ const unsigned int timeout_us = 100; ++ const unsigned int timeout_ms = 4; ++ struct reg_and_bit rb; ++ ++ rb = get_reg_and_bit(engine, regs == gen8_regs, regs, num); ++ if (!i915_mmio_reg_offset(rb.reg)) ++ continue; ++ ++ intel_uncore_write_fw(uncore, rb.reg, rb.bit); ++ if (__intel_wait_for_register_fw(uncore, ++ rb.reg, rb.bit, 0, ++ timeout_us, timeout_ms, ++ NULL)) ++ drm_err_ratelimited(>->i915->drm, ++ "%s TLB invalidation did not complete in %ums!\n", ++ engine->name, timeout_ms); ++ } ++ ++ intel_uncore_forcewake_put_delayed(uncore, FORCEWAKE_ALL); ++ mutex_unlock(tlb_invalidate_lock); ++ } ++} +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index 92668bcbece0..31b298618e7a 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -957,6 +957,10 @@ void i915_driver_remove(struct drm_i915_private *i915) + enable_rpm_wakeref_asserts(&i915->runtime_pm); + } + ++/* CVE-2022-0330 - kpatch gathered definitions */ ++#include ++#define KLP_CVE_2022_0330_MUTEX 0x2022033000000001 ++ + static void i915_driver_release(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = to_i915(dev); +@@ -979,6 +983,7 @@ static void i915_driver_release(struct drm_device *dev) + intel_runtime_pm_driver_release(rpm); + + i915_driver_late_release(dev_priv); ++ klp_shadow_free(dev_priv, KLP_CVE_2022_0330_MUTEX, NULL); + } + + static int i915_driver_open(struct drm_device *dev, struct drm_file *file) +diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c +index caa9b041616b..8b2f1c8b2170 100644 +--- a/drivers/gpu/drm/i915/i915_vma.c ++++ b/drivers/gpu/drm/i915/i915_vma.c +@@ -362,6 +362,9 @@ int i915_vma_wait_for_bind(struct i915_vma *vma) + return err; + } + ++/* CVE-2022-0330 - kpatch gathered definitions */ ++#define I915_BO_WAS_BOUND_BIT 4 ++ + /** + * i915_vma_bind - Sets up PTEs for an VMA in it's corresponding address space. + * @vma: VMA to map +@@ -439,6 +442,9 @@ int i915_vma_bind(struct i915_vma *vma, + vma->ops->bind_vma(vma->vm, NULL, vma, cache_level, bind_flags); + } + ++ if (vma->obj) ++ set_bit(I915_BO_WAS_BOUND_BIT, &vma->obj->flags); ++ + atomic_or(bind_flags, &vma->flags); + return 0; + } +diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c +index 9ac501bcfdad..9eb5d9e8e5a8 100644 +--- a/drivers/gpu/drm/i915/intel_uncore.c ++++ b/drivers/gpu/drm/i915/intel_uncore.c +@@ -694,7 +694,8 @@ void intel_uncore_forcewake_get__locked(struct intel_uncore *uncore, + } + + static void __intel_uncore_forcewake_put(struct intel_uncore *uncore, +- enum forcewake_domains fw_domains) ++ enum forcewake_domains fw_domains, ++ bool delayed) + { + struct intel_uncore_forcewake_domain *domain; + unsigned int tmp; +@@ -709,7 +710,11 @@ static void __intel_uncore_forcewake_put(struct intel_uncore *uncore, + continue; + } + +- uncore->funcs.force_wake_put(uncore, domain->mask); ++ if (delayed && ++ !(domain->uncore->fw_domains_timer & domain->mask)) ++ fw_domain_arm_timer(domain); ++ else ++ uncore->funcs.force_wake_put(uncore, domain->mask); + } + } + +@@ -730,7 +735,20 @@ void intel_uncore_forcewake_put(struct intel_uncore *uncore, + return; + + spin_lock_irqsave(&uncore->lock, irqflags); +- __intel_uncore_forcewake_put(uncore, fw_domains); ++ __intel_uncore_forcewake_put(uncore, fw_domains, false); ++ spin_unlock_irqrestore(&uncore->lock, irqflags); ++} ++ ++void intel_uncore_forcewake_put_delayed(struct intel_uncore *uncore, ++ enum forcewake_domains fw_domains) ++{ ++ unsigned long irqflags; ++ ++ if (!uncore->funcs.force_wake_put) ++ return; ++ ++ spin_lock_irqsave(&uncore->lock, irqflags); ++ __intel_uncore_forcewake_put(uncore, fw_domains, true); + spin_unlock_irqrestore(&uncore->lock, irqflags); + } + +@@ -772,7 +790,7 @@ void intel_uncore_forcewake_put__locked(struct intel_uncore *uncore, + if (!uncore->funcs.force_wake_put) + return; + +- __intel_uncore_forcewake_put(uncore, fw_domains); ++ __intel_uncore_forcewake_put(uncore, fw_domains, false); + } + + void assert_forcewakes_inactive(struct intel_uncore *uncore) +-- +2.34.1 + + diff --git a/SOURCES/CVE-2022-0435.patch b/SOURCES/CVE-2022-0435.patch new file mode 100644 index 0000000..86eee1a --- /dev/null +++ b/SOURCES/CVE-2022-0435.patch @@ -0,0 +1,139 @@ +From 8db2609e76912d088d19ba0938e80c5628e58e9e Mon Sep 17 00:00:00 2001 +From: Joe Lawrence +Date: Thu, 3 Mar 2022 11:44:42 -0500 +Subject: [KPATCH CVE-2022-0435] tipc: kpatch fixes for CVE-2022-0435 + +Kernels: +4.18.0-348.el8 +4.18.0-348.2.1.el8_5 +4.18.0-348.7.1.el8_5 +4.18.0-348.12.2.el8_5 + +Changes since last build: +[x86_64]: +link.o: changed function: tipc_link_rcv +monitor.o: changed function: tipc_mon_rcv + +[ppc64le]: +link.o: changed function: tipc_link_proto_rcv +monitor.o: changed function: tipc_mon_rcv + +--------------------------- + +Kpatch-MR: https://gitlab.com/redhat/prdsc/rhel/src/kpatch/rhel-8/-/merge_requests/36 +Approved-by: Yannick Cote (@ycote1) +Kernels: +4.18.0-348.el8 +4.18.0-348.2.1.el8_5 +4.18.0-348.7.1.el8_5 +4.18.0-348.12.2.el8_5 + +Modifications: none + +commit 8b2b73e6cb7bd6d9d5af8d21f15d002a373d0a2e +Author: Xin Long +Date: Thu Feb 10 21:43:20 2022 -0500 + + tipc: improve size validations for received domain records + + Bugzilla: https://bugzilla.redhat.com/2048970 + CVE: CVE-2022-0435 + Y-Commit: 0e080c279fd19325b263617515835d6ce45e88f4 + + O-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2048971 + O-CVE: CVE-2022-0435 + Tested: compile only + + commit 9aa422ad326634b76309e8ff342c246800621216 + Author: Jon Maloy + Date: Sat Feb 5 14:11:18 2022 -0500 + + tipc: improve size validations for received domain records + + The function tipc_mon_rcv() allows a node to receive and process + domain_record structs from peer nodes to track their views of the + network topology. + + This patch verifies that the number of members in a received domain + record does not exceed the limit defined by MAX_MON_DOMAIN, something + that may otherwise lead to a stack overflow. + + tipc_mon_rcv() is called from the function tipc_link_proto_rcv(), where + we are reading a 32 bit message data length field into a uint16. To + avert any risk of bit overflow, we add an extra sanity check for this in + that function. We cannot see that happen with the current code, but + future designers being unaware of this risk, may introduce it by + allowing delivery of very large (> 64k) sk buffers from the bearer + layer. This potential problem was identified by Eric Dumazet. + + This fixes CVE-2022-0435 + + Reported-by: Samuel Page + Reported-by: Eric Dumazet + Fixes: 35c55c9877f8 ("tipc: add neighbor monitoring framework") + Signed-off-by: Jon Maloy + Reviewed-by: Xin Long + Reviewed-by: Samuel Page + Reviewed-by: Eric Dumazet + Signed-off-by: Linus Torvalds + + Signed-off-by: Xin Long + Signed-off-by: Bruno Meneguele + +Signed-off-by: Joe Lawrence +--- + net/tipc/link.c | 9 +++++++-- + net/tipc/monitor.c | 2 ++ + 2 files changed, 9 insertions(+), 2 deletions(-) + +diff --git a/net/tipc/link.c b/net/tipc/link.c +index b5ed87dded2c..062ec1989c41 100644 +--- a/net/tipc/link.c ++++ b/net/tipc/link.c +@@ -2165,7 +2165,7 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb, + struct tipc_msg *hdr = buf_msg(skb); + struct tipc_gap_ack_blks *ga = NULL; + bool reply = msg_probe(hdr), retransmitted = false; +- u16 dlen = msg_data_sz(hdr), glen = 0; ++ u32 dlen = msg_data_sz(hdr), glen = 0; + u16 peers_snd_nxt = msg_next_sent(hdr); + u16 peers_tol = msg_link_tolerance(hdr); + u16 peers_prio = msg_linkprio(hdr); +@@ -2179,6 +2179,10 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb, + void *data; + + trace_tipc_proto_rcv(skb, false, l->name); ++ ++ if (dlen > U16_MAX) ++ goto exit; ++ + if (tipc_link_is_blocked(l) || !xmitq) + goto exit; + +@@ -2275,7 +2279,8 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb, + + /* Receive Gap ACK blocks from peer if any */ + glen = tipc_get_gap_ack_blks(&ga, l, hdr, true); +- ++ if(glen > dlen) ++ break; + tipc_mon_rcv(l->net, data + glen, dlen - glen, l->addr, + &l->mon_state, l->bearer_id); + +diff --git a/net/tipc/monitor.c b/net/tipc/monitor.c +index 6dce2abf436e..a37190da5a50 100644 +--- a/net/tipc/monitor.c ++++ b/net/tipc/monitor.c +@@ -465,6 +465,8 @@ void tipc_mon_rcv(struct net *net, void *data, u16 dlen, u32 addr, + state->probing = false; + + /* Sanity check received domain record */ ++ if (new_member_cnt > MAX_MON_DOMAIN) ++ return; + if (dlen < dom_rec_len(arrv_dom, 0)) + return; + if (dlen != dom_rec_len(arrv_dom, new_member_cnt)) +-- +2.34.1 + + diff --git a/SOURCES/CVE-2022-0492.patch b/SOURCES/CVE-2022-0492.patch new file mode 100644 index 0000000..3663e3c --- /dev/null +++ b/SOURCES/CVE-2022-0492.patch @@ -0,0 +1,101 @@ +From 6e23854a2c0c6acedb76eaeb306090aaacf58245 Mon Sep 17 00:00:00 2001 +From: Joe Lawrence +Date: Thu, 24 Feb 2022 13:03:17 -0500 +Subject: [KPATCH CVE-2022-0492] cgroup-v1: kpatch fixes for CVE-2022-0492 + +Kernels: +4.18.0-348.el8 +4.18.0-348.2.1.el8_5 +4.18.0-348.7.1.el8_5 +4.18.0-348.12.2.el8_5 + +Changes since last build: +arches: x86_64 ppc64le +cgroup-v1.o: changed function: cgroup1_parse_param +cgroup-v1.o: changed function: cgroup_release_agent_write +--------------------------- + +Kpatch-MR: https://gitlab.com/redhat/prdsc/rhel/src/kpatch/rhel-8/-/merge_requests/26 +Approved-by: Yannick Cote (@ycote1) +Kernels: +4.18.0-348.el8 +4.18.0-348.2.1.el8_5 +4.18.0-348.7.1.el8_5 +4.18.0-348.12.2.el8_5 + +Modifications: none + +commit 07650ec60ef7ae3d33cde8faed38770c838ff4b1 +Author: Waiman Long +Date: Tue Feb 8 19:21:47 2022 -0500 + + cgroup-v1: Require capabilities to set release_agent + + Bugzilla: https://bugzilla.redhat.com/2052166 + CVE: CVE-2022-0492 + Y-Commit: 55f79b1a4b02276a6edda7cb7ef5ec0c585141a1 + + O-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2052167 + O-CVE: CVE-2022-0492 + + commit 24f6008564183aa120d07c03d9289519c2fe02af + Author: Eric W. Biederman + Date: Thu, 20 Jan 2022 11:04:01 -0600 + + cgroup-v1: Require capabilities to set release_agent + + The cgroup release_agent is called with call_usermodehelper. The function + call_usermodehelper starts the release_agent with a full set fo capabilities. + Therefore require capabilities when setting the release_agaent. + + Reported-by: Tabitha Sable + Tested-by: Tabitha Sable + Fixes: 81a6a5cdd2c5 ("Task Control Groups: automatic userspace notification of idle cgroups") + Cc: stable@vger.kernel.org # v2.6.24+ + Signed-off-by: "Eric W. Biederman" + Signed-off-by: Tejun Heo + + Signed-off-by: Waiman Long + Signed-off-by: Bruno Meneguele + +Signed-off-by: Joe Lawrence +--- + kernel/cgroup/cgroup-v1.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c +index 852f1349f9d9..fdf337ccda6b 100644 +--- a/kernel/cgroup/cgroup-v1.c ++++ b/kernel/cgroup/cgroup-v1.c +@@ -544,6 +544,14 @@ static ssize_t cgroup_release_agent_write(struct kernfs_open_file *of, + + BUILD_BUG_ON(sizeof(cgrp->root->release_agent_path) < PATH_MAX); + ++ /* ++ * Release agent gets called with all capabilities, ++ * require capabilities to set release agent. ++ */ ++ if ((of->file->f_cred->user_ns != &init_user_ns) || ++ !capable(CAP_SYS_ADMIN)) ++ return -EPERM; ++ + cgrp = cgroup_kn_lock_live(of->kn, false); + if (!cgrp) + return -ENODEV; +@@ -951,6 +959,12 @@ int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param) + /* Specifying two release agents is forbidden */ + if (ctx->release_agent) + return invalfc(fc, "release_agent respecified"); ++ /* ++ * Release agent gets called with all capabilities, ++ * require capabilities to set release agent. ++ */ ++ if ((fc->user_ns != &init_user_ns) || !capable(CAP_SYS_ADMIN)) ++ return invalfc(fc, "Setting release_agent not allowed"); + ctx->release_agent = param->string; + param->string = NULL; + break; +-- +2.34.1 + + diff --git a/SOURCES/CVE-2022-22942.patch b/SOURCES/CVE-2022-22942.patch new file mode 100644 index 0000000..c49fa52 --- /dev/null +++ b/SOURCES/CVE-2022-22942.patch @@ -0,0 +1,211 @@ +From 73c1db23af5c7364af380d21739a6e1220a2490d Mon Sep 17 00:00:00 2001 +From: Joe Lawrence +Date: Tue, 1 Mar 2022 15:34:07 -0500 +Subject: [KPATCH CVE-2022-22942] drm/vmwgfx: kpatch fixes for CVE-2022-22942 + +Kernels: +4.18.0-348.el8 +4.18.0-348.2.1.el8_5 +4.18.0-348.7.1.el8_5 +4.18.0-348.12.2.el8_5 + +Changes since last build: +arches: x86_64 +vmwgfx_execbuf.o: changed function: vmw_execbuf_copy_fence_user +vmwgfx_execbuf.o: changed function: vmw_execbuf_process +vmwgfx_fence.o: changed function: vmw_fence_event_ioctl +vmwgfx_kms.o: changed function: vmw_kms_helper_validation_finish +--------------------------- + +Kpatch-MR: https://gitlab.com/redhat/prdsc/rhel/src/kpatch/rhel-8/-/merge_requests/32 +Approved-by: Yannick Cote (@ycote1) +Kernels: +4.18.0-348.el8 +4.18.0-348.2.1.el8_5 +4.18.0-348.7.1.el8_5 +4.18.0-348.12.2.el8_5 + +Modifications: none + +commit 1b221c65601c93cb4ad2b24487c0015d6bae7c7f +Author: Dave Airlie +Date: Fri Jan 28 16:36:48 2022 -0500 + + drm/vmwgfx: Fix stale file descriptors on failed usercopy + + Bugzilla: https://bugzilla.redhat.com/2047601 + CVE: CVE-2022-22942 + Y-Commit: b6793b842fba127aa491384431e84b79c7619afd + + O-Bugzilla: http://bugzilla.redhat.com/2047602 + O-CVE: CVE-2022-22942 + + commit a0f90c8815706981c483a652a6aefca51a5e191c + Author: Mathias Krause + Date: Thu Jan 27 18:34:19 2022 +1000 + + drm/vmwgfx: Fix stale file descriptors on failed usercopy + + A failing usercopy of the fence_rep object will lead to a stale entry in + the file descriptor table as put_unused_fd() won't release it. This + enables userland to refer to a dangling 'file' object through that still + valid file descriptor, leading to all kinds of use-after-free + exploitation scenarios. + + Fix this by deferring the call to fd_install() until after the usercopy + has succeeded. + + Fixes: c906965dee22 ("drm/vmwgfx: Add export fence to file descriptor support") + Signed-off-by: Mathias Krause + Signed-off-by: Zack Rusin + Signed-off-by: Dave Airlie + Signed-off-by: Linus Torvalds + + Signed-off-by: Dave Airlie + Signed-off-by: Bruno Meneguele + +Signed-off-by: Joe Lawrence +--- + drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 5 ++-- + drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 33 +++++++++++++------------ + drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 2 +- + drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 2 +- + 4 files changed, 21 insertions(+), 21 deletions(-) + +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +index eb76a6b9ebca..2f4f39446240 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +@@ -1069,15 +1069,14 @@ extern int vmw_execbuf_fence_commands(struct drm_file *file_priv, + struct vmw_private *dev_priv, + struct vmw_fence_obj **p_fence, + uint32_t *p_handle); +-extern void vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv, ++extern int vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv, + struct vmw_fpriv *vmw_fp, + int ret, + struct drm_vmw_fence_rep __user + *user_fence_rep, + struct vmw_fence_obj *fence, + uint32_t fence_handle, +- int32_t out_fence_fd, +- struct sync_file *sync_file); ++ int32_t out_fence_fd); + bool vmw_cmd_describe(const void *buf, u32 *size, char const **cmd); + + /** +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +index 462f17320708..399cb4cce292 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +@@ -3804,17 +3804,17 @@ int vmw_execbuf_fence_commands(struct drm_file *file_priv, + * Also if copying fails, user-space will be unable to signal the fence object + * so we wait for it immediately, and then unreference the user-space reference. + */ +-void ++int + vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv, + struct vmw_fpriv *vmw_fp, int ret, + struct drm_vmw_fence_rep __user *user_fence_rep, + struct vmw_fence_obj *fence, uint32_t fence_handle, +- int32_t out_fence_fd, struct sync_file *sync_file) ++ int32_t out_fence_fd) + { + struct drm_vmw_fence_rep fence_rep; + + if (user_fence_rep == NULL) +- return; ++ return 0; + + memset(&fence_rep, 0, sizeof(fence_rep)); + +@@ -3842,20 +3842,14 @@ vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv, + * handle. + */ + if (unlikely(ret != 0) && (fence_rep.error == 0)) { +- if (sync_file) +- fput(sync_file->file); +- +- if (fence_rep.fd != -1) { +- put_unused_fd(fence_rep.fd); +- fence_rep.fd = -1; +- } +- + ttm_ref_object_base_unref(vmw_fp->tfile, fence_handle, + TTM_REF_USAGE); + VMW_DEBUG_USER("Fence copy error. Syncing.\n"); + (void) vmw_fence_obj_wait(fence, false, false, + VMW_FENCE_WAIT_TIMEOUT); + } ++ ++ return ret ? -EFAULT : 0; + } + + /** +@@ -4193,16 +4187,23 @@ int vmw_execbuf_process(struct drm_file *file_priv, + + (void) vmw_fence_obj_wait(fence, false, false, + VMW_FENCE_WAIT_TIMEOUT); ++ } ++ } ++ ++ ret = vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret, ++ user_fence_rep, fence, handle, out_fence_fd); ++ ++ if (sync_file) { ++ if (ret) { ++ /* usercopy of fence failed, put the file object */ ++ fput(sync_file->file); ++ put_unused_fd(out_fence_fd); + } else { + /* Link the fence with the FD created earlier */ + fd_install(out_fence_fd, sync_file->file); + } + } + +- vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret, +- user_fence_rep, fence, handle, out_fence_fd, +- sync_file); +- + /* Don't unreference when handing fence out */ + if (unlikely(out_fence != NULL)) { + *out_fence = fence; +@@ -4220,7 +4221,7 @@ int vmw_execbuf_process(struct drm_file *file_priv, + */ + vmw_validation_unref_lists(&val_ctx); + +- return 0; ++ return ret; + + out_unlock_binding: + mutex_unlock(&dev_priv->binding_mutex); +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +index 378ec7600154..23cf8a264f3d 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +@@ -1167,7 +1167,7 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data, + } + + vmw_execbuf_copy_fence_user(dev_priv, vmw_fp, 0, user_fence_rep, fence, +- handle, -1, NULL); ++ handle, -1); + vmw_fence_obj_unreference(&fence); + return 0; + out_no_create: +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +index 9a89f658e501..bb0448044ced 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +@@ -2477,7 +2477,7 @@ void vmw_kms_helper_validation_finish(struct vmw_private *dev_priv, + if (file_priv) + vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), + ret, user_fence_rep, fence, +- handle, -1, NULL); ++ handle, -1); + if (out_fence) + *out_fence = fence; + else +-- +2.34.1 + + diff --git a/SPECS/kpatch-patch.spec b/SPECS/kpatch-patch.spec index 2c11a52..93c3cc4 100644 --- a/SPECS/kpatch-patch.spec +++ b/SPECS/kpatch-patch.spec @@ -6,7 +6,7 @@ %define kernel_ver 4.18.0-348.7.1.el8_5 %define kpatch_ver 0.9.5 %define rpm_ver 1 -%define rpm_rel 1 +%define rpm_rel 2 %if !%{empty_package} # Patch sources below. DO NOT REMOVE THIS LINE. @@ -16,6 +16,24 @@ Source100: CVE-2021-4155.patch # # https://bugzilla.redhat.com/2040593 Source101: CVE-2022-0185.patch +# +# https://bugzilla.redhat.com/2031991 +Source102: CVE-2021-0920.patch +# +# https://bugzilla.redhat.com/2034618 +Source103: CVE-2021-4154.patch +# +# https://bugzilla.redhat.com/2044377 +Source104: CVE-2022-0330.patch +# +# https://bugzilla.redhat.com/2050135 +Source105: CVE-2022-0435.patch +# +# https://bugzilla.redhat.com/2052187 +Source106: CVE-2022-0492.patch +# +# https://bugzilla.redhat.com/2047620 +Source107: CVE-2022-22942.patch # End of patch sources. DO NOT REMOVE THIS LINE. %endif @@ -154,6 +172,14 @@ It is only a method to subscribe to the kpatch stream for kernel-%{kernel_ver}. %endif %changelog +* Fri Mar 04 2022 Yannick Cote [1-2.el8_5] +- kernel: failing usercopy allows for use-after-free exploitation [2047620] {CVE-2022-22942} +- kernel: cgroups v1 release_agent feature may allow privilege escalation [2052187] {CVE-2022-0492} +- kernel: remote stack overflow via kernel panic on systems using TIPC may lead to DoS [2050135] {CVE-2022-0435} +- kernel: possible privileges escalation due to missing TLB flush [2044377] {CVE-2022-0330} +- kernel: local privilege escalation by exploiting the fsconfig syscall parameter leads to container breakout [2034618] {CVE-2021-4154} +- kernel: Use After Free in unix_gc() which could result in a local privilege escalation [2031991] {CVE-2021-0920} + * Tue Jan 18 2022 Joe Lawrence [1-1.el8_5] - kernel: fs_context: heap overflow in legacy parameter handling [2040593] {CVE-2022-0185} - kernel: xfs: raw block device data leak in XFS_IOC_ALLOCSP IOCTL [2034875] {CVE-2021-4155}