Unverified Commit 086e523c authored by Emily's avatar Emily Committed by GitHub
Browse files

xen: delete patching infrastructure, 4.19.0 -> 4.19.0-unstable-2024-11-12 (#355535)

parents 56fea726 e4ab3bf4
Loading
Loading
Loading
Loading
+9 −115
Original line number Diff line number Diff line
@@ -7,7 +7,6 @@
  testers,
  which,
  fetchgit,
  fetchpatch,

  # Xen
  acpica-tools,
@@ -65,7 +64,6 @@
  withSeaBIOS ? true,
  withOVMF ? true,
  withIPXE ? true,
  useDefaultPatchList ? true,
  rev,
  hash,
  patches ? [ ],
@@ -73,117 +71,26 @@
}:

let
  # Inherit helper functions from lib and builtins.
  inherit (builtins) elemAt isAttrs;
  inherit (lib.meta) getExe';
  inherit (lib.lists) optional optionals;
  inherit (lib.systems.inspect.patterns) isLinux isAarch64;
  inherit (lib) teams;
  inherit (lib.strings)
    concatLines
    enableFeature
    makeSearchPathOutput
    optionalString
    removeSuffix
    versionOlder
    ;
  inherit (lib.platforms) linux aarch64;
  inherit (lib) teams;
  inherit (lib.licenses)
    cc-by-40
    gpl2Only
    lgpl21Only
    mit
    ;
  inherit (lib.meta) getExe';
  inherit (lib.lists)
    count
    flatten
    optional
    optionals
    range
    remove
    zipListsWith
    ;
  inherit (lib.attrsets) attrByPath;

  # Mark versions older than minSupportedVersion as EOL.
  minSupportedVersion = "4.16";

  ## Generic Patch Handling ##

  upstreamPatches = import ./patches.nix {
    inherit lib fetchpatch;
  };

  upstreamPatchList = flatten (
    with upstreamPatches;
    [
      QUBES_REPRODUCIBLE_BUILDS
      XSA_460
      XSA_461
      XSA_462
      XSA_464
    ]
  );

  ## XSA Patches Description Builder ##

  # Simple counter for the number of attrsets (patches) in the patches list after normalisation.
  numberOfPatches = count (patch: isAttrs patch) upstreamPatchList;

  # builtins.elemAt's index begins at 0, so we subtract 1 from the number of patches in order to
  # produce the range that will be used in the following builtin.map calls.
  availablePatchesToTry = range 0 (numberOfPatches - 1);

  # Takes in an attrByPath input, and outputs the attribute value for each patch in a list.
  # If a patch does not have a given attribute, returns `null`. Use lib.lists.remove null
  # to remove these junk values, if necessary.
  retrievePatchAttributes =
    attributeName:
    map (x: attrByPath attributeName null (elemAt upstreamPatchList x)) availablePatchesToTry;

  # Produces a list of newline-separated strings that lists the vulnerabilities this
  # Xen is NOT affected by, due to the applied Xen Security Advisory patches. This is
  # then used in meta.longDescription, to let users know their Xen is patched against
  # known vulnerabilities, as the package version isn't always the best indicator.
  #
  # Produces something like this: (one string for each XSA)
  #  * [Xen Security Advisory #1](https://xenbits.xenproject.org/xsa/advisory-1.html): **Title for XSA.**
  #  >Description of issue in XSA
  #Extra lines
  #are not indented,
  #but markdown should be
  #fine with it.
  #  Fixes:
  #  * [CVE-1999-00001](https://www.cve.org/CVERecord?id=CVE-1999-00001)
  #  * [CVE-1999-00002](https://www.cve.org/CVERecord?id=CVE-1999-00002)
  #  * [CVE-1999-00003](https://www.cve.org/CVERecord?id=CVE-1999-00003)
  writeAdvisoryDescription =
    if (remove null (retrievePatchAttributes [ "xsa" ]) != [ ]) then
      zipListsWith (a: b: a + b)
        (zipListsWith (a: b: a + "**" + b + ".**\n  >")
          (zipListsWith (a: b: "* [Xen Security Advisory #" + a + "](" + b + "): ")
            (remove null (retrievePatchAttributes [ "xsa" ]))
            (
              remove null (retrievePatchAttributes [
                "meta"
                "homepage"
              ])
            )
          )
          (
            remove null (retrievePatchAttributes [
              "meta"
              "description"
            ])
          )
        )
        (
          remove null (retrievePatchAttributes [
            "meta"
            "longDescription"
          ])
        )
    else
      [ ];

  #TODO: fix paths instead.
  scriptEnvPath = makeSearchPathOutput "out" "bin" [
    bridge-utils
@@ -205,10 +112,8 @@ let
in

stdenv.mkDerivation (finalAttrs: {
  inherit pname version;
  inherit pname version patches;

  # TODO: Split $out in $bin for binaries and $lib for libraries.
  # TODO: Python package to be in separate output/package.
  outputs = [
    "out"
    "man"
@@ -217,14 +122,11 @@ stdenv.mkDerivation (finalAttrs: {
    "boot"
  ];

  # Main Xen source.
  src = fetchgit {
    url = "https://xenbits.xenproject.org/git-http/xen.git";
    inherit rev hash;
  };

  patches = optionals useDefaultPatchList upstreamPatchList ++ patches;

  nativeBuildInputs = [
    autoPatchelfHook
    bison
@@ -265,7 +167,7 @@ stdenv.mkDerivation (finalAttrs: {
    "--with-system-qemu"
    (if withSeaBIOS then "--with-system-seabios=${systemSeaBIOS.firmware}" else "--disable-seabios")
    (if withOVMF then "--with-system-ovmf=${OVMF.firmware}" else "--disable-ovmf")
    (if withIPXE then "--with-system-ipxe=${ipxe}" else "--disable-ipxe")
    (if withIPXE then "--with-system-ipxe=${ipxe.firmware}" else "--disable-ipxe")
    (enableFeature withFlask "xsmpolicy")
  ];

@@ -436,14 +338,7 @@ stdenv.mkDerivation (finalAttrs: {
      + optionalString withFlask "\n* `xsm-flask`: The [FLASK Xen Security Module](https://wiki.xenproject.org/wiki/Xen_Security_Modules_:_XSM-FLASK). The `xenpolicy-${version}` file is available on the `boot` output of this package."
      + optionalString withSeaBIOS "\n* `seabios`: Support for the SeaBIOS boot firmware on HVM domains."
      + optionalString withOVMF "\n* `ovmf`: Support for the OVMF UEFI boot firmware on HVM domains."
      + optionalString withIPXE "\n* `ipxe`: Support for the iPXE boot firmware on HVM domains."
      # Finally, we write a notice explaining which vulnerabilities this Xen is NOT vulnerable to.
      # This will hopefully give users the peace of mind that their Xen is secure, without needing
      # to search the source code for the XSA patches.
      + optionalString (writeAdvisoryDescription != [ ]) (
        "\n\nThis Xen Project Hypervisor (${version}) has been patched against the following known security vulnerabilities:\n"
        + removeSuffix "\n" (concatLines writeAdvisoryDescription)
      );
      + optionalString withIPXE "\n* `ipxe`: Support for the iPXE boot firmware on HVM domains.";

    homepage = "https://xenproject.org/";
    downloadPage = "https://downloads.xenproject.org/release/xen/${version}/";
@@ -465,8 +360,7 @@ stdenv.mkDerivation (finalAttrs: {

    mainProgram = "xl";

    #TODO: Migrate meta.platforms to the new lib.systems.inspect.patterns.* format.
    platforms = linux;
    badPlatforms = aarch64;
    platforms = [ isLinux ];
    badPlatforms = [ isAarch64 ];
  } // meta;
})
+0 −169
Original line number Diff line number Diff line
# Patching Xen? Check the XSAs at https://xenbits.xen.org/xsa/
# and try applying all the ones we haven't gotten around to
# yet, if any are necessary. Patches from other downstreams
# are also welcome if they fix important issues with vanilla Xen.

{ lib, fetchpatch }:

let
  inherit (builtins) concatStringsSep;
  inherit (lib.strings) optionalString concatMapStrings;

  xsaPatch =
    {
      id,
      title,
      description,
      type ? "xsa",
      hash ? "",
      cve ? null,
    }:
    (fetchpatch {
      name = "XSA-" + id + optionalString (cve != null) ("-" + concatStringsSep "+" cve);
      url = "https://xenbits.xen.org/xsa/xsa${id}.patch";
      inherit hash;
      passthru = {
        xsa = id;
        inherit type;
      };
      meta = {
        description = title;
        longDescription =
          description
          + "\n"
          + (
            if (cve == null) then
              # Why the two spaces preceding these CVE messages?
              # This is parsed by writeAdvisoryDescription in generic.nix,
              # and doing this was easier than messing with lib.strings even more.
              "  _No CVE was assigned to this XSA._"
            else
              "  Fixes:${
                  concatMapStrings (x: "\n  * [" + x + "](https://www.cve.org/CVERecord?id=" + x + ")") cve
                }"
          );
        homepage = "https://xenbits.xenproject.org/xsa/advisory-${id}.html";
      };
    });
  qubesPatch =
    {
      name,
      tag,
      type ? "qubes",
      hash ? "",
    }:
    (fetchpatch {
      inherit name;
      url = "https://raw.githubusercontent.com/QubesOS/qubes-vmm-xen/v${tag}/${name}.patch";
      inherit hash;
      passthru.type = type;
    });
in
{
  # Example patches:
  #
  # "XSA_100" = xsaPatch {
  #   id = "100";
  #   title = "Verbatim Title of XSA";
  #   description = ''
  #     Verbatim description of XSA.
  #   '';
  #   cve = [ "CVE-1999-0001" "CVE-1999-0002" ]; # Not all XSAs have CVEs. This attribute is optional.
  #   hash = "sha256-0000000000000000000000000000000000000000000000000000";
  # };
  #
  # "QUBES_libxl-fix-all-issues" = qubesPatch {
  #   name = "1000-libxl-fix-all-issues";
  #   tag = "4.20.0-1";
  #   hash = "sha256-0000000000000000000000000000000000000000000000000000";
  # };

  # Build reproducibility patches for Xen.
  # Qubes OS has not updated them to later versions of Xen yet,
  # but they appear to work on Xen 4.17.4 - 4.19.0.
  QUBES_REPRODUCIBLE_BUILDS = [
    (qubesPatch {
      name = "1100-Define-build-dates-time-based-on-SOURCE_DATE_EPOCH";
      tag = "4.17.4-5";
      hash = "sha256-OwKA9oPTwhRcSmiOb+PxzifbO/IG8IHWlvddFh/nP6s=";
    })
    (qubesPatch {
      name = "1101-docs-rename-DATE-to-PANDOC_REL_DATE-and-allow-to-spe";
      tag = "4.17.4-5";
      hash = "sha256-BUtYt0mM3bURVaGv4oDznzxx1Wo4sfOpGV5GB8qc5Ns=";
    })
    (qubesPatch {
      name = "1102-docs-xen-headers-use-alphabetical-sorting-for-incont";
      tag = "4.17.4-5";
      hash = "sha256-mQUp2w9lUb7KDq5MuPQjs6y7iuMDeXoZjDjlXfa5z44=";
    })
  ];

  # Xen Security Advisory #460: (4.16.6 - 4.19.0)
  "XSA_460" = xsaPatch {
    id = "460";
    title = "Error handling in x86 IOMMU identity mapping";
    description = ''
      Certain PCI devices in a system might be assigned Reserved Memory
      Regions (specified via Reserved Memory Region Reporting, "RMRR") for
      Intel VT-d or Unity Mapping ranges for AMD-Vi.  These are typically used
      for platform tasks such as legacy USB emulation.
      Since the precise purpose of these regions is unknown, once a device
      associated with such a region is active, the mappings of these regions
      need to remain continuouly accessible by the device.  In the logic
      establishing these mappings, error handling was flawed, resulting in
      such mappings to potentially remain in place when they should have been
      removed again.  Respective guests would then gain access to memory
      regions which they aren't supposed to have access to.
    '';
    cve = [ "CVE-2024-31145" ];
    hash = "sha256-3q4nAP2xGEptX6BIpSlALOt2r0kjj1up5pF3xCFp+l0=";
  };
  # Xen Security Advisory #461: (4.16.6 - 4.19.0)
  "XSA_461" = xsaPatch {
    id = "461";
    title = "PCI device pass-through with shared resources";
    description = ''
      When multiple devices share resources and one of them is to be passed
      through to a guest, security of the entire system and of respective
      guests individually cannot really be guaranteed without knowing
      internals of any of the involved guests.  Therefore such a configuration
      cannot really be security-supported, yet making that explicit was so far
      missing.
    '';
    cve = [ "CVE-2024-31146" ];
    hash = "sha256-JQWoqf47hy9WXNkVC/LgmjUhkxN0SBF6w8PF4aFZxhM=";
  };
  # Xen Security Advisory #462: (4.16.6 - 4.19.0)
  "XSA_462" = xsaPatch {
    id = "462";
    title = "x86: Deadlock in vlapic_error()";
    description = ''
      In x86's APIC (Advanced Programmable Interrupt Controller) architecture,
      error conditions are reported in a status register.  Furthermore, the OS
      can opt to receive an interrupt when a new error occurs.
      It is possible to configure the error interrupt with an illegal vector,
      which generates an error when an error interrupt is raised.
      This case causes Xen to recurse through vlapic_error().  The recursion
      itself is bounded; errors accumulate in the the status register and only
      generate an interrupt when a new status bit becomes set.
      However, the lock protecting this state in Xen will try to be taken
      recursively, and deadlock.
    '';
    cve = [ "CVE-2024-45817" ];
    hash = "sha256-01lzjaT2f69UfEdTUCkm92DDOmd+Mo8sNPZsHJfgJEM=";
  };
  "XSA_464" = xsaPatch {
    id = "464";
    title = "libxl leaks data to PVH guests via ACPI tables";
    description = ''
      PVH guests have their ACPI tables constructed by the toolstack.  The
      construction involves building the tables in local memory, which are
      then copied into guest memory.  While actually used parts of the local
      memory are filled in correctly, excess space that is being allocated is
      left with its prior contents.
    '';
    cve = [ "CVE-2024-45819" ];
    hash = "sha256-oQa4NuX4Y1hhfnqHV6kvsJZiQ/NAz/WwO0Kidbcyayc=";
  };
}
+6 −2
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
  embedScript ? null,
  additionalTargets ? { },
  additionalOptions ? [ ],
  firmwareBinary ? "ipxe.efirom",
}:

let
@@ -130,9 +131,12 @@ stdenv.mkDerivation (finalAttrs: {

  enableParallelBuilding = true;

  passthru.updateScript = unstableGitUpdater {
  passthru = {
    firmware = "${finalAttrs.finalPackage}/${firmwareBinary}";
    updateScript = unstableGitUpdater {
      tagPrefix = "v";
    };
  };

  meta = {
    description = "Network boot firmware";
+3 −3
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@

buildXenPackage.override { inherit python3Packages; } {
  pname = "xen";
  version = "4.19.0";
  rev = "026c9fa29716b0ff0f8b7c687908e71ba29cf239";
  hash = "sha256-Q6x+2fZ4ITBz6sKICI0NHGx773Rc919cl+wzI89UY+Q=";
  version = "4.19.0-unstable-2024-11-12";
  rev = "251a9496485a86f302980a3f8d3c656831b5a62f";
  hash = "sha256-kHuB6kagH3AU+Wsx4oD7HnNsZpxCu7x3v/m4/1xi6lY=";
}