Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package xen for openSUSE:Factory checked in 
at 2023-01-27 10:15:16
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/xen (Old)
 and      /work/SRC/openSUSE:Factory/.xen.new.32243 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "xen"

Fri Jan 27 10:15:16 2023 rev:325 rq:1061070 version:4.17.0_04

Changes:
--------
--- /work/SRC/openSUSE:Factory/xen/xen.changes  2023-01-04 18:10:43.000587609 
+0100
+++ /work/SRC/openSUSE:Factory/.xen.new.32243/xen.changes       2023-01-27 
10:23:53.489964341 +0100
@@ -1,0 +2,7 @@
+Wed Jan 25 10:39:54 MST 2023 - carn...@suse.com
+
+- bsc#1207544 - VUL-0: CVE-2022-42330: xen: Guests can cause
+  Xenstore crash via soft reset (XSA-425)
+  xsa425.patch
+
+-------------------------------------------------------------------
@@ -4,0 +12,6 @@
+
+-------------------------------------------------------------------
+Tue Dec 20 13:35:00 CET 2022 - jbeul...@suse.com
+
+- Upstream bug fixes (bsc#1027519)
+  63a03e28-x86-high-freq-TSC-overflow.patch

New:
----
  63a03e28-x86-high-freq-TSC-overflow.patch
  xsa425.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ xen.spec ++++++
--- /var/tmp/diff_new_pack.4Q4ydH/_old  2023-01-27 10:23:55.313974205 +0100
+++ /var/tmp/diff_new_pack.4Q4ydH/_new  2023-01-27 10:23:55.317974227 +0100
@@ -119,7 +119,7 @@
 %endif
 Provides:       installhint(reboot-needed)
 
-Version:        4.17.0_02
+Version:        4.17.0_04
 Release:        0
 Summary:        Xen Virtualization: Hypervisor (aka VMM aka Microkernel)
 License:        GPL-2.0-only
@@ -155,6 +155,8 @@
 # For xen-libs
 Source99:       baselibs.conf
 # Upstream patches
+Patch1:         63a03e28-x86-high-freq-TSC-overflow.patch
+Patch100:       xsa425.patch
 # EMBARGOED security fixes
 # libxc
 Patch301:       libxc-bitmap-long.patch

++++++ 63a03e28-x86-high-freq-TSC-overflow.patch ++++++
# Commit ad15a0a8ca2515d8ac58edfc0bc1d3719219cb77
# Date 2022-12-19 11:34:16 +0100
# Author Neowutran <x...@neowutran.ovh>
# Committer Jan Beulich <jbeul...@suse.com>
x86/time: prevent overflow with high frequency TSCs

Make sure tsc_khz is promoted to a 64-bit type before multiplying by
1000 to avoid an 'overflow before widen' bug. Otherwise just above
4.294GHz the value will overflow. Processors with clocks this high are
now in production and require this to work correctly.

Signed-off-by: Neowutran <x...@neowutran.ovh>
Reviewed-by: Jan Beulich <jbeul...@suse.com>

--- a/xen/arch/x86/time.c
+++ b/xen/arch/x86/time.c
@@ -2585,7 +2585,7 @@ int tsc_set_info(struct domain *d,
     case TSC_MODE_ALWAYS_EMULATE:
         d->arch.vtsc_offset = get_s_time() - elapsed_nsec;
         d->arch.tsc_khz = gtsc_khz ?: cpu_khz;
-        set_time_scale(&d->arch.vtsc_to_ns, d->arch.tsc_khz * 1000);
+        set_time_scale(&d->arch.vtsc_to_ns, d->arch.tsc_khz * 1000UL);
 
         /*
          * In default mode use native TSC if the host has safe TSC and

++++++ xsa425.patch ++++++
From: Jason Andryuk <jandr...@gmail.com>
Subject: Revert "tools/xenstore: simplify loop handling connection I/O"

I'm observing guest kexec trigger xenstored to abort on a double free.

gdb output:
Program received signal SIGABRT, Aborted.
__pthread_kill_implementation (no_tid=0, signo=6, threadid=140645614258112) at 
./nptl/pthread_kill.c:44
44    ./nptl/pthread_kill.c: No such file or directory.
(gdb) bt
    at ./nptl/pthread_kill.c:44
    at ./nptl/pthread_kill.c:78
    at ./nptl/pthread_kill.c:89
    at ../sysdeps/posix/raise.c:26
    at talloc.c:119
    ptr=ptr@entry=0x559fae724290) at talloc.c:232
    at xenstored_core.c:2945
(gdb) frame 5
    at talloc.c:119
119            TALLOC_ABORT("Bad talloc magic value - double free");
(gdb) frame 7
    at xenstored_core.c:2945
2945                talloc_increase_ref_count(conn);
(gdb) p conn
$1 = (struct connection *) 0x559fae724290

Looking at a xenstore trace, we have:
IN 0x559fae71f250 20230120 17:40:53 READ (/local/domain/3/image/device-model-dom
id )
wrl: dom    0      1  msec      10000 credit     1000000 reserve        100 disc
ard
wrl: dom    3      1  msec      10000 credit     1000000 reserve        100 disc
ard
wrl: dom    0      0  msec      10000 credit     1000000 reserve          0 disc
ard
wrl: dom    3      0  msec      10000 credit     1000000 reserve          0 disc
ard
OUT 0x559fae71f250 20230120 17:40:53 ERROR (ENOENT )
wrl: dom    0      1  msec      10000 credit     1000000 reserve        100 disc
ard
wrl: dom    3      1  msec      10000 credit     1000000 reserve        100 disc
ard
IN 0x559fae71f250 20230120 17:40:53 RELEASE (3 )
DESTROY watch 0x559fae73f630
DESTROY watch 0x559fae75ddf0
DESTROY watch 0x559fae75ec30
DESTROY watch 0x559fae75ea60
DESTROY watch 0x559fae732c00
DESTROY watch 0x559fae72cea0
DESTROY watch 0x559fae728fc0
DESTROY watch 0x559fae729570
DESTROY connection 0x559fae724290
orphaned node /local/domain/3/device/suspend/event-channel deleted
orphaned node /local/domain/3/device/vbd/51712 deleted
orphaned node /local/domain/3/device/vkbd/0 deleted
orphaned node /local/domain/3/device/vif/0 deleted
orphaned node /local/domain/3/control/shutdown deleted
orphaned node /local/domain/3/control/feature-poweroff deleted
orphaned node /local/domain/3/control/feature-reboot deleted
orphaned node /local/domain/3/control/feature-suspend deleted
orphaned node /local/domain/3/control/feature-s3 deleted
orphaned node /local/domain/3/control/feature-s4 deleted
orphaned node /local/domain/3/control/sysrq deleted
orphaned node /local/domain/3/data deleted
orphaned node /local/domain/3/drivers deleted
orphaned node /local/domain/3/feature deleted
orphaned node /local/domain/3/attr deleted
orphaned node /local/domain/3/error deleted
orphaned node /local/domain/3/console/backend-id deleted

and no further output.

The trace shows that DESTROY was called for connection 0x559fae724290,
but that is the same pointer (conn) main() was looping through from
connections.  So it wasn't actually removed from the connections list?

Reverting commit e8e6e42279a5 "tools/xenstore: simplify loop handling
connection I/O" fixes the abort/double free.  I think the use of
list_for_each_entry_safe is incorrect.  list_for_each_entry_safe makes
traversal safe for deleting the current iterator, but RELEASE/do_release
will delete some other entry in the connections list.  I think the
observed abort is because list_for_each_entry has next pointing to the
deleted connection, and it is used in the subsequent iteration.

Add a comment explaining the unsuitability of list_for_each_entry_safe.
Also notice that the old code takes a reference on next which would
prevents a use-after-free.

This reverts commit e8e6e42279a5723239c5c40ba4c7f579a979465d.

This is XSA-425/CVE-2022-42330.

Fixes: e8e6e42279a5 ("tools/xenstore: simplify loop handling connection I/O")
Signed-off-by: Jason Andryuk <jandr...@gmail.com>
Reviewed-by: Juergen Gross <jgr...@suse.com>
Reviewed-by: Julien Grall <jgr...@amazon.com>
---
 tools/xenstore/xenstored_core.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -2935,8 +2935,23 @@ int main(int argc, char *argv[])
                        }
                }
 
-               list_for_each_entry_safe(conn, next, &connections, list) {
-                       talloc_increase_ref_count(conn);
+               /*
+                * list_for_each_entry_safe is not suitable here because
+                * handle_input may delete entries besides the current one, but
+                * those may be in the temporary next which would trigger a
+                * use-after-free.  list_for_each_entry_safe is only safe for
+                * deleting the current entry.
+                */
+               next = list_entry(connections.next, typeof(*conn), list);
+               if (&next->list != &connections)
+                       talloc_increase_ref_count(next);
+               while (&next->list != &connections) {
+                       conn = next;
+
+                       next = list_entry(conn->list.next,
+                                         typeof(*conn), list);
+                       if (&next->list != &connections)
+                               talloc_increase_ref_count(next);
 
                        if (conn_can_read(conn))
                                handle_input(conn);

Reply via email to