]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 20 Feb 2023 11:20:54 +0000 (12:20 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 20 Feb 2023 11:20:54 +0000 (12:20 +0100)
added patches:
alarmtimer-prevent-starvation-by-small-intervals-and-sig_ign.patch
kvm-initialize-all-of-the-kvm_debugregs-structure-before-sending-it-to-userspace.patch

queue-5.10/alarmtimer-prevent-starvation-by-small-intervals-and-sig_ign.patch [new file with mode: 0644]
queue-5.10/kvm-initialize-all-of-the-kvm_debugregs-structure-before-sending-it-to-userspace.patch [new file with mode: 0644]
queue-5.10/series

diff --git a/queue-5.10/alarmtimer-prevent-starvation-by-small-intervals-and-sig_ign.patch b/queue-5.10/alarmtimer-prevent-starvation-by-small-intervals-and-sig_ign.patch
new file mode 100644 (file)
index 0000000..ddfe342
--- /dev/null
@@ -0,0 +1,132 @@
+From d125d1349abeb46945dc5e98f7824bf688266f13 Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Thu, 9 Feb 2023 23:25:49 +0100
+Subject: alarmtimer: Prevent starvation by small intervals and SIG_IGN
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit d125d1349abeb46945dc5e98f7824bf688266f13 upstream.
+
+syzbot reported a RCU stall which is caused by setting up an alarmtimer
+with a very small interval and ignoring the signal. The reproducer arms the
+alarm timer with a relative expiry of 8ns and an interval of 9ns. Not a
+problem per se, but that's an issue when the signal is ignored because then
+the timer is immediately rearmed because there is no way to delay that
+rearming to the signal delivery path.  See posix_timer_fn() and commit
+58229a189942 ("posix-timers: Prevent softirq starvation by small intervals
+and SIG_IGN") for details.
+
+The reproducer does not set SIG_IGN explicitely, but it sets up the timers
+signal with SIGCONT. That has the same effect as explicitely setting
+SIG_IGN for a signal as SIGCONT is ignored if there is no handler set and
+the task is not ptraced.
+
+The log clearly shows that:
+
+   [pid  5102] --- SIGCONT {si_signo=SIGCONT, si_code=SI_TIMER, si_timerid=0, si_overrun=316014, si_int=0, si_ptr=NULL} ---
+
+It works because the tasks are traced and therefore the signal is queued so
+the tracer can see it, which delays the restart of the timer to the signal
+delivery path. But then the tracer is killed:
+
+   [pid  5087] kill(-5102, SIGKILL <unfinished ...>
+   ...
+   ./strace-static-x86_64: Process 5107 detached
+
+and after it's gone the stall can be observed:
+
+   syzkaller login: [   79.439102][    C0] hrtimer: interrupt took 68471 ns
+   [  184.460538][    C1] rcu: INFO: rcu_preempt detected stalls on CPUs/tasks:
+   ...
+   [  184.658237][    C1] rcu: Stack dump where RCU GP kthread last ran:
+   [  184.664574][    C1] Sending NMI from CPU 1 to CPUs 0:
+   [  184.669821][    C0] NMI backtrace for cpu 0
+   [  184.669831][    C0] CPU: 0 PID: 5108 Comm: syz-executor192 Not tainted 6.2.0-rc6-next-20230203-syzkaller #0
+   ...
+   [  184.670036][    C0] Call Trace:
+   [  184.670041][    C0]  <IRQ>
+   [  184.670045][    C0]  alarmtimer_fired+0x327/0x670
+
+posix_timer_fn() prevents that by checking whether the interval for
+timers which have the signal ignored is smaller than a jiffie and
+artifically delay it by shifting the next expiry out by a jiffie. That's
+accurate vs. the overrun accounting, but slightly inaccurate
+vs. timer_gettimer(2).
+
+The comment in that function says what needs to be done and there was a fix
+available for the regular userspace induced SIG_IGN mechanism, but that did
+not work due to the implicit ignore for SIGCONT and similar signals. This
+needs to be worked on, but for now the only available workaround is to do
+exactly what posix_timer_fn() does:
+
+Increase the interval of self-rearming timers, which have their signal
+ignored, to at least a jiffie.
+
+Interestingly this has been fixed before via commit ff86bf0c65f1
+("alarmtimer: Rate limit periodic intervals") already, but that fix got
+lost in a later rework.
+
+Reported-by: syzbot+b9564ba6e8e00694511b@syzkaller.appspotmail.com
+Fixes: f2c45807d399 ("alarmtimer: Switch over to generic set/get/rearm routine")
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: John Stultz <jstultz@google.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/87k00q1no2.ffs@tglx
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/time/alarmtimer.c |   33 +++++++++++++++++++++++++++++----
+ 1 file changed, 29 insertions(+), 4 deletions(-)
+
+--- a/kernel/time/alarmtimer.c
++++ b/kernel/time/alarmtimer.c
+@@ -470,11 +470,35 @@ u64 alarm_forward(struct alarm *alarm, k
+ }
+ EXPORT_SYMBOL_GPL(alarm_forward);
+-u64 alarm_forward_now(struct alarm *alarm, ktime_t interval)
++static u64 __alarm_forward_now(struct alarm *alarm, ktime_t interval, bool throttle)
+ {
+       struct alarm_base *base = &alarm_bases[alarm->type];
++      ktime_t now = base->get_ktime();
++
++      if (IS_ENABLED(CONFIG_HIGH_RES_TIMERS) && throttle) {
++              /*
++               * Same issue as with posix_timer_fn(). Timers which are
++               * periodic but the signal is ignored can starve the system
++               * with a very small interval. The real fix which was
++               * promised in the context of posix_timer_fn() never
++               * materialized, but someone should really work on it.
++               *
++               * To prevent DOS fake @now to be 1 jiffie out which keeps
++               * the overrun accounting correct but creates an
++               * inconsistency vs. timer_gettime(2).
++               */
++              ktime_t kj = NSEC_PER_SEC / HZ;
++
++              if (interval < kj)
++                      now = ktime_add(now, kj);
++      }
++
++      return alarm_forward(alarm, now, interval);
++}
+-      return alarm_forward(alarm, base->get_ktime(), interval);
++u64 alarm_forward_now(struct alarm *alarm, ktime_t interval)
++{
++      return __alarm_forward_now(alarm, interval, false);
+ }
+ EXPORT_SYMBOL_GPL(alarm_forward_now);
+@@ -548,9 +572,10 @@ static enum alarmtimer_restart alarm_han
+       if (posix_timer_event(ptr, si_private) && ptr->it_interval) {
+               /*
+                * Handle ignored signals and rearm the timer. This will go
+-               * away once we handle ignored signals proper.
++               * away once we handle ignored signals proper. Ensure that
++               * small intervals cannot starve the system.
+                */
+-              ptr->it_overrun += alarm_forward_now(alarm, ptr->it_interval);
++              ptr->it_overrun += __alarm_forward_now(alarm, ptr->it_interval, true);
+               ++ptr->it_requeue_pending;
+               ptr->it_active = 1;
+               result = ALARMTIMER_RESTART;
diff --git a/queue-5.10/kvm-initialize-all-of-the-kvm_debugregs-structure-before-sending-it-to-userspace.patch b/queue-5.10/kvm-initialize-all-of-the-kvm_debugregs-structure-before-sending-it-to-userspace.patch
new file mode 100644 (file)
index 0000000..f221c46
--- /dev/null
@@ -0,0 +1,53 @@
+From 2c10b61421a28e95a46ab489fd56c0f442ff6952 Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Tue, 14 Feb 2023 11:33:04 +0100
+Subject: kvm: initialize all of the kvm_debugregs structure before sending it to userspace
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+commit 2c10b61421a28e95a46ab489fd56c0f442ff6952 upstream.
+
+When calling the KVM_GET_DEBUGREGS ioctl, on some configurations, there
+might be some unitialized portions of the kvm_debugregs structure that
+could be copied to userspace.  Prevent this as is done in the other kvm
+ioctls, by setting the whole structure to 0 before copying anything into
+it.
+
+Bonus is that this reduces the lines of code as the explicit flag
+setting and reserved space zeroing out can be removed.
+
+Cc: Sean Christopherson <seanjc@google.com>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Dave Hansen <dave.hansen@linux.intel.com>
+Cc: <x86@kernel.org>
+Cc: "H. Peter Anvin" <hpa@zytor.com>
+Cc: stable <stable@kernel.org>
+Reported-by: Xingyuan Mo <hdthky0@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Message-Id: <20230214103304.3689213-1-gregkh@linuxfoundation.org>
+Tested-by: Xingyuan Mo <hdthky0@gmail.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/x86.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -4455,12 +4455,11 @@ static void kvm_vcpu_ioctl_x86_get_debug
+ {
+       unsigned long val;
++      memset(dbgregs, 0, sizeof(*dbgregs));
+       memcpy(dbgregs->db, vcpu->arch.db, sizeof(vcpu->arch.db));
+       kvm_get_dr(vcpu, 6, &val);
+       dbgregs->dr6 = val;
+       dbgregs->dr7 = vcpu->arch.dr7;
+-      dbgregs->flags = 0;
+-      memset(&dbgregs->reserved, 0, sizeof(dbgregs->reserved));
+ }
+ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
index 18d0478f370b7ae3db3fd7b83f9938d75a4fae6e..36a0e03f00b5036079a4e1337ef5620ce4375ac0 100644 (file)
@@ -50,3 +50,5 @@ flow_offload-fill-flags-to-action-structure.patch
 net-sched-act_ctinfo-use-percpu-stats.patch
 i40e-add-checking-for-null-for-nlmsg_find_attr.patch
 net-sched-tcindex-search-key-must-be-16-bits.patch
+kvm-initialize-all-of-the-kvm_debugregs-structure-before-sending-it-to-userspace.patch
+alarmtimer-prevent-starvation-by-small-intervals-and-sig_ign.patch