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