From d899fb6f8a4b6370576e3a009e959bc98ee03c16 Mon Sep 17 00:00:00 2001 From: Ryan Sullivan Date: Mon, 16 Oct 2023 14:08:36 -0400 Subject: [KPATCH CVE-2023-3611] kpatch fixes for CVE-2023-3611 Kernels: 3.10.0-1160.90.1.el7 3.10.0-1160.92.1.el7 3.10.0-1160.95.1.el7 3.10.0-1160.99.1.el7 3.10.0-1160.102.1.el7 Kpatch-MR: https://gitlab.com/redhat/prdsc/rhel/src/kpatch/rhel-7/-/merge_requests/60 Approved-by: Joe Lawrence (@joe.lawrence) Approved-by: Yannick Cote (@ycote1) Changes since last build: arches: x86_64 ppc64le cls_fw.o: changed function: fw_change cls_fw.o: changed function: fw_set_parms cls_route.o: changed function: route4_change cls_u32.o: changed function: u32_change sch_qfq.o: changed function: qfq_enqueue --------------------------- Modifications: none commit 726e9f3d88c729cdae09768c94e588deebdb9d52 Author: Marcelo Tosatti Date: Mon Jan 23 17:17:17 2023 -0300 KVM: x86: rename argument to kvm_set_tsc_khz commit 4941b8cb3746f09bb102f7a5d64d878e96a0c6cd Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2152838 JIRA: https://issues.redhat.com/browse/RHELPLAN-141963 Testing: Tested by QE This refers to the desired (scaled) frequency, which is called user_tsc_khz in the rest of the file. Reviewed-by: Marcelo Tosatti Signed-off-by: Paolo Bonzini Signed-off-by: Marcelo Tosatti commit 866faa0e99083ee93d04d3c37065cf8dbfc51a34 Author: Marcelo Tosatti Date: Mon Jan 23 17:24:19 2023 -0300 KVM: x86: rewrite handling of scaled TSC for kvmclock commit 78db6a5037965429c04d708281f35a6e5562d31b Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2152838 Testing: Tested by QE JIRA: https://issues.redhat.com/browse/RHELPLAN-141963 This is the same as before: kvm_scale_tsc(tgt_tsc_khz) = tgt_tsc_khz * ratio = tgt_tsc_khz * user_tsc_khz / tsc_khz (see set_tsc_khz) = user_tsc_khz (see kvm_guest_time_update) = vcpu->arch.virtual_tsc_khz (see kvm_set_tsc_khz) However, computing it through kvm_scale_tsc will make it possible to include the NTP correction in tgt_tsc_khz. Reviewed-by: Marcelo Tosatti Signed-off-by: Paolo Bonzini Signed-off-by: Marcelo Tosatti commit bde6eebb5708ecd38db0023e657d38058e0d962f Author: Marcelo Tosatti Date: Wed Jan 25 16:07:18 2023 -0300 KVM: x86: add bit to indicate correct tsc_shift Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2152838 Testing: Tested by QE Upstream Status: RHEL7 only JIRA: https://issues.redhat.com/browse/RHELPLAN-141963 This changeset is unique to RHEL-7 since it was decided it is not necessary upstream: "I don't think it's justifiable to further complicate the userspace API for a bug that's been fixed six years ago. I'd be very surprised if any combination of modern upstream {QEMU,kernel} is going to do a successful migration from such an old {QEMU,kernel}. RHEL/CentOS are able to do so because *specific pairs* have been tested, but as far as upstream is concerned this adds complexity that absolutely no one will use." Before commit 78db6a5037965429c04d708281f35a6e5562d31b, kvm_guest_time_update() would use vcpu->virtual_tsc_khz to calculate tsc_shift value in the vcpus pvclock structure written to guest memory. For those kernels, if vcpu->virtual_tsc_khz != tsc_khz (which can be the case when guest state is restored via migration, or if tsc-khz option is passed to QEMU), and TSC scaling is not enabled (which happens if the difference between the frequency requested via KVM_SET_TSC_KHZ and the host TSC KHZ is smaller than 250ppm), then there can be a difference between what KVM_GET_CLOCK would return and what the guest reads as kvmclock value. When KVM_SET_CLOCK'ing what is read with KVM_GET_CLOCK, the guest can observe a forward or backwards time jump. Advertise to userspace that current kernel contains this fix, so QEMU can workaround the problem by reading pvclock via guest memory directly otherwise. Signed-off-by: Marcelo Tosatti commit 9dbd3713d82f45c9781f2dc6dd49dc3ee07ba980 Author: Davide Caratti Date: Tue Aug 8 12:55:43 2023 +0200 net/sched: sch_qfq: account for stab overhead in qfq_enqueue Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2225555 CVE: CVE-2023-3611 Upstream Status: net.git commit 3e337087c3b5 Conflicts: - we don't have QFQ_MAX_LMAX defined in rhel-7 because of missing upstream commit 25369891fcef ("net/sched: sch_qfq: refactor parsing of netlink parameters"): use its value in the test inside qfq_change_agg() commit 3e337087c3b5805fe0b8a46ba622a962880b5d64 Author: Pedro Tammela Date: Tue Jul 11 18:01:02 2023 -0300 net/sched: sch_qfq: account for stab overhead in qfq_enqueue Lion says: ------- In the QFQ scheduler a similar issue to CVE-2023-31436 persists. Consider the following code in net/sched/sch_qfq.c: static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free) { unsigned int len = qdisc_pkt_len(skb), gso_segs; // ... if (unlikely(cl->agg->lmax < len)) { pr_debug("qfq: increasing maxpkt from %u to %u for class %u", cl->agg->lmax, len, cl->common.classid); err = qfq_change_agg(sch, cl, cl->agg->class_weight, len); if (err) { cl->qstats.drops++; return qdisc_drop(skb, sch, to_free); } // ... } Similarly to CVE-2023-31436, "lmax" is increased without any bounds checks according to the packet length "len". Usually this would not impose a problem because packet sizes are naturally limited. This is however not the actual packet length, rather the "qdisc_pkt_len(skb)" which might apply size transformations according to "struct qdisc_size_table" as created by "qdisc_get_stab()" in net/sched/sch_api.c if the TCA_STAB option was set when modifying the qdisc. A user may choose virtually any size using such a table. As a result the same issue as in CVE-2023-31436 can occur, allowing heap out-of-bounds read / writes in the kmalloc-8192 cache. ------- We can create the issue with the following commands: tc qdisc add dev $DEV root handle 1: stab mtu 2048 tsize 512 mpu 0 \ overhead 999999999 linklayer ethernet qfq tc class add dev $DEV parent 1: classid 1:1 htb rate 6mbit burst 15k tc filter add dev $DEV parent 1: matchall classid 1:1 ping -I $DEV 1.1.1.2 This is caused by incorrectly assuming that qdisc_pkt_len() returns a length within the QFQ_MIN_LMAX < len < QFQ_MAX_LMAX. Fixes: 462dbc9101ac ("pkt_sched: QFQ Plus: fair-queueing service at DRR cost") Reported-by: Lion Reviewed-by: Eric Dumazet Signed-off-by: Jamal Hadi Salim Signed-off-by: Pedro Tammela Reviewed-by: Simon Horman Signed-off-by: Paolo Abeni Signed-off-by: Davide Caratti Signed-off-by: Ryan Sullivan --- net/sched/sch_qfq.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c index a36b3ec3271a..ca8c79456c80 100644 --- a/net/sched/sch_qfq.c +++ b/net/sched/sch_qfq.c @@ -387,8 +387,13 @@ static int qfq_change_agg(struct Qdisc *sch, struct qfq_class *cl, u32 weight, u32 lmax) { struct qfq_sched *q = qdisc_priv(sch); - struct qfq_aggregate *new_agg = qfq_find_agg(q, lmax, weight); + struct qfq_aggregate *new_agg; + /* 'lmax' can range from [QFQ_MIN_LMAX, pktlen + stab overhead] */ + if (lmax > (1UL << QFQ_MTU_SHIFT)) + return -EINVAL; + + new_agg = qfq_find_agg(q, lmax, weight); if (new_agg == NULL) { /* create new aggregate */ new_agg = kzalloc(sizeof(*new_agg), GFP_ATOMIC); if (new_agg == NULL) -- 2.41.0