Xen Security Advisory 420 v2 (CVE-2022-42324) - Oxenstored 32->31 bit integer truncation issues

Xen.org security team posted 1 patch 1 year, 6 months ago
Failed in applying to current master (apply log)
Xen Security Advisory 420 v2 (CVE-2022-42324) - Oxenstored 32->31 bit integer truncation issues
Posted by Xen.org security team 1 year, 6 months ago
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

            Xen Security Advisory CVE-2022-42324 / XSA-420
                               version 2

            Oxenstored 32->31 bit integer truncation issues

UPDATES IN VERSION 2
====================

Public release.

ISSUE DESCRIPTION
=================

Integers in Ocaml are 63 or 31 bits of signed precision.

The Ocaml Xenbus library takes a C uint32_t out of the ring and casts it
directly to an Ocaml integer.  In 64-bit Ocaml builds this is fine, but
in 32-bit builds, it truncates off the most significant bit, and then
creates unsigned/signed confusion in the remainder.

This in turn can feed a negative value into logic not expecting a
negative value, resulting in unexpected exceptions being thrown.

The unexpected exception is not handled suitably, creating a busy-loop
trying (and failing) to take the bad packet out of the xenstore ring.

IMPACT
======

A malicious or buggy guest can write a packet into the xenstore ring
which causes 32-bit builds of oxenstored to busy loop.

VULNERABLE SYSTEMS
==================

All versions of Xen are affected.

Systems running a 32-bit build of oxenstored are affected.

Systems running a 64-bit build of oxenstored, or systems running (C)
xenstored are not affected.

MITIGATION
==========

Running xenstored instead of oxenstored will avoid the vulnerability.

CREDITS
=======

This issue was discovered by Jürgen Groß of SUSE.

RESOLUTION
==========

Applying the appropriate attached patch resolves this issue.

Note that patches for released versions are generally prepared to
apply to the stable branches, and may not apply cleanly to the most
recent release tarball.  Downstreams are encouraged to update to the
tip of the stable branch before applying these patches.

xsa420.patch           xen-unstable - Xen 4.13.x

$ sha256sum xsa420*
565b332d325fd0fdeb5fee890c0cd9b53c4478c46c6b7ec7b24fd3444d2dc812  xsa420.meta
bfa83ca1e78ef81f93c3d94cb1522d1cffed8b9989c5639e8ec663fad0a71027  xsa420.patch
$

DEPLOYMENT DURING EMBARGO
=========================

Deployment of the patches and/or mitigations described above (or
others which are substantially similar) is permitted during the
embargo, even on public-facing systems with untrusted guest users and
administrators.

But: Distribution of updated software is prohibited (except to other
members of the predisclosure list).

Predisclosure list members who wish to deploy significantly different
patches and/or mitigations, please contact the Xen Project Security
Team.


(Note: this during-embargo deployment notice is retained in
post-embargo publicly released Xen Project advisories, even though it
is then no longer applicable.  This is to enable the community to have
oversight of the Xen Project Security Team's decisionmaking.)

For more information about permissible uses of embargoed information,
consult the Xen Project community's agreed Security Policy:
  http://www.xenproject.org/security-policy.html
-----BEGIN PGP SIGNATURE-----

iQFABAEBCAAqFiEEI+MiLBRfRHX6gGCng/4UyVfoK9kFAmNg+68MHHBncEB4ZW4u
b3JnAAoJEIP+FMlX6CvZWJ8H/33T8Ub00BrIWdWSvajjRA4oLamGKRg5uJoI5peJ
cpgKB7iFcoOZcM+G2YfYjm8W2ckoEHXQkJ7fJEbAW0rHc8+WyWl2ulklZSpyi9RX
B6jloIo+5pFoenShirPrJNyfbCmgJduRiUcIzPMRg6vgTmS1RO1W2x3/A6haxez5
LOJCm8dhUBbrp83KH7MgVBlUXIlVQ1irKBmCps11lFG7LaMWjLtScPI4qCpFbMf/
Cmd91Jw6EpzfOWcqohbRabqXXrPZJqSe+EwqrEJsVkkEIK2y2e/kUWcy/9shr9a2
YtudokkROE+bJGbpM9bbucCu/Rnwqj20fDIztR0soCtPbOM=
=QFv9
-----END PGP SIGNATURE-----
{
  "XSA": 420,
  "SupportedVersions": [
    "master",
    "4.16",
    "4.15",
    "4.14",
    "4.13"
  ],
  "Trees": [
    "xen"
  ],
  "Recipes": {
    "4.13": {
      "Recipes": {
        "xen": {
          "StableRef": "0be63c2615b268001f7cc9b72ce25eed952737dc",
          "Prereqs": [
            414,
            415,
            326,
            416,
            417,
            418,
            419
          ],
          "Patches": [
            "xsa420.patch"
          ]
        }
      }
    },
    "4.14": {
      "Recipes": {
        "xen": {
          "StableRef": "016de62747b26ead5a5c763b640fe8e205cd182b",
          "Prereqs": [
            414,
            415,
            326,
            416,
            417,
            418,
            419
          ],
          "Patches": [
            "xsa420.patch"
          ]
        }
      }
    },
    "4.15": {
      "Recipes": {
        "xen": {
          "StableRef": "816580afdd1730d4f85f64477a242a439af1cdf8",
          "Prereqs": [
            414,
            415,
            326,
            416,
            417,
            418,
            419
          ],
          "Patches": [
            "xsa420.patch"
          ]
        }
      }
    },
    "4.16": {
      "Recipes": {
        "xen": {
          "StableRef": "1bce7fb1f702da4f7a749c6f1457ecb20bf74fca",
          "Prereqs": [
            412,
            414,
            415,
            326,
            416,
            417,
            418,
            419
          ],
          "Patches": [
            "xsa420.patch"
          ]
        }
      }
    },
    "master": {
      "Recipes": {
        "xen": {
          "StableRef": "cc4747be8ba157a3b310921e9ee07fb8545aa206",
          "Prereqs": [
            412,
            414,
            415,
            326,
            416,
            417,
            418,
            419
          ],
          "Patches": [
            "xsa420.patch"
          ]
        }
      }
    }
  }
}From 210879456769ca211c6630f47399ca7a61a37f35 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Edwin=20T=C3=B6r=C3=B6k?= <edvin.torok@citrix.com>
Date: Wed, 12 Oct 2022 19:13:05 +0100
Subject: tools/ocaml: Ensure packet size is never negative
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Integers in Ocaml have 63 or 31 bits of signed precision.

On 64-bit builds of Ocaml, this is fine because a C uint32_t always fits
within a 63-bit signed integer.

In 32-bit builds of Ocaml, this goes wrong.  The C uint32_t is truncated
first (loses the top bit), then has a unsigned/signed mismatch.

A "negative" value (i.e. a packet on the ring of between 1G and 2G in size)
will trigger an exception later in Bytes.make in xb.ml, and because the packet
is not removed from the ring, the exception re-triggers on every subsequent
query, creating a livelock.

Fix both the source of the exception in Xb, and as defence in depth, mark the
domain as bad for any Invalid_argument exceptions to avoid the risk of
livelock.

This is XSA-420 / CVE-2022-42324.

Reported-by: Juergen Gross <jgross@suse.com>
Signed-off-by: Edwin Török <edvin.torok@citrix.com>
Acked-by: Christian Lindig <christian.lindig@citrix.com>

diff --git a/tools/ocaml/libs/xb/partial.ml b/tools/ocaml/libs/xb/partial.ml
index b6e2a716e263..3aa8927eb7f0 100644
--- a/tools/ocaml/libs/xb/partial.ml
+++ b/tools/ocaml/libs/xb/partial.ml
@@ -36,7 +36,7 @@ let of_string s =
 	   This will leave the guest connection is a bad state and will
 	   be hard to recover from without restarting the connection
 	   (ie rebooting the guest) *)
-	let dlen = min xenstore_payload_max dlen in
+	let dlen = max 0 (min xenstore_payload_max dlen) in
 	{
 		tid = tid;
 		rid = rid;
@@ -46,8 +46,8 @@ let of_string s =
 	}
 
 let append pkt s sz =
-	if pkt.len > 4096 then failwith "Buffer.add: cannot grow buffer";
-	Buffer.add_string pkt.buf (String.sub s 0 sz)
+	if Buffer.length pkt.buf + sz > xenstore_payload_max then failwith "Buffer.add: cannot grow buffer";
+	Buffer.add_substring pkt.buf s 0 sz
 
 let to_complete pkt =
 	pkt.len - (Buffer.length pkt.buf)
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index 5f439fe59f47..f3a71b24ad94 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -722,7 +722,7 @@ let do_input store cons doms con =
 			History.reconnect con;
 			info "%s reconnection complete" (Connection.get_domstr con);
 			None
-		| Failure exp ->
+		| Invalid_argument exp | Failure exp ->
 			error "caught exception %s" exp;
 			error "got a bad client %s" (sprintf "%-8s" (Connection.get_domstr con));
 			Connection.mark_as_bad con;