Unverified Commit 0f3ce175 authored by Emily's avatar Emily Committed by GitHub
Browse files

xen: cleanup, code quality improvements (#342915)

parents 2cfbcf00 5c62c3d2
Loading
Loading
Loading
Loading
+107 −93
Original line number Diff line number Diff line
@@ -98,11 +98,13 @@ let
  ];

  # Inherit attributes from a versionDefinition.
  inherit (versionDefinition) pname;
  inherit (versionDefinition) branch;
  inherit (versionDefinition) version;
  inherit (versionDefinition) latest;
  inherit (versionDefinition) pkg;
  inherit (versionDefinition)
    pname
    branch
    version
    latest
    pkg
    ;

  # Mark versions older than minSupportedVersion as EOL.
  minSupportedVersion = "4.17";
@@ -118,10 +120,9 @@ let
    lib.attrsets.optionalAttrs withInternalQEMU {
      qemu = {
        src = fetchgit {
          url = "https://xenbits.xen.org/git-http/qemu-xen.git";
          url = "https://xenbits.xenproject.org/git-http/qemu-xen.git";
          fetchSubmodules = true;
          inherit (pkg.qemu) rev;
          inherit (pkg.qemu) hash;
          inherit (pkg.qemu) rev hash;
        };
        patches = lib.lists.optionals (lib.attrsets.hasAttrByPath [ "patches" ] pkg.qemu) pkg.qemu.patches;
        path = "tools/qemu-xen";
@@ -130,9 +131,8 @@ let
    // lib.attrsets.optionalAttrs withInternalSeaBIOS {
      seaBIOS = {
        src = fetchgit {
          url = "https://xenbits.xen.org/git-http/seabios.git";
          inherit (pkg.seaBIOS) rev;
          inherit (pkg.seaBIOS) hash;
          url = "https://xenbits.xenproject.org/git-http/seabios.git";
          inherit (pkg.seaBIOS) rev hash;
        };
        patches = lib.lists.optionals (lib.attrsets.hasAttrByPath [
          "patches"
@@ -143,10 +143,9 @@ let
    // lib.attrsets.optionalAttrs withInternalOVMF {
      ovmf = {
        src = fetchgit {
          url = "https://xenbits.xen.org/git-http/ovmf.git";
          url = "https://xenbits.xenproject.org/git-http/ovmf.git";
          fetchSubmodules = true;
          inherit (pkg.ovmf) rev;
          inherit (pkg.ovmf) hash;
          inherit (pkg.ovmf) rev hash;
        };
        patches = lib.lists.optionals (lib.attrsets.hasAttrByPath [ "patches" ] pkg.ovmf) pkg.ovmf.patches;
        path = "tools/firmware/ovmf-dir-remote";
@@ -157,8 +156,7 @@ let
        src = fetchFromGitHub {
          owner = "ipxe";
          repo = "ipxe";
          inherit (pkg.ipxe) rev;
          inherit (pkg.ipxe) hash;
          inherit (pkg.ipxe) rev hash;
        };
        patches = lib.lists.optionals (lib.attrsets.hasAttrByPath [ "patches" ] pkg.ipxe) pkg.ipxe.patches;
        path = "tools/firmware/etherboot/ipxe.git";
@@ -317,8 +315,7 @@ let
in

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

  outputs = [
    "out" # TODO: Split $out in $bin for binaries and $lib for libraries.
@@ -330,9 +327,8 @@ stdenv.mkDerivation (finalAttrs: {

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

  patches =
@@ -536,8 +532,10 @@ stdenv.mkDerivation (finalAttrs: {
      ${deployPrefetchedSourcesPatches}
    ''
    # Patch shebangs for QEMU and OVMF build scripts.
    + ''
    + lib.strings.optionalString withInternalQEMU ''
      patchShebangs --build tools/qemu-xen/scripts/tracetool.py
    ''
    + lib.strings.optionalString withInternalOVMF ''
      patchShebangs --build tools/firmware/ovmf-dir-remote/OvmfPkg/build.sh tools/firmware/ovmf-dir-remote/BaseTools/BinWrappers/PosixLike/{AmlToC,BrotliCompress,build,GenFfs,GenFv,GenFw,GenSec,LzmaCompress,TianoCompress,Trim,VfrCompile}
    '';

@@ -640,8 +638,15 @@ stdenv.mkDerivation (finalAttrs: {
    };
  };

  meta = {
  meta =
    if
      !(lib.attrsets.hasAttrByPath [
        "meta"
      ] versionDefinition)
    then
      {
        inherit branch;

        # Short description for Xen.
        description =
          "Xen Hypervisor"
@@ -652,6 +657,7 @@ stdenv.mkDerivation (finalAttrs: {
            "meta"
            "description"
          ] packageDefinition) " (${packageDefinition.meta.description})";

        # Long description for Xen.
        longDescription =
          # Starts with the longDescription from ./packages.nix.
@@ -691,9 +697,11 @@ stdenv.mkDerivation (finalAttrs: {
            "\n\nThis Xen (${version}) has been patched against the following known security vulnerabilities:\n"
            + lib.strings.removeSuffix "\n" (lib.strings.concatLines writeAdvisoryDescription)
          );

        homepage = "https://xenproject.org/";
        downloadPage = "https://downloads.xenproject.org/release/xen/${version}/";
        changelog = "https://wiki.xenproject.org/wiki/Xen_Project_${branch}_Release_Notes";

        license = with lib.licenses; [
          # Documentation.
          cc-by-40
@@ -704,13 +712,19 @@ stdenv.mkDerivation (finalAttrs: {
          # Development headers in $dev/include.
          mit
        ];

        # This automatically removes maintainers from EOL versions of Xen, so we aren't bothered about versions we don't explictly support.
        maintainers = lib.lists.optionals (lib.strings.versionAtLeast version minSupportedVersion) (
          with lib.maintainers; [ sigmasquadron ]
        );
        knownVulnerabilities = lib.lists.optional (lib.strings.versionOlder version minSupportedVersion) "Xen ${version} is no longer supported by the Xen Security Team. See https://xenbits.xenproject.org/docs/unstable/support-matrix.html";

        mainProgram = "xl";

        # Evaluates to x86_64-linux.
        platforms = lib.lists.intersectLists lib.platforms.linux lib.platforms.x86_64;
    knownVulnerabilities = lib.lists.optional (lib.strings.versionOlder version minSupportedVersion) "Xen ${version} is no longer supported by the Xen Security Team. See https://xenbits.xenproject.org/docs/unstable/support-matrix.html";
  };

      }
    else
      versionDefinition.meta;
})
+0 −15
Original line number Diff line number Diff line
@@ -99,21 +99,6 @@ in
    })
  ];

  # Xen Security Advisory #458: (4.16.6 - 4.19-rc3)
  "XSA_458" = xsaPatch {
    id = "458";
    title = "Double unlock in x86 guest IRQ handling";
    description = ''
      An optional feature of PCI MSI called "Multiple Message" allows a device
      to use multiple consecutive interrupt vectors.  Unlike for MSI-X, the
      setting up of these consecutive vectors needs to happen all in one go.
      In this handling an error path could be taken in different situations,
      with or without a particular lock held. This error path wrongly releases
      the lock even when it is not currently held.
    '';
    cve = [ "CVE-2024-31143" ];
    hash = "sha256-yHI9Sp/7Ed40iIYQ/HOOIULlfzAzL0c0MGqdF+GR+AQ=";
  };
  # Xen Security Advisory #460: (4.16.6 - 4.19.0)
  "XSA_460" = xsaPatch {
    id = "460";
+22 −13
Original line number Diff line number Diff line
@@ -5,6 +5,9 @@ set -o errexit
set -o pipefail
set -o nounset

#TODO: Use `jq` instead of `sed`.
#TODO: Accept the small security drawback and make this script runnable by r-ryantm.

# This script expects to be called in an interactive terminal somewhere inside Nixpkgs.
echo "Preparing..."
nixpkgs=$(git rev-parse --show-toplevel)
@@ -22,7 +25,7 @@ userInputFingerprint=${userInputFingerprint:-"23E3222C145F4475FA8060A783FE14C957

# Clone xen.git.
echo -e "Cloning \e[1;34mxen.git\e[0m..."
git clone --quiet https://xenbits.xen.org/git-http/xen.git /tmp/xenUpdateScript/xen
git clone --quiet https://xenbits.xenproject.org/git-http/xen.git /tmp/xenUpdateScript/xen
cd /tmp/xenUpdateScript/xen

# Get list of versions and branches.
@@ -35,6 +38,8 @@ minSupportedBranch="$(grep " minSupportedVersion = " "$xenPath"/generic/default
supportedBranches=($(for version in "${branchList[@]}"; do if [ "$(printf '%s\n' "$minSupportedBranch" "$version" | sort -V | head -n1)" = "$minSupportedBranch" ]; then echo "$version"; fi; done))
supportedVersions=($(for version in "${supportedBranches[@]}"; do echo "$versionList" | tr ' ' '\n' | grep "$version" | tail --lines=1; done))

echo -e "\e[1mNOTE\e[0m: As we're also pre-fetching the submodules, QEMU and OVMF may take a very long time to fetch."

# Main loop that installs every supportedVersion.
for version in "${supportedVersions[@]}"; do
    echo -e "\n------------------------------------------------"
@@ -59,31 +64,33 @@ for version in "${supportedVersions[@]}"; do
    git switch --quiet --detach RELEASE-"$version"

    # Originally we told people to go check the Makefile themselves.
    echo -e "\nDetermining source versions from Xen Makefiles..."
    qemuVersion="$(grep -ie "QEMU_UPSTREAM_REVISION ?=" /tmp/xenUpdateScript/xen/Config.mk | sed s/"QEMU_UPSTREAM_REVISION ?= "//g)"
    seaBIOSVersion="$(grep -ie "SEABIOS_UPSTREAM_REVISION ?= rel-" /tmp/xenUpdateScript/xen/Config.mk | sed s/"SEABIOS_UPSTREAM_REVISION ?= "//g)"
    ovmfVersion="$(grep -ie "OVMF_UPSTREAM_REVISION ?=" /tmp/xenUpdateScript/xen/Config.mk | sed s/"OVMF_UPSTREAM_REVISION ?= "//g)"
    ipxeVersion="$(grep -ie "IPXE_GIT_TAG :=" /tmp/xenUpdateScript/xen/tools/firmware/etherboot/Makefile | sed s/"IPXE_GIT_TAG := "//g)"
    echo -e -n "\nDetermining source versions from Xen Makefiles..."
    qemuVersion="$(grep "QEMU_UPSTREAM_REVISION ?=" /tmp/xenUpdateScript/xen/Config.mk | sed s/"QEMU_UPSTREAM_REVISION ?= "//g)"
    seaBIOSVersion="$(grep "SEABIOS_UPSTREAM_REVISION ?= rel-" /tmp/xenUpdateScript/xen/Config.mk | sed s/"SEABIOS_UPSTREAM_REVISION ?= "//g)"
    ovmfVersion="$(grep "OVMF_UPSTREAM_REVISION ?=" /tmp/xenUpdateScript/xen/Config.mk | sed s/"OVMF_UPSTREAM_REVISION ?= "//g)"
    miniOSVersion="$(grep "MINIOS_UPSTREAM_REVISION ?=" /tmp/xenUpdateScript/xen/Config.mk | sed s/"MINIOS_UPSTREAM_REVISION ?= "//g)"
    ipxeVersion="$(grep "IPXE_GIT_TAG :=" /tmp/xenUpdateScript/xen/tools/firmware/etherboot/Makefile | sed s/"IPXE_GIT_TAG := "//g)"
    echo "done!"

    # Use `nix-prefetch-git` to fetch `rev`s and `hash`es.
    echo "Pre-fetching sources and determining hashes..."
    echo -e -n "  \e[1;32mXen\e[0m..."
    fetchXen=$(nix-prefetch-git --url https://xenbits.xen.org/git-http/xen.git --rev RELEASE-"$version" --quiet)
    fetchXen=$(nix-prefetch-git --url https://xenbits.xenproject.org/git-http/xen.git --rev RELEASE-"$version" --quiet)
    finalVersion="$(echo "$fetchXen" | tr ', ' '\n ' | grep -ie rev | sed s/'  "rev": "'//g | sed s/'"'//g)"
    hash="$(echo "$fetchXen" | tr ', ' '\n ' | grep -ie hash | sed s/'  "hash": "'//g | sed s/'"'//g)"
    echo "done!"
    echo -e -n "  \e[1;36mQEMU\e[0m..."
    fetchQEMU=$(nix-prefetch-git --url https://xenbits.xen.org/git-http/qemu-xen.git --rev "$qemuVersion" --quiet --fetch-submodules)
    fetchQEMU=$(nix-prefetch-git --url https://xenbits.xenproject.org/git-http/qemu-xen.git --rev "$qemuVersion" --quiet --fetch-submodules)
    finalQEMUVersion="$(echo "$fetchQEMU" | tr ', ' '\n ' | grep -ie rev | sed s/'  "rev": "'//g | sed s/'"'//g)"
    qemuHash="$(echo "$fetchQEMU" | tr ', ' '\n ' | grep -ie hash | sed s/'  "hash": "'//g | sed s/'"'//g)"
    echo "done!"
    echo -e -n "  \e[1;36mSeaBIOS\e[0m..."
    fetchSeaBIOS=$(nix-prefetch-git --url https://xenbits.xen.org/git-http/seabios.git --rev "$seaBIOSVersion" --quiet)
    fetchSeaBIOS=$(nix-prefetch-git --url https://xenbits.xenproject.org/git-http/seabios.git --rev "$seaBIOSVersion" --quiet)
    finalSeaBIOSVersion="$(echo "$fetchSeaBIOS" | tr ', ' '\n ' | grep -ie rev | sed s/'  "rev": "'//g | sed s/'"'//g)"
    seaBIOSHash="$(echo "$fetchSeaBIOS" | tr ', ' '\n ' | grep -ie hash | sed s/'  "hash": "'//g | sed s/'"'//g)"
    echo "done!"
    echo -e -n "  \e[1;36mOVMF\e[0m..."
    ovmfHash="$(nix-prefetch-git --url https://xenbits.xen.org/git-http/ovmf.git --rev "$ovmfVersion" --quiet --fetch-submodules | grep -ie hash | sed s/'  "hash": "'//g | sed s/'",'//g)"
    ovmfHash="$(nix-prefetch-git --url https://xenbits.xenproject.org/git-http/ovmf.git --rev "$ovmfVersion" --quiet --fetch-submodules | grep -ie hash | sed s/'  "hash": "'//g | sed s/'",'//g)"
    echo "done!"
    echo -e -n "  \e[1;36miPXE\e[0m..."
    ipxeHash="$(nix-prefetch-git --url https://github.com/ipxe/ipxe.git --rev "$ipxeVersion" --quiet | grep -ie hash | sed s/'  "hash": "'//g | sed s/'",'//g)"
@@ -120,13 +127,13 @@ for version in "${supportedVersions[@]}"; do
    echo -e "Found the following patches:\n  \e[1;32mXen\e[0m:     \e[1;33m$discoveredXenPatchesEcho\e[0m\n  \e[1;36mQEMU\e[0m:    \e[1;33m$discoveredQEMUPatchesEcho\e[0m\n  \e[1;36mSeaBIOS\e[0m: \e[1;33m$discoveredSeaBIOSPatchesEcho\e[0m\n  \e[1;36mOVMF\e[0m:    \e[1;33m$discoveredOVMFPatchesEcho\e[0m\n  \e[1;36miPXE\e[0m:    \e[1;33m$discoveredIPXEPatchesEcho\e[0m"

    # Prepare patches that are called in ./patches.nix.
    defaultPatchListInit=("QUBES_REPRODUCIBLE_BUILDS" "XSA_458" "XSA_460" "XSA_461" )
    defaultPatchListInit=("QUBES_REPRODUCIBLE_BUILDS" "XSA_460" "XSA_461" )
    read -r -a defaultPatchList -p $'\nWould you like to override the \e[1;34mupstreamPatches\e[0m list for \e[1;32mXen '"$version"$'\e[0m? If no, press \e[1;34menter\e[0m to use the default patch list: [ \e[1;34m'"${defaultPatchListInit[*]}"$' \e[0m]: '
    defaultPatchList=(${defaultPatchList[@]:-${defaultPatchListInit[@]}})
    upstreamPatches=${defaultPatchList[*]}

    # Write and format default.nix file.
    echo -e "\nWriting updated \e[1;34mversionDefinition\e[0m..."
    echo -e -n "\nWriting updated \e[1;34mversionDefinition\e[0m..."
    cat >"$branch"/default.nix <<EOF
{
  lib,
@@ -181,9 +188,11 @@ callPackage (import ../generic/default.nix {
  };
}) ({ ocamlPackages = ocaml-ng.ocamlPackages_$ocamlVersion; } // genericDefinition)
EOF
echo done!

    echo "Formatting..."
    echo -n "Formatting..."
    nixfmt "$branch"/default.nix
    echo done!

    echo -e "\n\e[1;32mSuccessfully produced $branch/default.nix.\e[0m"
done