xen: cleanup, code quality improvements (#342915)

This commit is contained in:
Emily 2024-09-19 20:04:06 +01:00 committed by GitHub
commit 0f3ce1759b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 129 additions and 121 deletions

View File

@ -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,77 +638,93 @@ stdenv.mkDerivation (finalAttrs: {
};
};
meta = {
inherit branch;
# Short description for Xen.
description =
"Xen Hypervisor"
# The "and related components" addition is automatically hidden if said components aren't being built.
+ lib.strings.optionalString (prefetchedSources != { }) " and related components"
# To alter the description inside the paranthesis, edit ./packages.nix.
+ lib.strings.optionalString (lib.attrsets.hasAttrByPath [
meta =
if
!(lib.attrsets.hasAttrByPath [
"meta"
"description"
] packageDefinition) " (${packageDefinition.meta.description})";
# Long description for Xen.
longDescription =
# Starts with the longDescription from ./packages.nix.
(packageDefinition.meta.longDescription or "")
+ lib.strings.optionalString (!withInternalQEMU) (
"\nUse with `qemu_xen_${lib.strings.stringAsChars (x: if x == "." then "_" else x) branch}`"
+ lib.strings.optionalString latest " or `qemu_xen`"
+ ".\n"
)
# Then, if any of the optional with* components are being built, add the "Includes:" string.
+
lib.strings.optionalString
(
withInternalQEMU
|| withInternalSeaBIOS
|| withInternalOVMF
|| withInternalIPXE
|| withEFI
|| withFlask
] versionDefinition)
then
{
inherit branch;
# Short description for Xen.
description =
"Xen Hypervisor"
# The "and related components" addition is automatically hidden if said components aren't being built.
+ lib.strings.optionalString (prefetchedSources != { }) " and related components"
# To alter the description inside the paranthesis, edit ./packages.nix.
+ lib.strings.optionalString (lib.attrsets.hasAttrByPath [
"meta"
"description"
] packageDefinition) " (${packageDefinition.meta.description})";
# Long description for Xen.
longDescription =
# Starts with the longDescription from ./packages.nix.
(packageDefinition.meta.longDescription or "")
+ lib.strings.optionalString (!withInternalQEMU) (
"\nUse with `qemu_xen_${lib.strings.stringAsChars (x: if x == "." then "_" else x) branch}`"
+ lib.strings.optionalString latest " or `qemu_xen`"
+ ".\n"
)
(
"\nIncludes:"
# Originally, this was a call for the complicated withPrefetchedSources. Since there aren't
# that many optional components, we just use lib.strings.optionalString, because it's simpler.
# Optional components that aren't being built are automatically hidden.
+ lib.strings.optionalString withEFI "\n* `xen.efi`: Xen's [EFI binary](https://xenbits.xenproject.org/docs/${branch}-testing/misc/efi.html), available on the `boot` output of this package."
+ lib.strings.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."
+ lib.strings.optionalString withInternalQEMU "\n* `qemu-xen`: Xen's mirror of [QEMU](https://www.qemu.org/)."
+ lib.strings.optionalString withInternalSeaBIOS "\n* `seabios-xen`: Xen's mirror of [SeaBIOS](https://www.seabios.org/SeaBIOS)."
+ lib.strings.optionalString withInternalOVMF "\n* `ovmf-xen`: Xen's mirror of [OVMF](https://github.com/tianocore/tianocore.github.io/wiki/OVMF)."
+ lib.strings.optionalString withInternalIPXE "\n* `ipxe-xen`: Xen's pinned version of [iPXE](https://ipxe.org/)."
)
# 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.
+ lib.strings.optionalString (writeAdvisoryDescription != [ ]) (
"\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
# Most of Xen is licensed under the GPL v2.0.
gpl2Only
# Xen Libraries and the `xl` command-line utility.
lgpl21Only
# 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 ]
);
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";
};
# Then, if any of the optional with* components are being built, add the "Includes:" string.
+
lib.strings.optionalString
(
withInternalQEMU
|| withInternalSeaBIOS
|| withInternalOVMF
|| withInternalIPXE
|| withEFI
|| withFlask
)
(
"\nIncludes:"
# Originally, this was a call for the complicated withPrefetchedSources. Since there aren't
# that many optional components, we just use lib.strings.optionalString, because it's simpler.
# Optional components that aren't being built are automatically hidden.
+ lib.strings.optionalString withEFI "\n* `xen.efi`: Xen's [EFI binary](https://xenbits.xenproject.org/docs/${branch}-testing/misc/efi.html), available on the `boot` output of this package."
+ lib.strings.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."
+ lib.strings.optionalString withInternalQEMU "\n* `qemu-xen`: Xen's mirror of [QEMU](https://www.qemu.org/)."
+ lib.strings.optionalString withInternalSeaBIOS "\n* `seabios-xen`: Xen's mirror of [SeaBIOS](https://www.seabios.org/SeaBIOS)."
+ lib.strings.optionalString withInternalOVMF "\n* `ovmf-xen`: Xen's mirror of [OVMF](https://github.com/tianocore/tianocore.github.io/wiki/OVMF)."
+ lib.strings.optionalString withInternalIPXE "\n* `ipxe-xen`: Xen's pinned version of [iPXE](https://ipxe.org/)."
)
# 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.
+ lib.strings.optionalString (writeAdvisoryDescription != [ ]) (
"\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
# Most of Xen is licensed under the GPL v2.0.
gpl2Only
# Xen Libraries and the `xl` command-line utility.
lgpl21Only
# 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;
}
else
versionDefinition.meta;
})

View File

@ -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";

View File

@ -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