diff --git a/.github/workflows/go-test-coverage.yml b/.github/workflows/go-test-coverage.yml index 194536f23dc..3e0dec379b0 100644 --- a/.github/workflows/go-test-coverage.yml +++ b/.github/workflows/go-test-coverage.yml @@ -88,7 +88,7 @@ jobs: sudo env "PATH=$PATH" make go-test-coverage - name: Upload test coverage - uses: actions/upload-artifact@v2.1.4 + uses: actions/upload-artifact@v4 with: name: TestCoverage path: toolkit/out/tools/test_coverage_report.html diff --git a/.github/workflows/lint-specs.yml b/.github/workflows/lint-specs.yml index fc3ff4fb5e1..887bb0812ce 100644 --- a/.github/workflows/lint-specs.yml +++ b/.github/workflows/lint-specs.yml @@ -97,7 +97,7 @@ jobs: fi exit 0 - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 if: ${{ always() }} with: name: linted_specs diff --git a/.pipelines/containerSourceData/busybox/Dockerfile-Busybox b/.pipelines/containerSourceData/busybox/Dockerfile-Busybox index 31592d5aa5f..c91b763628f 100644 --- a/.pipelines/containerSourceData/busybox/Dockerfile-Busybox +++ b/.pipelines/containerSourceData/busybox/Dockerfile-Busybox @@ -33,8 +33,7 @@ RUN mkdir /staging \ && pushd /staging \ && rm -rf boot media mnt opt run \ && rm -rf usr/lib/sysimage \ - && rm -rf var/cache \ - && rm -rf var/lib/rpm; \ + && rm -rf var/cache; \ ln -vL /staging/usr/sbin/busybox /staging/bin/; \ chroot /staging /bin/busybox --install -s /bin diff --git a/.pipelines/containerSourceData/scripts/BuildGoldenContainer.sh b/.pipelines/containerSourceData/scripts/BuildGoldenContainer.sh index 58f7aeaf457..911eb2c415e 100755 --- a/.pipelines/containerSourceData/scripts/BuildGoldenContainer.sh +++ b/.pipelines/containerSourceData/scripts/BuildGoldenContainer.sh @@ -57,7 +57,7 @@ set -e # -j OUTPUT -k ./rpms.tar.gz -l ~/CBL-Mariner/.pipelines/containerSourceData \ # -m "false" -n "false" -p development -q "false" -u "true" -while getopts ":a:b:c:d:e:f:g:h:i:j:k:l:m:n:o:p:q:r:s:t:u:v:" OPTIONS; do +while getopts ":a:b:c:d:e:f:g:h:i:j:k:l:m:n:o:p:q:r:s:t:u:v:w:" OPTIONS; do case ${OPTIONS} in a ) BASE_IMAGE_NAME_FULL=$OPTARG;; b ) ACR=$OPTARG;; @@ -81,6 +81,7 @@ while getopts ":a:b:c:d:e:f:g:h:i:j:k:l:m:n:o:p:q:r:s:t:u:v:" OPTIONS; do t ) SBOM_SCRIPT=$OPTARG;; u ) DISTROLESS=$OPTARG;; v ) VERSION_EXTRACT_CMD=$OPTARG;; + w ) TOOLCHAIN_RPMS_TARBALL=$OPTARG;; \? ) echo "Error - Invalid Option: -$OPTARG" 1>&2 @@ -124,6 +125,7 @@ function print_inputs { echo "SBOM_TOOL_PATH -> $SBOM_TOOL_PATH" echo "SBOM_SCRIPT -> $SBOM_SCRIPT" echo "DISTROLESS -> $DISTROLESS" + echo "TOOLCHAIN_RPMS_TARBALL -> $TOOLCHAIN_RPMS_TARBALL" } function validate_inputs { @@ -167,6 +169,11 @@ function validate_inputs { exit 1 fi + if [[ ! -f $TOOLCHAIN_RPMS_TARBALL ]]; then + echo "Error - No TOOLCHAIN_RPMS_TARBALL tarball found." + exit 1 + fi + if [ ! -d "$CONTAINER_SRC_DIR" ]; then echo "Error - Container source directory does not exist." exit 1 @@ -262,6 +269,7 @@ function prepare_docker_directory { # Copy files into docker context directory tar -xf "$RPMS_TARBALL" -C "$HOST_MOUNTED_DIR"/ + tar -xf "$TOOLCHAIN_RPMS_TARBALL" -C "$HOST_MOUNTED_DIR/RPMS"/ cp -v "$CONTAINER_SRC_DIR/marinerLocalRepo.repo" "$HOST_MOUNTED_DIR"/ } diff --git a/.pipelines/prchecks/PackageBuildPRCheck.yml b/.pipelines/prchecks/PackageBuildPRCheck.yml index 0bae7267320..ea1426f5c3a 100644 --- a/.pipelines/prchecks/PackageBuildPRCheck.yml +++ b/.pipelines/prchecks/PackageBuildPRCheck.yml @@ -1,10 +1,8 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. -# Since we're boosting our builds by using a private, pre-compiled raw toolchain -# the pipeline requires defining the following variables outside of the YAML: -# - rawToolchainCacheURL_AMD64 -# - rawToolchainCacheURL_ARM64 +# The "agentPool" parameter is defined in the "Agent pools (DEV)" variable group. +# The "rawToolchain*" parameters are defined in the "Raw toolchain info" variable group. trigger: none @@ -13,15 +11,15 @@ parameters: type: object default: - name: "AMD64" - agentPool: "$(DEV_AMD64_Managed)" # Pool defined inside the "Agent pools (DEV)" variable group. + agentPool: "$(DEV_AMD64_Managed)" maxCPUs: "$(($(nproc) / 2))" - rawToolchainCacheURL: "$(rawToolchainCacheURL_AMD64)" - rawToolchainExpectedHash: "f56df34b90915c93f772d3961bf5e9eeb8c1233db43dd92070214e4ce6b72894" + rawToolchainCacheURL: "$(rawToolchainCacheURL_AMD64_2.0)" + rawToolchainExpectedHash: "$(rawToolchainCacheHash_AMD64_2.0)" - name: "ARM64" - agentPool: "$(DEV_ARM64_Managed)" # Pool defined inside the "Agent pools (DEV)" variable group. + agentPool: "$(DEV_ARM64_Managed)" maxCPUs: "$(($(nproc) / 3))" - rawToolchainCacheURL: "$(rawToolchainCacheURL_ARM64)" - rawToolchainExpectedHash: "65de43b3bdcfdaac71df1f11fd1f830a8109b1eb9d7cb6cbc2e2d0e929d0ef76" + rawToolchainCacheURL: "$(rawToolchainCacheURL_ARM64_2.0)" + rawToolchainExpectedHash: "$(rawToolchainCacheHash_ARM64_2.0)" - name: debug type: boolean default: false @@ -36,12 +34,15 @@ resources: variables: - group: "Agent pools (DEV)" + - group: "Raw toolchain info" - name: rpmsArtifactNameBase value: RPMs - name: toolchainArtifactNameBase value: Toolchain + - name: toolchainTestsArtifactNameBase + value: Toolchain_tests - name: system.debug - value: '${{ parameters.debug }}' + value: "${{ parameters.debug }}" extends: template: v2/OneBranch.NonOfficial.CrossPlat.yml@templates @@ -75,6 +76,9 @@ extends: # Toolchain package tests should be run through the full package build, calculate the list of packages that should be re-tested # and make it available to the next stage via an output variable: 'CalculateToolchainPackageRetestList.toolchainPackageRetestList' - template: .pipelines/templates/ToolchainCalculatePackageRetests.yml@self + parameters: + # GCC fails to build as a regular package. + ignoredSpecs: ["gcc"] - script: echo "##vso[task.setvariable variable=toolchainArtifactName;isOutput=true]$(ob_artifactBaseName)" name: "ToolchainArtifactName" @@ -100,9 +104,8 @@ extends: isCustom: true name: ${{ configuration.agentPool }} variables: - ob_artifactBaseName: ${{ variables.rpmsArtifactNameBase }}_${{ configuration.name }}_$(System.JobAttempt) + ob_artifactBaseName: $(rpmsArtifactNameBase)_${{ configuration.name }}_$(System.JobAttempt) ob_outputDirectory: $(Build.ArtifactStagingDirectory) - testListFromToolchain: $[ stageDependencies.Toolchain_${{ configuration.name }}.Build.outputs['CalculateToolchainPackageRetestList.toolchainPackageRetestList'] ] toolchainArtifactName: $[ stageDependencies.Toolchain_${{ configuration.name }}.Build.outputs['ToolchainArtifactName.toolchainArtifactName'] ] steps: - template: .pipelines/templates/PackageBuild.yml@self @@ -112,12 +115,11 @@ extends: isCheckBuild: true isQuickRebuildPackages: true isUseCCache: true - outputArtifactsFolder: $(ob_outputDirectory) maxCPU: "${{ configuration.maxCPUs }}" + outputArtifactsFolder: $(ob_outputDirectory) pipArtifactFeeds: "mariner/Mariner-Pypi-Feed" selfRepoName: self testSuiteName: "[${{ configuration.name }}] Package test" - testRerunList: "$(testListFromToolchain)" - script: echo "##vso[task.setvariable variable=rpmsArtifactName;isOutput=true]$(ob_artifactBaseName)" name: "RPMsArtifactName" @@ -125,12 +127,50 @@ extends: - task: PublishPipelineArtifact@1 inputs: - artifact: ${{ variables.rpmsArtifactNameBase }}_${{ configuration.name }}_$(System.JobAttempt) + artifact: $(rpmsArtifactNameBase)_${{ configuration.name }}_$(System.JobAttempt) targetPath: $(ob_outputDirectory) condition: always() displayName: "Publish packages build artifacts" - - stage: sodiff_${{ configuration.name }} + - stage: Toolchain_tests_${{ configuration.name }} + dependsOn: Toolchain_${{ configuration.name }} + jobs: + - job: TestToolchainPackages + condition: stageDependencies.Toolchain_${{ configuration.name }}.Build.outputs['CalculateToolchainPackageRetestList.toolchainPackageRetestList'] + pool: + type: linux + isCustom: true + name: ${{ configuration.agentPool }} + variables: + ob_artifactBaseName: $(toolchainTestsArtifactNameBase)_${{ configuration.name }}_$(System.JobAttempt) + ob_outputDirectory: $(Build.ArtifactStagingDirectory) + testListFromToolchain: $[ stageDependencies.Toolchain_${{ configuration.name }}.Build.outputs['CalculateToolchainPackageRetestList.toolchainPackageRetestList'] ] + toolchainArtifactName: $[ stageDependencies.Toolchain_${{ configuration.name }}.Build.outputs['ToolchainArtifactName.toolchainArtifactName'] ] + steps: + - template: .pipelines/templates/PackageBuild.yml@self + parameters: + checkBuildRetries: "1" + customToolchainArtifactName: $(toolchainArtifactName) + isAllowToolchainRebuilds: true + isCheckBuild: true + isQuickRebuildPackages: true + isUseCCache: true + maxCPU: "${{ configuration.maxCPUs }}" + outputArtifactsFolder: $(ob_outputDirectory) + pipArtifactFeeds: "mariner/Mariner-Pypi-Feed" + selfRepoName: self + srpmPackList: "$(testListFromToolchain)" + testRerunList: "$(testListFromToolchain)" + testSuiteName: "[${{ configuration.name }}] Toolchain test" + + - task: PublishPipelineArtifact@1 + inputs: + artifact: $(toolchainTestsArtifactNameBase)_${{ configuration.name }}_$(System.JobAttempt) + targetPath: $(ob_outputDirectory) + condition: always() + displayName: "Publish toolchain build artifacts" + + - stage: Sodiff_${{ configuration.name }} dependsOn: RPMs_${{ configuration.name }} jobs: - job: Sodiff_Check diff --git a/.pipelines/templates/PackageBuild.yml b/.pipelines/templates/PackageBuild.yml index ca3038450a5..4ab4ec29042 100644 --- a/.pipelines/templates/PackageBuild.yml +++ b/.pipelines/templates/PackageBuild.yml @@ -37,6 +37,14 @@ parameters: # - name: build-artifacts # rpmsTarball: cache.tar.gz + - name: isAllowToolchainRebuilds + type: string + default: "default" + values: + - "default" + - "false" + - "true" + - name: isCheckBuild type: string default: "default" @@ -105,6 +113,14 @@ parameters: type: string default: "srpms.tar.gz" + - name: packageBuildList + type: string + default: "" + + - name: packageRebuildList + type: string + default: "" + - name: pipArtifactFeeds type: string default: "" @@ -184,20 +200,14 @@ steps: check_build_retries_arg="CHECK_BUILD_RETRIES=${{ parameters.checkBuildRetries }}" fi - if [[ ${{ parameters.isDeltaBuild }} == "true" ]]; then - delta_fetch_arg="DELTA_FETCH=y" - elif [[ ${{ parameters.isDeltaBuild }} == "false" ]]; then - delta_fetch_arg="DELTA_FETCH=n" - fi - - if [[ -n "${{ parameters.maxCascadingRebuilds }}" ]]; then - max_cascading_rebuilds_arg="MAX_CASCADING_REBUILDS=${{ parameters.maxCascadingRebuilds }}" + if [[ -n "${{ parameters.customToolchainArtifactName }}" ]]; then + toolchain_archive_arg="TOOLCHAIN_ARCHIVE=$(toolchainArchive)" fi - if [[ ${{ parameters.isQuickRebuildPackages }} == "true" ]]; then - quick_rebuild_packages_arg="QUICK_REBUILD_PACKAGES=y" - elif [[ ${{ parameters.isQuickRebuildPackages }} == "false" ]]; then - quick_rebuild_packages_arg="QUICK_REBUILD_PACKAGES=n" + if [[ ${{ parameters.isAllowToolchainRebuilds }} == "true" ]]; then + allow_toolchain_rebuilds_arg="ALLOW_TOOLCHAIN_REBUILDS=y" + elif [[ ${{ parameters.isAllowToolchainRebuilds }} == "false" ]]; then + allow_toolchain_rebuilds_arg="ALLOW_TOOLCHAIN_REBUILDS=n" fi if [[ ${{ parameters.isCheckBuild }} == "true" ]]; then @@ -206,8 +216,16 @@ steps: run_check_arg="RUN_CHECK=n" fi - if [[ -n "${{ parameters.customToolchainArtifactName }}" ]]; then - toolchain_archive_arg="TOOLCHAIN_ARCHIVE=$(toolchainArchive)" + if [[ ${{ parameters.isDeltaBuild }} == "true" ]]; then + delta_fetch_arg="DELTA_FETCH=y" + elif [[ ${{ parameters.isDeltaBuild }} == "false" ]]; then + delta_fetch_arg="DELTA_FETCH=n" + fi + + if [[ ${{ parameters.isQuickRebuildPackages }} == "true" ]]; then + quick_rebuild_packages_arg="QUICK_REBUILD_PACKAGES=y" + elif [[ ${{ parameters.isQuickRebuildPackages }} == "false" ]]; then + quick_rebuild_packages_arg="QUICK_REBUILD_PACKAGES=n" fi if [[ ${{ parameters.isUseCCache }} == "true" ]]; then @@ -216,15 +234,22 @@ steps: use_ccache_arg="USE_CCACHE=n" fi + if [[ -n "${{ parameters.maxCascadingRebuilds }}" ]]; then + max_cascading_rebuilds_arg="MAX_CASCADING_REBUILDS=${{ parameters.maxCascadingRebuilds }}" + fi + sudo make -C "${{ parameters.buildRepoRoot }}/toolkit" build-packages -j$(nproc) \ CONCURRENT_PACKAGE_BUILDS=${{ parameters.concurrentPackageBuilds }} \ CONFIG_FILE="" \ MAX_CPU="${{ parameters.maxCPU }}" \ + PACKAGE_BUILD_LIST="${{ parameters.packageBuildList }}" \ + PACKAGE_REBUILD_LIST="${{ parameters.packageRebuildList }}" \ REBUILD_TOOLS=y \ REPO_LIST="${{ parameters.extraPackageRepos }}" \ SPECS_DIR="${{ parameters.buildRepoRoot }}/${{ parameters.specsFolderPath }}" \ SRPM_PACK_LIST="${{ parameters.srpmPackList }}" \ TEST_RERUN_LIST="${{ parameters.testRerunList }}" \ + $allow_toolchain_rebuilds_arg \ $check_build_retries_arg \ $delta_fetch_arg \ $max_cascading_rebuilds_arg \ diff --git a/.pipelines/templates/PackageTestResultsAnalysis.yml b/.pipelines/templates/PackageTestResultsAnalysis.yml index f89d6322841..f015abcb0f2 100644 --- a/.pipelines/templates/PackageTestResultsAnalysis.yml +++ b/.pipelines/templates/PackageTestResultsAnalysis.yml @@ -281,14 +281,16 @@ steps: - ${{ if parameters.failOnTestFailures }}: - bash: | - report_path="${{ parameters.testsWorkspace }}/${{ parameters.reportFileName }}" - if [[ ! -f "$report_path" ]]; then - echo "##[error]Test report not found at '$report_path'." - exit 1 - fi - - if ! grep -q '^ - 1.18.0-25 +- Bump release to rebuild with go 1.22.7 + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 1.18.0-24 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS-EXTENDED/containernetworking-plugins/containernetworking-plugins.spec b/SPECS-EXTENDED/containernetworking-plugins/containernetworking-plugins.spec index faeb741f486..c01ece88d0a 100644 --- a/SPECS-EXTENDED/containernetworking-plugins/containernetworking-plugins.spec +++ b/SPECS-EXTENDED/containernetworking-plugins/containernetworking-plugins.spec @@ -24,7 +24,7 @@ Name: %{project}-%{repo} Version: 1.1.1 -Release: 15%{?dist} +Release: 16%{?dist} Summary: Libraries for writing CNI plugin License: ASL 2.0 and BSD and MIT Vendor: Microsoft Corporation @@ -129,6 +129,9 @@ install -p plugins/ipam/dhcp/systemd/cni-dhcp.socket %{buildroot}%{_unitdir} %{_unitdir}/cni-dhcp.socket %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 1.1.1-16 +- Bump release to rebuild with go 1.22.7 + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 1.1.1-15 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS-EXTENDED/delve/delve.spec b/SPECS-EXTENDED/delve/delve.spec index 8e6812fae04..593ddb35582 100644 --- a/SPECS-EXTENDED/delve/delve.spec +++ b/SPECS-EXTENDED/delve/delve.spec @@ -2,7 +2,7 @@ Vendor: Microsoft Corporation Distribution: Mariner Name: delve Version: 1.5.0 -Release: 18%{?dist} +Release: 19%{?dist} Summary: A debugger for the Go programming language License: MIT @@ -72,6 +72,9 @@ done %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 1.5.0-19 +- Bump release to rebuild with go 1.22.7 + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 1.5.0-18 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS-EXTENDED/nmi/nmi.spec b/SPECS-EXTENDED/nmi/nmi.spec index 4ee1461e8d6..d993ad75f4f 100644 --- a/SPECS-EXTENDED/nmi/nmi.spec +++ b/SPECS-EXTENDED/nmi/nmi.spec @@ -2,7 +2,7 @@ Summary: Node Managed Identity Name: nmi Version: 1.8.17 -Release: 4%{?dist} +Release: 5%{?dist} License: MIT Vendor: Microsoft Corporation Distribution: Mariner @@ -62,6 +62,9 @@ popd %{_bindir}/%{name} %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 1.8.17-5 +- Bump release to rebuild with go 1.22.7 + * Wed Jul 17 2024 Muhammad Falak R Wani - 1.8.17-4 - Drop requirement on a specific version of golang diff --git a/SPECS-EXTENDED/podman/podman.spec b/SPECS-EXTENDED/podman/podman.spec index f5b820ac500..4aa2df29143 100644 --- a/SPECS-EXTENDED/podman/podman.spec +++ b/SPECS-EXTENDED/podman/podman.spec @@ -36,7 +36,7 @@ Name: podman Version: 4.1.1 -Release: 21%{?dist} +Release: 22%{?dist} License: ASL 2.0 and BSD and ISC and MIT and MPLv2.0 Summary: Manage Pods, Containers and Container Images Vendor: Microsoft Corporation @@ -387,6 +387,9 @@ cp -pav test/system %{buildroot}/%{_datadir}/%{name}/test/ # rhcontainerbot account currently managed by lsm5 %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 4.1.1-22 +- Bump release to rebuild with go 1.22.7 + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 4.1.1-21 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS-EXTENDED/umoci/umoci.spec b/SPECS-EXTENDED/umoci/umoci.spec index b26f2f70cee..367087c688f 100644 --- a/SPECS-EXTENDED/umoci/umoci.spec +++ b/SPECS-EXTENDED/umoci/umoci.spec @@ -1,7 +1,7 @@ Summary: Open Container Image manipulation tool Name: umoci Version: 0.4.7 -Release: 16%{?dist} +Release: 17%{?dist} License: Apache-2.0 Vendor: Microsoft Corporation Distribution: Mariner @@ -39,6 +39,9 @@ go test -mod=vendor %{_bindir}/umoci %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 0.4.7-17 +- Bump release to rebuild with go 1.22.7 + * Wed Jul 17 2024 Muhammad Falak R Wani - 0.4.7-16 - Drop requirement on a specific version of golang diff --git a/SPECS-SIGNED/kernel-azure-signed/kernel-azure-signed.spec b/SPECS-SIGNED/kernel-azure-signed/kernel-azure-signed.spec index 756a698c52d..bf62a473e8c 100644 --- a/SPECS-SIGNED/kernel-azure-signed/kernel-azure-signed.spec +++ b/SPECS-SIGNED/kernel-azure-signed/kernel-azure-signed.spec @@ -9,7 +9,7 @@ %define uname_r %{version}-%{release} Summary: Signed Linux Kernel for Azure Name: kernel-azure-signed-%{buildarch} -Version: 5.15.164.1 +Version: 5.15.167.1 Release: 1%{?dist} License: GPLv2 Vendor: Microsoft Corporation @@ -153,6 +153,12 @@ ln -sf linux-%{uname_r}.cfg /boot/mariner.cfg %exclude /module_info.ld %changelog +* Wed Sep 18 2024 CBL-Mariner Servicing Account - 5.15.167.1-1 +- Auto-upgrade to 5.15.167.1 + +* Thu Aug 29 2024 CBL-Mariner Servicing Account - 5.15.165.1-1 +- Auto-upgrade to 5.15.165.1 + * Fri Aug 09 2024 CBL-Mariner Servicing Account - 5.15.164.1-1 - Auto-upgrade to 5.15.164.1 diff --git a/SPECS-SIGNED/kernel-hci-signed/kernel-hci-signed.spec b/SPECS-SIGNED/kernel-hci-signed/kernel-hci-signed.spec index b5c387d6143..6bf9056ad53 100644 --- a/SPECS-SIGNED/kernel-hci-signed/kernel-hci-signed.spec +++ b/SPECS-SIGNED/kernel-hci-signed/kernel-hci-signed.spec @@ -4,7 +4,7 @@ %define uname_r %{version}-%{release} Summary: Signed Linux Kernel for HCI Name: kernel-hci-signed-%{buildarch} -Version: 5.15.164.1 +Version: 5.15.167.1 Release: 1%{?dist} License: GPLv2 Vendor: Microsoft Corporation @@ -149,6 +149,12 @@ ln -sf linux-%{uname_r}.cfg /boot/mariner.cfg %exclude /module_info.ld %changelog +* Wed Sep 18 2024 CBL-Mariner Servicing Account - 5.15.167.1-1 +- Auto-upgrade to 5.15.167.1 + +* Thu Aug 29 2024 CBL-Mariner Servicing Account - 5.15.165.1-1 +- Auto-upgrade to 5.15.165.1 + * Fri Aug 09 2024 CBL-Mariner Servicing Account - 5.15.164.1-1 - Auto-upgrade to 5.15.164.1 diff --git a/SPECS-SIGNED/kernel-signed/kernel-signed.spec b/SPECS-SIGNED/kernel-signed/kernel-signed.spec index 11d372c72ba..ba288f78de6 100644 --- a/SPECS-SIGNED/kernel-signed/kernel-signed.spec +++ b/SPECS-SIGNED/kernel-signed/kernel-signed.spec @@ -9,7 +9,7 @@ %define uname_r %{version}-%{release} Summary: Signed Linux Kernel for %{buildarch} systems Name: kernel-signed-%{buildarch} -Version: 5.15.164.1 +Version: 5.15.167.1 Release: 1%{?dist} License: GPLv2 Vendor: Microsoft Corporation @@ -153,6 +153,15 @@ ln -sf linux-%{uname_r}.cfg /boot/mariner.cfg %exclude /module_info.ld %changelog +* Wed Sep 18 2024 CBL-Mariner Servicing Account - 5.15.167.1-1 +- Auto-upgrade to 5.15.167.1 + +* Thu Aug 29 2024 CBL-Mariner Servicing Account - 5.15.165.1-1 +- Auto-upgrade to 5.15.165.1 + +* Tue Aug 27 2024 Chris Co - 5.15.164.1-2 +- Bump release to match kernel + * Fri Aug 09 2024 CBL-Mariner Servicing Account - 5.15.164.1-1 - Auto-upgrade to 5.15.164.1 diff --git a/SPECS/KeysInUse-OpenSSL/KeysInUse-OpenSSL.spec b/SPECS/KeysInUse-OpenSSL/KeysInUse-OpenSSL.spec index 2a173fede5f..50e1b8d62af 100644 --- a/SPECS/KeysInUse-OpenSSL/KeysInUse-OpenSSL.spec +++ b/SPECS/KeysInUse-OpenSSL/KeysInUse-OpenSSL.spec @@ -1,7 +1,7 @@ Summary: The KeysInUse Engine for OpenSSL allows the logging of private key usage through OpenSSL Name: KeysInUse-OpenSSL Version: 0.3.4 -Release: 6%{?dist} +Release: 7%{?dist} License: MIT Vendor: Microsoft Corporation Distribution: Mariner @@ -74,6 +74,9 @@ if [ -x %{_bindir}/keysinuseutil ]; then fi %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 0.3.4-7 +- Bump release to rebuild with go 1.22.7 + * Wed Jul 17 2024 Muhammad Falak R Wani - 0.3.4-6 - Drop requirement on a specific version of golang diff --git a/SPECS/LICENSES-AND-NOTICES/LICENSES-MAP.md b/SPECS/LICENSES-AND-NOTICES/LICENSES-MAP.md index aae573b205e..48acb35567a 100644 --- a/SPECS/LICENSES-AND-NOTICES/LICENSES-MAP.md +++ b/SPECS/LICENSES-AND-NOTICES/LICENSES-MAP.md @@ -5,7 +5,7 @@ The CBL-Mariner SPEC files originated from a variety of sources with varying lic | CentOS | [MIT](https://www.centos.org/legal/#licensing-policy) | crash-ptdump-command
delve
fstrm
nodejs-nodemon
rhnlib
rt-setup
rt-tests
rtctl
tuned | | Ceph source | [LGPL2.1](https://github.com/ceph/ceph/blob/master/COPYING-LGPL2.1) | ceph | | Debian | [MIT](https://opensource.org/licenses/MIT) | prometheus-process-exporter | -| Fedora | [Fedora MIT License Declaration](https://fedoraproject.org/wiki/Licensing:Main?rd=Licensing#License_of_Fedora_SPEC_Files) | a52dec
abseil-cpp
accountsservice
acpica-tools
acpid
adcli
adobe-mappings-cmap
adobe-mappings-pdf
advancecomp
adwaita-icon-theme
afflib
aide
alsa-firmware
alsa-plugins
amtk
amtterm
annobin
ansible-freeipa
archivemount
argparse-manpage
arptables
arpwatch
asio
aspell
aspell-en
at
at-spi2-atk
at-spi2-core
atf
atk
atop
attr
audiofile
augeas
authbind
authd
authselect
autoconf213
avahi
babeltrace
babeltrace2
babl
baekmuk-ttf-fonts
bats
bcache-tools
biosdevname
blosc
bluez
bmake
bogofilter
bolt
boom-boot
booth
botan2
breezy
brotli
buildah
busybox
bwidget
byacc
ca-certificates
cachefilesd
cairomm
calamares
capstone
catatonit
catch
catch1
cdrdao
celt051
cereal
certmonger
cfitsio
cgdcbxd
chan
CharLS
checkpolicy
checksec
chrony
cim-schema
cjkuni-uming-fonts
cjose
cldr-emoji-annotation
clucene
clutter
clutter-gst3
clutter-gtk
cmocka
cogl
collectd
colm
color-filesystem
colord
colorize
compat-lua
compiler-rt
conda
conmon
conntrack-tools
console-setup
container-exception-logger
containernetworking-plugins
convmv
corosync
corosync-qdevice
cpp-hocon
cppcheck
cpprest
cpptest
cpuid
criu
crypto-policies
cryptsetup
cscope
ctags
CUnit
cups
custodia
Cython
dbus-c++
dbus-python
dbxtool
dconf
dcraw
debootstrap
deltarpm
desktop-file-utils
device-mapper-persistent-data
dietlibc
diffstat
ding-libs
discount
distribution-gpg-keys
dleyna-connector-dbus
dleyna-core
dmraid
dnf
dnf-plugins-core
docbook-dtds
docbook-simple
docbook-slides
docbook-style-dsssl
docbook-utils
docbook2X
docbook5-schemas
docbook5-style-xsl
dogtail
dos2unix
dotconf
double-conversion
dovecot
dpdk
dpkg
driverctl
dropwatch
drpm
dumpet
dvd+rw-tools
dwarves
dwz
dyninst
ebtables
edac-utils
edk2
efax
efi-rpm-macros
egl-wayland
eglexternalplatform
elinks
enca
enchant
enchant2
enscript
environment-modules
evemu
execstack
exempi
exiv2
extra-cmake-modules
fabtests
facter
fakechroot
fakeroot
fapolicyd
fdk-aac-free
fdupes
fence-virt
fetchmail
fftw
filebench
fio
fipscheck
firewalld
fish
flac
flatbuffers
flite
fltk
fmt
fontawesome-fonts
fontpackages
fonts-rpm-macros
foomatic-db
freeglut
freeipmi
freeradius
freetds
freexl
fribidi
fros
frr
fsverity-utils
fuse-overlayfs
fuse-sshfs
fuse-zip
fuse3
future
fxload
gavl
gconf-editor
GConf2
gcovr
gcr
gdal
gdisk
gdk-pixbuf2
generic-logos
genwqe-tools
geoclue2
GeoIP
GeoIP-GeoLite-data
geolite2
geos
gfs2-utils
ghc-srpm-macros
giflib
gl-manpages
glew
glm
glog
glusterfs
gnome-desktop-testing
gnome-doc-utils
gnome-icon-theme
gnome-keyring
gnu-efi
go-rpm-macros
gom
google-api-python-client
google-crosextra-caladea-fonts
google-crosextra-carlito-fonts
google-guice
google-noto-cjk-fonts
google-noto-emoji-fonts
google-roboto-slab-fonts
gphoto2
gpm
gpsbabel
graphene
graphite2
graphviz
grubby
gsettings-desktop-schemas
gsl
gsm
gspell
gssdp
gssntlmssp
gstreamer1
gstreamer1-plugins-base
gtk-vnc
gtk2
gtk3
gtkspell
gupnp
gupnp-av
gupnp-dlna
gupnp-igd
hardening-check
hdf
hdf5
heimdal
help2man
hexedit
hicolor-icon-theme
hiera
highlight
hivex
hostname
hping3
hsakmt
htop
hunspell
hunspell-af
hunspell-ar
hunspell-as
hunspell-ast
hunspell-az
hunspell-be
hunspell-bg
hunspell-bn
hunspell-br
hunspell-ca
hunspell-cop
hunspell-csb
hunspell-cv
hunspell-cy
hunspell-da
hunspell-de
hunspell-dsb
hunspell-el
hunspell-en
hunspell-eo
hunspell-es
hunspell-et
hunspell-eu
hunspell-fa
hunspell-fj
hunspell-fo
hunspell-fr
hunspell-fur
hunspell-fy
hunspell-ga
hunspell-gd
hunspell-gl
hunspell-grc
hunspell-gu
hunspell-gv
hunspell-haw
hunspell-hi
hunspell-hil
hunspell-hr
hunspell-hsb
hunspell-ht
hunspell-hu
hunspell-hy
hunspell-ia
hunspell-id
hunspell-is
hunspell-it
hunspell-kk
hunspell-km
hunspell-kn
hunspell-ko
hunspell-ku
hunspell-ky
hunspell-la
hunspell-lb
hunspell-ln
hunspell-mai
hunspell-mg
hunspell-mi
hunspell-mk
hunspell-ml
hunspell-mn
hunspell-mos
hunspell-mr
hunspell-ms
hunspell-mt
hunspell-nds
hunspell-ne
hunspell-nl
hunspell-no
hunspell-nr
hunspell-nso
hunspell-ny
hunspell-om
hunspell-or
hunspell-pa
hunspell-pl
hunspell-pt
hunspell-quh
hunspell-ro
hunspell-ru
hunspell-rw
hunspell-se
hunspell-shs
hunspell-si
hunspell-sk
hunspell-sl
hunspell-smj
hunspell-so
hunspell-sq
hunspell-sr
hunspell-sv
hunspell-sw
hunspell-ta
hunspell-te
hunspell-tet
hunspell-th
hunspell-tk
hunspell-tl
hunspell-tn
hunspell-tpi
hunspell-ts
hunspell-uk
hunspell-uz
hunspell-ve
hunspell-vi
hunspell-wa
hunspell-xh
hunspell-yi
hwdata
hwloc
hyperscan
hyperv-daemons
hyphen
hyphen-as
hyphen-bg
hyphen-bn
hyphen-ca
hyphen-da
hyphen-de
hyphen-el
hyphen-es
hyphen-fa
hyphen-fo
hyphen-fr
hyphen-ga
hyphen-gl
hyphen-grc
hyphen-gu
hyphen-hi
hyphen-hsb
hyphen-hu
hyphen-ia
hyphen-id
hyphen-is
hyphen-it
hyphen-kn
hyphen-ku
hyphen-lt
hyphen-mi
hyphen-ml
hyphen-mn
hyphen-mr
hyphen-nl
hyphen-or
hyphen-pa
hyphen-pl
hyphen-pt
hyphen-ro
hyphen-ru
hyphen-sa
hyphen-sk
hyphen-sl
hyphen-sv
hyphen-ta
hyphen-te
hyphen-tk
hyphen-uk
ibus
ibus-chewing
ibus-hangul
ibus-kkc
ibus-libzhuyin
ibus-m17n
ibus-rawcode
ibus-sayura
ibus-table
ibus-table-chinese
icc-profiles-openicc
icon-naming-utils
icoutils
iftop
iio-sensor-proxy
ilmbase
im-chooser
imaptest
imsettings
indent
infinipath-psm
inih
iniparser
intel-cmt-cat
intel-ipsec-mb
ioping
IP2Location
ipa-pgothic-fonts
ipcalc
ipmitool
iprutils
iptraf-ng
iptstate
irssi
iscsi-initiator-utils
isns-utils
iso-codes
isomd5sum
iw
iwd
jabberpy
jasper
javapackages-bootstrap
javapackages-tools
jbigkit
jdom2
jemalloc
jfsutils
jimtcl
jose
js-jquery
jsoncpp
Judy
jurand
kata-containers
kde-filesystem
kde-settings
kexec-tools
keybinder3
keycloak-httpd-client-install
kf5
kf5-kconfig
kf5-kcoreaddons
kf5-ki18n
kf5-kwidgetsaddons
kpmcore
kronosnet
ksh
kyotocabinet
kyua
ladspa
lame
langtable
lapack
lasso
latencytop
lato-fonts
lcms2
lcov
ldns
leatherman
ledmon
lensfun
leveldb
lftp
libabw
libaec
libao
libappstream-glib
libart_lgpl
libasyncns
libatasmart
libavc1394
libblockdev
libbpf
libbsd
libburn
libbytesize
libcacard
libcanberra
libcdio
libcdio-paranoia
libcdr
libcgroup
libchewing
libcli
libcmis
libcmpiutil
libcomps
libcroco
libdaemon
libdap
libdatrie
libdazzle
libdbi
libdbi-drivers
libdbusmenu
libdc1394
libdeflate
libdmx
libdnf
libdrm
libdvdnav
libdvdread
libdwarf
libeasyfc
libecap
libecb
libell
libEMF
libeot
libepoxy
libepubgen
libesmtp
libetonyek
libev
libevdev
libewf
libexif
libexttextcat
libfabric
libfontenc
libfreehand
libftdi
libgadu
libgdither
libgee
libgee06
libgeotiff
libgexiv2
libgit2
libgit2-glib
libglade2
libglvnd
libgovirt
libgphoto2
libgsf
libgta
libguestfs
libgusb
libgxim
libgxps
libhangul
libhugetlbfs
libibcommon
libical
libICE
libicns
libid3tag
libIDL
libidn2
libiec61883
libieee1284
libimobiledevice
libindicator
libinput
libiodbc
libipt
libiptcdata
libiscsi
libisoburn
libisofs
libjcat
libkcapi
libkeepalive
libkkc
libkkc-data
libkml
liblangtag
libldb
libldm
liblerc
liblockfile
liblognorm
liblouis
liblqr-1
liblzf
libmad
libmediaart
libmicrohttpd
libmikmod
libmodman
libmodplug
libmodulemd1
libmpcdec
libmspub
libmtp
libmusicbrainz5
libmwaw
libnbd
libnet
libnetfilter_log
libnfs
libnotify
libntlm
libnumbertext
liboauth
libodfgen
libofa
libogg
liboggz
liboil
libomxil-bellagio
libopenraw
liboping
libosinfo
libotf
libotr
libpagemaker
libpaper
libpciaccess
libpeas
libpfm
libpinyin
libplist
libpmemobj-cpp
libpng12
libpng15
libproxy
libpsm2
libpwquality
libqb
libqxp
libraqm
LibRaw
libraw1394
libreport
libreswan
librevenge
librsvg2
librx
libsamplerate
libsass
libsecret
libsemanage
libsigc++20
libsigsegv
libslirp
libSM
libsmbios
libsmi
libsndfile
libsodium
libspiro
libsrtp
libssh
libstaroffice
libstemmer
libstoragemgmt
libtdb
libteam
libtevent
libthai
libtnc
libtomcrypt
libtommath
libtraceevent
libtranslit
libucil
libunicap
libuninameslist
liburing
libusbmuxd
libuser
libutempter
libvarlink
libverto
libvirt-dbus
libvirt-glib
libvirt-java
libvirt-python
libvisio
libvisual
libvoikko
libvorbis
libvpx
libwacom
libwnck3
libwpd
libwpe
libwpg
libwps
libwvstreams
libX11
libXau
libXaw
libxcb
libXcomposite
libxcrypt
libXcursor
libXdamage
libXdmcp
libXext
libxfce4util
libXfixes
libXfont2
libXft
libXi
libXinerama
libxkbcommon
libxkbfile
libxklavier
libxmlb
libXmu
libXpm
libXrandr
libXrender
libXres
libXScrnSaver
libxshmfence
libXt
libXtst
libXv
libXxf86vm
libyami
libyang
libyubikey
libzip
libzmf
lilv
linuxconsoletools
linuxptp
lksctp-tools
lldpd
lockdev
logwatch
lpsolve
lrzsz
lua
lua-expat
lua-filesystem
lua-json
lua-lpeg
lua-lunit
lua-rpm-macros
lua-term
luajit
luksmeta
lutok
lv2
lzip
lzop
m17n-db
m17n-lib
mac-robber
mailcap
mailx
malaga
malaga-suomi-voikko
mallard-rng
man-pages-cs
man-pages-es
man-pages-it
man-pages-ja
man-pages-ko
man-pages-pl
man-pages-ru
man-pages-zh-CN
mariadb-connector-c
mariadb-connector-odbc
marisa
maven-compiler-plugin
maven-jar-plugin
maven-resolver
maven-resources-plugin
maven-surefire
maven-wagon
mcelog
mcpp
mcstrans
mdadm
mdds
meanwhile
mecab
mecab-ipadic
media-player-info
memcached
memkind
mesa
mesa-libGLU
metis
microcode_ctl
microdnf
minicom
minizip
mksh
mobile-broadband-provider-info
mock
mock-core-configs
mod_auth_gssapi
mod_auth_mellon
mod_auth_openidc
mod_authnz_pam
mod_fcgid
mod_http2
mod_intercept_form_submit
mod_lookup_identity
mod_md
mod_security
mod_security_crs
mod_wsgi
mokutil
moreutils
mosh
mpage
mrtg
mstflint
mt-st
mtdev
mtools
mtr
mtx
multilib-rpm-config
munge
mutt
mythes
mythes-bg
mythes-ca
mythes-cs
mythes-da
mythes-de
mythes-el
mythes-en
mythes-eo
mythes-es
mythes-fr
mythes-ga
mythes-hu
mythes-mi
mythes-ne
mythes-nl
mythes-pl
mythes-pt
mythes-ro
mythes-ru
mythes-sk
mythes-sl
mythes-sv
mythes-uk
nbd
nbdkit
neon
netavark
netcdf
netcf
netlabel_tools
netpbm
netsniff-ng
nfs4-acl-tools
nftables
nilfs-utils
nkf
nload
nlopt
nodejs-packaging
nss-mdns
nss-pam-ldapd
nss_nis
nss_wrapper
ntfs-3g
ntfs-3g-system-compression
numad
numatop
numpy
nvmetcli
nvml
oath-toolkit
ocaml
ocaml-alcotest
ocaml-astring
ocaml-base
ocaml-bigarray-compat
ocaml-bisect-ppx
ocaml-calendar
ocaml-camlp5
ocaml-camomile
ocaml-cinaps
ocaml-cmdliner
ocaml-compiler-libs-janestreet
ocaml-cppo
ocaml-csexp
ocaml-csv
ocaml-ctypes
ocaml-curses
ocaml-dune
ocaml-extlib
ocaml-fileutils
ocaml-findlib
ocaml-fmt
ocaml-fpath
ocaml-gettext
ocaml-integers
ocaml-libvirt
ocaml-luv
ocaml-lwt
ocaml-markup
ocaml-migrate-parsetree
ocaml-mmap
ocaml-num
ocaml-ocamlbuild
ocaml-ocplib-endian
ocaml-ounit
ocaml-parsexp
ocaml-ppx-derivers
ocaml-ppxlib
ocaml-re
ocaml-react
ocaml-result
ocaml-seq
ocaml-sexplib
ocaml-sexplib0
ocaml-stdio
ocaml-topkg
ocaml-tyxml
ocaml-uuidm
ocaml-uutf
ocaml-xml-light
ocaml-zarith
ocl-icd
oddjob
ogdi
omping
opa
opal
open-vm-tools
openblas
opencc
opencl-filesystem
opencl-headers
opencryptoki
opencsd
opendnssec
OpenEXR
openjade
openjpeg2
openmpi
openobex
openoffice-lv
openrdate
opensc
openslp
opensm
opensp
openssl
openssl-ibmpkcs11
openssl-pkcs11
openwsman
optipng
opus
opusfile
orangefs
ORBit2
orc
os-prober
osinfo-db
osinfo-db-tools
overpass-fonts
p11-kit
p7zip
pacemaker
pacrunner
pakchois
pam_krb5
pam_wrapper
papi
paps
parallel
patchelf
patchutils
pbzip2
pcp
pcsc-lite
pcsc-lite-ccid
PEGTL
perl
perl-Algorithm-C3
perl-Algorithm-Diff
perl-Alien-Build
perl-Alien-pkgconf
perl-AnyEvent
perl-AnyEvent-AIO
perl-AnyEvent-BDB
perl-App-cpanminus
perl-App-FatPacker
perl-AppConfig
perl-Archive-Extract
perl-Archive-Zip
perl-Authen-SASL
perl-B-Debug
perl-B-Hooks-EndOfScope
perl-B-Hooks-OP-Check
perl-B-Keywords
perl-B-Lint
perl-bareword-filehandles
perl-BDB
perl-Bit-Vector
perl-boolean
perl-Browser-Open
perl-BSD-Resource
perl-Business-ISBN
perl-Business-ISBN-Data
perl-Bytes-Random-Secure
perl-Capture-Tiny
perl-Carp-Clan
perl-CBOR-XS
perl-Class-Accessor
perl-Class-C3
perl-Class-C3-XS
perl-Class-Data-Inheritable
perl-Class-Factory-Util
perl-Class-Inspector
perl-Class-ISA
perl-Class-Load
perl-Class-Load-XS
perl-Class-Method-Modifiers
perl-Class-Singleton
perl-Class-Tiny
perl-Class-XSAccessor
perl-Clone
perl-Color-ANSI-Util
perl-Color-RGB-Util
perl-ColorThemeBase-Static
perl-ColorThemeRole-ANSI
perl-ColorThemes-Standard
perl-ColorThemeUtil-ANSI
perl-Compress-Bzip2
perl-Compress-LZF
perl-Compress-Raw-Lzma
perl-Config-AutoConf
perl-Config-INI
perl-Config-INI-Reader-Multiline
perl-Config-IniFiles
perl-Config-Simple
perl-Config-Tiny
perl-Const-Fast
perl-Convert-ASN1
perl-Convert-Bencode
perl-Coro
perl-Coro-Multicore
perl-CPAN-Changes
perl-CPAN-DistnameInfo
perl-CPAN-Meta-Check
perl-Cpanel-JSON-XS
perl-Crypt-CBC
perl-Crypt-DES
perl-Crypt-IDEA
perl-Crypt-OpenSSL-Bignum
perl-Crypt-OpenSSL-Guess
perl-Crypt-OpenSSL-Random
perl-Crypt-OpenSSL-RSA
perl-Crypt-PasswdMD5
perl-Crypt-Random-Seed
perl-CSS-Tiny
perl-Data-Dump
perl-Data-Munge
perl-Data-OptList
perl-Data-Peek
perl-Data-Section
perl-Data-UUID
perl-Date-Calc
perl-Date-ISO8601
perl-Date-Manip
perl-DateTime
perl-DateTime-Format-Builder
perl-DateTime-Format-DateParse
perl-DateTime-Format-HTTP
perl-DateTime-Format-IBeat
perl-DateTime-Format-ISO8601
perl-DateTime-Format-Mail
perl-DateTime-Format-Strptime
perl-DateTime-Locale
perl-DateTime-TimeZone
perl-DateTime-TimeZone-SystemV
perl-DateTime-TimeZone-Tzfile
perl-DBD-MySQL
perl-Devel-CallChecker
perl-Devel-Caller
perl-Devel-CheckBin
perl-Devel-CheckLib
perl-Devel-Cycle
perl-Devel-EnforceEncapsulation
perl-Devel-GlobalDestruction
perl-Devel-GlobalDestruction-XS
perl-Devel-Hide
perl-Devel-Leak
perl-Devel-LexAlias
perl-Devel-Size
perl-Devel-StackTrace
perl-Devel-Symdump
perl-Digest-BubbleBabble
perl-Digest-CRC
perl-Digest-HMAC
perl-Digest-SHA1
perl-Dist-CheckConflicts
perl-DynaLoader-Functions
perl-Email-Address
perl-Email-Date-Format
perl-Encode-Detect
perl-Encode-EUCJPASCII
perl-Encode-IMAPUTF7
perl-Encode-Locale
perl-Env-ShellWords
perl-Error
perl-EV
perl-Eval-Closure
perl-Event
perl-Exception-Class
perl-Expect
perl-ExtUtils-Config
perl-ExtUtils-Depends
perl-ExtUtils-Helpers
perl-ExtUtils-InstallPaths
perl-ExtUtils-PkgConfig
perl-FCGI
perl-Fedora-VSP
perl-FFI-CheckLib
perl-File-BaseDir
perl-File-BOM
perl-File-chdir
perl-File-CheckTree
perl-File-Copy-Recursive
perl-File-DesktopEntry
perl-File-Find-Object
perl-File-Find-Object-Rule
perl-File-Find-Rule
perl-File-Find-Rule-Perl
perl-File-Inplace
perl-File-Listing
perl-File-MimeInfo
perl-File-pushd
perl-File-ReadBackwards
perl-File-Remove
perl-File-ShareDir
perl-File-ShareDir-Install
perl-File-Slurp
perl-File-Slurp-Tiny
perl-File-Slurper
perl-File-Type
perl-Font-TTF
perl-FreezeThaw
perl-GD
perl-GD-Barcode
perl-generators
perl-Getopt-ArgvFile
perl-gettext
perl-Graphics-ColorNamesLite-WWW
perl-GSSAPI
perl-Guard
perl-Hook-LexWrap
perl-HTML-Parser
perl-HTML-Tagset
perl-HTML-Tree
perl-HTTP-Cookies
perl-HTTP-Daemon
perl-HTTP-Date
perl-HTTP-Message
perl-HTTP-Negotiate
perl-Image-Base
perl-Image-Info
perl-Image-Xbm
perl-Image-Xpm
perl-Import-Into
perl-Importer
perl-inc-latest
perl-indirect
perl-Inline-Files
perl-IO-AIO
perl-IO-All
perl-IO-CaptureOutput
perl-IO-Compress-Lzma
perl-IO-HTML
perl-IO-Multiplex
perl-IO-SessionData
perl-IO-Socket-INET6
perl-IO-String
perl-IO-stringy
perl-IO-Tty
perl-IPC-Run
perl-IPC-Run3
perl-IPC-System-Simple
perl-JSON
perl-JSON-Color
perl-JSON-MaybeXS
perl-LDAP
perl-libnet
perl-libwww-perl
perl-libxml-perl
perl-Lingua-EN-Inflect
perl-List-MoreUtils-XS
perl-local-lib
perl-Locale-Codes
perl-Locale-Maketext-Gettext
perl-Locale-Msgfmt
perl-Locale-PO
perl-Log-Message
perl-Log-Message-Simple
perl-LWP-MediaTypes
perl-LWP-Protocol-https
perl-Mail-AuthenticationResults
perl-Mail-DKIM
perl-Mail-IMAPTalk
perl-Mail-SPF
perl-MailTools
perl-Math-Int64
perl-Math-Random-ISAAC
perl-MIME-Charset
perl-MIME-Lite
perl-MIME-Types
perl-Mixin-Linewise
perl-MLDBM
perl-Mock-Config
perl-Module-Build-Tiny
perl-Module-CPANfile
perl-Module-Implementation
perl-Module-Install-AuthorRequires
perl-Module-Install-AuthorTests
perl-Module-Install-AutoLicense
perl-Module-Install-GithubMeta
perl-Module-Install-ManifestSkip
perl-Module-Install-ReadmeFromPod
perl-Module-Install-ReadmeMarkdownFromPod
perl-Module-Install-Repository
perl-Module-Install-TestBase
perl-Module-Load-Util
perl-Module-Manifest
perl-Module-Manifest-Skip
perl-Module-Package
perl-Module-Package-Au
perl-Module-Pluggable
perl-Module-Runtime
perl-Module-Signature
perl-Mojolicious
perl-Moo
perl-Mozilla-CA
perl-Mozilla-LDAP
perl-MRO-Compat
perl-multidimensional
perl-namespace-autoclean
perl-namespace-clean
perl-Net-CIDR-Lite
perl-Net-Daemon
perl-Net-DNS
perl-Net-DNS-Resolver-Mock
perl-Net-DNS-Resolver-Programmable
perl-Net-HTTP
perl-Net-IMAP-Simple
perl-Net-IMAP-Simple-SSL
perl-Net-IP
perl-Net-LibIDN2
perl-Net-Patricia
perl-Net-SMTP-SSL
perl-Net-SNMP
perl-Net-Telnet
perl-Newt
perl-NNTPClient
perl-NTLM
perl-Number-Compare
perl-Object-Deadly
perl-Object-HashBase
perl-Package-Anon
perl-Package-Constants
perl-Package-DeprecationManager
perl-Package-Generator
perl-Package-Stash
perl-Package-Stash-XS
perl-PadWalker
perl-Paper-Specs
perl-PAR-Dist
perl-Parallel-Iterator
perl-Params-Classify
perl-Params-Util
perl-Params-Validate
perl-Params-ValidationCompiler
perl-Parse-PMFile
perl-Parse-RecDescent
perl-Parse-Yapp
perl-Path-Tiny
perl-Perl-Critic
perl-Perl-Critic-More
perl-Perl-Destruct-Level
perl-Perl-MinimumVersion
perl-Perl4-CoreLibs
perl-PerlIO-gzip
perl-PerlIO-utf8_strict
perl-PkgConfig-LibPkgConf
perl-Pod-Coverage
perl-Pod-Coverage-TrustPod
perl-Pod-Escapes
perl-Pod-Eventual
perl-Pod-LaTeX
perl-Pod-Markdown
perl-Pod-Parser
perl-Pod-Plainer
perl-Pod-POM
perl-Pod-Spell
perl-PPI
perl-PPI-HTML
perl-PPIx-QuoteLike
perl-PPIx-Regexp
perl-PPIx-Utilities
perl-prefork
perl-Probe-Perl
perl-Razor-Agent
perl-Readonly
perl-Readonly-XS
perl-Ref-Util
perl-Ref-Util-XS
perl-Regexp-Pattern-Perl
perl-Return-MultiLevel
perl-Role-Tiny
perl-Scope-Guard
perl-Scope-Upper
perl-SGMLSpm
perl-SNMP_Session
perl-Socket6
perl-Software-License
perl-Sort-Versions
perl-Specio
perl-Spiffy
perl-strictures
perl-String-CRC32
perl-String-Format
perl-String-ShellQuote
perl-String-Similarity
perl-Sub-Exporter
perl-Sub-Exporter-Progressive
perl-Sub-Identify
perl-Sub-Info
perl-Sub-Install
perl-Sub-Name
perl-Sub-Quote
perl-Sub-Uplevel
perl-SUPER
perl-Switch
perl-Syntax-Highlight-Engine-Kate
perl-Sys-CPU
perl-Sys-MemInfo
perl-Sys-Virt
perl-Taint-Runtime
perl-Task-Weaken
perl-Term-Size-Any
perl-Term-Size-Perl
perl-Term-Table
perl-Term-UI
perl-TermReadKey
perl-Test-Base
perl-Test-ClassAPI
perl-Test-CPAN-Meta
perl-Test-CPAN-Meta-JSON
perl-Test-Deep
perl-Test-Differences
perl-Test-DistManifest
perl-Test-Distribution
perl-Test-EOL
perl-Test-Exception
perl-Test-Exit
perl-Test-FailWarnings
perl-Test-Fatal
perl-Test-File
perl-Test-File-ShareDir
perl-Test-Harness
perl-Test-HasVersion
perl-Test-InDistDir
perl-Test-Inter
perl-Test-LeakTrace
perl-Test-LongString
perl-Test-Manifest
perl-Test-Memory-Cycle
perl-Test-MinimumVersion
perl-Test-MockObject
perl-Test-MockRandom
perl-Test-Needs
perl-Test-NoTabs
perl-Test-NoWarnings
perl-Test-Object
perl-Test-Output
perl-Test-Pod
perl-Test-Pod-Coverage
perl-Test-Portability-Files
perl-Test-Requires
perl-Test-RequiresInternet
perl-Test-Script
perl-Test-Simple
perl-Test-SubCalls
perl-Test-Synopsis
perl-Test-Taint
perl-Test-TrailingSpace
perl-Test-utf8
perl-Test-Vars
perl-Test-Warn
perl-Test-Without-Module
perl-Test2-Plugin-NoWarnings
perl-Test2-Suite
perl-Test2-Tools-Explain
perl-Text-CharWidth
perl-Text-CSV_XS
perl-Text-Diff
perl-Text-Glob
perl-Text-Iconv
perl-Text-Soundex
perl-Text-Unidecode
perl-Text-WrapI18N
perl-Tie-IxHash
perl-Time-Duration
perl-TimeDate
perl-Tree-DAG_Node
perl-Unicode-EastAsianWidth
perl-Unicode-LineBreak
perl-Unicode-Map8
perl-Unicode-String
perl-Unicode-UTF8
perl-UNIVERSAL-can
perl-UNIVERSAL-isa
perl-Unix-Syslog
perl-URI
perl-Variable-Magic
perl-Version-Requirements
perl-WWW-RobotRules
perl-XML-Catalog
perl-XML-DOM
perl-XML-Dumper
perl-XML-Filter-BufferText
perl-XML-Generator
perl-XML-Grove
perl-XML-Handler-YAWriter
perl-XML-LibXML
perl-XML-LibXSLT
perl-XML-NamespaceSupport
perl-XML-Parser-Lite
perl-XML-RegExp
perl-XML-SAX
perl-XML-SAX-Base
perl-XML-SAX-Writer
perl-XML-Simple
perl-XML-TokeParser
perl-XML-TreeBuilder
perl-XML-Twig
perl-XML-Writer
perl-XML-XPath
perl-XML-XPathEngine
perl-XString
perl-YAML-LibYAML
perl-YAML-PP
perl-YAML-Syck
perltidy
pesign
phodav
php
php-pear
php-pecl-zip
physfs
picosat
pinfo
pipewire
pixman
pkcs11-helper
pkgconf
plexus-cipher
plexus-containers
plexus-sec-dispatcher
plotutils
pmdk-convert
pmix
pngcrush
pngnq
po4a
podman
poetry
policycoreutils
polkit-pkla-compat
portreserve
postfix
potrace
powertop
ppp
pps-tools
pptp
priv_wrapper
procmail
prometheus
prometheus-node-exporter
ps_mem
psacct
psutils
ptlib
publicsuffix-list
pugixml
pulseaudio
puppet
pwgen
pyatspi
pybind11
pycairo
pyelftools
pyflakes
pygobject3
PyGreSQL
pykickstart
pylint
pyparted
pyproject-rpm-macros
pyserial
python-absl-py
python-aiodns
python-aiohttp
python-alsa
python-argcomplete
python-astroid
python-astunparse
python-async-generator
python-augeas
python-azure-sdk
python-beautifulsoup4
python-betamax
python-blinker
python-blivet
python-cached_property
python-charset-normalizer
python-cheetah
python-click
python-cmd2
python-colorama
python-CommonMark
python-conda-package-handling
python-configshell
python-cpuinfo
python-cups
python-curio
python-cytoolz
python-d2to1
python-dbus-client-gen
python-dbus-python-client-gen
python-dbus-signature-pyparsing
python-dbusmock
python-ddt
python-debtcollector
python-decorator
python-distlib
python-dmidecode
python-dns
python-dtopt
python-dulwich
python-enchant
python-entrypoints
python-ethtool
python-evdev
python-extras
python-faker
python-fasteners
python-fields
python-filelock
python-fixtures
python-flake8
python-flask
python-flit
python-flit-core
python-fluidity-sm
python-frozendict
python-funcsigs
python-gast
python-genshi
python-google-auth
python-google-auth-oauthlib
python-greenlet
python-gssapi
python-h5py
python-hs-dbus-signature
python-html5lib
python-httplib2
python-humanize
python-hwdata
python-importlib-metadata
python-inotify
python-into-dbus-python
python-IPy
python-iso8601
python-isodate
python-isort
python-itsdangerous
python-junit-xml
python-justbases
python-justbytes
python-jwcrypto
python-jwt
python-kdcproxy
python-kerberos
python-kmod
python-kubernetes
python-lazy-object-proxy
python-ldap
python-linux-procfs
python-lit
python-markdown
python-mccabe
python-memcached
python-mimeparse
python-mock
python-monotonic
python-more-itertools
python-mpmath
python-msal
python-msrestazure
python-mutagen
python-networkx
python-nose2
python-ntlm-auth
python-oauth2client
python-openpyxl
python-openstackdocstheme
python-oslo-i18n
python-oslo-sphinx
python-paramiko
python-pefile
python-pexpect
python-pkgconfig
python-platformdirs
python-pluggy
python-podman-api
python-process-tests
python-productmd
python-ptyprocess
python-pycares
python-pycosat
python-pydbus
python-pymongo
python-PyMySQL
python-pyperclip
python-pyroute2
python-pyrsistent
python-pysocks
python-pytest-benchmark
python-pytest-cov
python-pytest-expect
python-pytest-flake8
python-pytest-forked
python-pytest-mock
python-pytest-relaxed
python-pytest-runner
python-pytest-subtests
python-pytest-timeout
python-pytest-xdist
python-pytoml
python-pyudev
python-pywbem
python-qrcode
python-rdflib
python-recommonmark
python-redis
python-requests-file
python-requests-ftp
python-requests-kerberos
python-requests-mock
python-requests-oauthlib
python-requests-toolbelt
python-requests_ntlm
python-responses
python-retrying
python-rfc3986
python-rpm-generators
python-rpmfluff
python-rtslib
python-ruamel-yaml
python-ruamel-yaml-clib
python-s3transfer
python-schedutils
python-semantic_version
python-should_dsl
python-simpleline
python-slip
python-sniffio
python-soupsieve
python-sphinx
python-sphinx-epytext
python-sphinx-theme-py3doc-enhanced
python-sphinx_rtd_theme
python-sphinxcontrib-apidoc
python-sphinxcontrib-applehelp
python-sphinxcontrib-devhelp
python-sphinxcontrib-htmlhelp
python-sphinxcontrib-httpdomain
python-sphinxcontrib-jsmath
python-sphinxcontrib-qthelp
python-sphinxcontrib-serializinghtml
python-sqlalchemy
python-suds
python-systemd
python-tempita
python-templated-dictionary
python-termcolor
python-testpath
python-testresources
python-testscenarios
python-testtools
python-tidy
python-toml
python-tomli
python-toolz
python-tornado
python-tox
python-tox-current-env
python-tqdm
python-trio
python-typing-extensions
python-uamqp
python-unittest2
python-uritemplate
python-urwid
python-varlink
python-virt-firmware
python-voluptuous
python-waitress
python-webencodings
python-webtest
python-wheel
python-whoosh
python-winrm
python-wrapt
python-xmltodict
python-yubico
python-zipp
python-zmq
python3-mallard-ducktype
python3-pytest-asyncio
python3-typed_ast
pyusb
pywbem
pyxattr
qemu
qhull
qpdf
qperf
qr-code-generator
qt5-qtbase
qt5-qtconnectivity
qt5-qtdeclarative
qt5-qtsensors
qt5-qtserialport
qt5-qtsvg
qt5-qttools
qt5-rpm-macros
quagga
quota
quotatool
radvd
ragel
raptor2
rarian
rasdaemon
rasqal
rcs
rdist
rdma-core
re2
re2c
realmd
rear
recode
redland
resource-agents
rest
rhash
rlwrap
rp-pppoe
rpm-mpi-hooks
rpmdevtools
rpmlint
rtkit
rtl-sdr
ruby-augeas
rubygem-bson
rubygem-coderay
rubygem-diff-lcs
rubygem-flexmock
rubygem-hpricot
rubygem-introspection
rubygem-liquid
rubygem-maruku
rubygem-metaclass
rubygem-mongo
rubygem-mustache
rubygem-mysql2
rubygem-pkg-config
rubygem-rake
rubygem-rake-compiler
rubygem-ronn
rubygem-rouge
rubygem-rspec
rubygem-rspec-expectations
rubygem-rspec-mocks
rubygem-rspec-support
rubygem-thread_order
rusers
rust-cbindgen
samba
sanlock
sassist
satyr
sbc
sblim-cim-client2
sblim-cmpi-base
sblim-cmpi-devel
sblim-cmpi-fsvol
sblim-cmpi-network
sblim-cmpi-nfsv3
sblim-cmpi-nfsv4
sblim-cmpi-params
sblim-cmpi-sysfs
sblim-cmpi-syslog
sblim-indication_helper
sblim-sfcb
sblim-sfcc
sblim-sfcCommon
sblim-testsuite
sblim-wbemcli
scl-utils
scotch
screen
scrub
SDL
SDL2
SDL_sound
sdparm
seabios
secilc
selinux-policy
sendmail
serd
setools
setserial
setuptool
sgabios
sgml-common
sgpio
shared-mime-info
sharutils
sip
sisu
skkdic
sleuthkit
slirp4netns
smartmontools
smc-tools
socket_wrapper
softhsm
sombok
sord
sos
sound-theme-freedesktop
soundtouch
sox
soxr
sparsehash
spausedd
speex
speexdsp
spice-protocol
spice-vdagent
spirv-headers
spirv-tools
splix
squashfs-tools
squid
sratom
sscg
star
startup-notification
stunnel
subscription-manager
suitesparse
SuperLU
supermin
switcheroo-control
symlinks
sympy
sysfsutils
systemd-bootchart
t1lib
t1utils
taglib
tang
targetcli
tbb
tcl-pgtcl
tclx
teckit
telnet
tidy
time
tini
tinycdb
tix
tk
tlog
tmpwatch
tn5250
tofrodos
tokyocabinet
tpm-quote-tools
tpm-tools
tss2
ttembed
ttmkfdir
tuna
twolame
uchardet
uclibc-ng
ucpp
ucs-miscfixed-fonts
ucx
udftools
udica
udisks2
uglify-js
uid_wrapper
unicode-emoji
unicode-ucd
unique3
units
upower
uriparser
urlview
usb_modeswitch
usb_modeswitch-data
usbguard
usbip
usbmuxd
usbredir
usermode
ustr
uthash
uuid
uw-imap
v4l-utils
vhostmd
vino
virglrenderer
virt-p2v
virt-top
virt-what
virt-who
virtiofsd
vitess
vmem
volume_key
vorbis-tools
vte291
vulkan-headers
vulkan-loader
watchdog
wavpack
wayland
wayland-protocols
web-assets
webrtc-audio-processing
websocketpp
whois
wireguard-tools
wireless-regdb
wireshark
woff2
wordnet
words
wpebackend-fdo
wsmancli
wvdial
x3270
xapian-core
Xaw3d
xcb-proto
xcb-util
xcb-util-image
xcb-util-keysyms
xcb-util-renderutil
xcb-util-wm
xdelta
xdg-dbus-proxy
xdg-utils
xerces-c
xfconf
xfsdump
xhtml1-dtds
xkeyboard-config
xmlstarlet
xmltoman
xmvn
xorg-x11-apps
xorg-x11-drv-libinput
xorg-x11-font-utils
xorg-x11-fonts
xorg-x11-proto-devel
xorg-x11-server
xorg-x11-server-utils
xorg-x11-util-macros
xorg-x11-utils
xorg-x11-xauth
xorg-x11-xbitmaps
xorg-x11-xinit
xorg-x11-xkb-utils
xorg-x11-xtrans-devel
xrestop
xterm
xxhash
yajl
yaml-cpp
yasm
yelp-tools
yelp-xsl
ykclient
yp-tools
ypbind
ypserv
z3
zenity
zerofree
zfs-fuse
zipper
zopfli
zziplib | +| Fedora | [Fedora MIT License Declaration](https://fedoraproject.org/wiki/Licensing:Main?rd=Licensing#License_of_Fedora_SPEC_Files) | a52dec
abseil-cpp
accountsservice
acpica-tools
acpid
adcli
adobe-mappings-cmap
adobe-mappings-pdf
advancecomp
adwaita-icon-theme
afflib
aide
alsa-firmware
alsa-plugins
amtk
amtterm
annobin
ansible-freeipa
archivemount
argparse-manpage
arptables
arpwatch
asio
aspell
aspell-en
at
at-spi2-atk
at-spi2-core
atf
atk
atop
attr
audiofile
augeas
authbind
authd
authselect
autoconf213
avahi
babeltrace
babeltrace2
babl
baekmuk-ttf-fonts
bats
bcache-tools
biosdevname
blosc
bluez
bmake
bogofilter
bolt
boom-boot
booth
botan2
breezy
brotli
buildah
busybox
bwidget
byacc
ca-certificates
cachefilesd
cairomm
calamares
capstone
catatonit
catch
catch1
cdrdao
celt051
cereal
certmonger
cfitsio
cgdcbxd
chan
CharLS
checkpolicy
checksec
chrony
cim-schema
cjkuni-uming-fonts
cjose
cldr-emoji-annotation
clucene
clutter
clutter-gst3
clutter-gtk
cmocka
cogl
collectd
colm
color-filesystem
colord
colorize
compat-lua
compiler-rt
conda
conmon
conntrack-tools
console-setup
container-exception-logger
containernetworking-plugins
convmv
corosync
corosync-qdevice
cpp-hocon
cppcheck
cpprest
cpptest
cpuid
criu
crypto-policies
cryptsetup
cscope
ctags
CUnit
cups
custodia
Cython
dbus-c++
dbus-python
dbxtool
dconf
dcraw
debootstrap
deltarpm
desktop-file-utils
device-mapper-persistent-data
dietlibc
diffstat
ding-libs
discount
distribution-gpg-keys
dleyna-connector-dbus
dleyna-core
dmraid
dnf
dnf-plugins-core
docbook-dtds
docbook-simple
docbook-slides
docbook-style-dsssl
docbook-utils
docbook2X
docbook5-schemas
docbook5-style-xsl
dogtail
dos2unix
dotconf
double-conversion
dovecot
dpdk
dpkg
driverctl
dropwatch
drpm
dumpet
dvd+rw-tools
dwarves
dwz
dyninst
ebtables
edac-utils
edk2
efax
efi-rpm-macros
egl-wayland
eglexternalplatform
elinks
enca
enchant
enchant2
enscript
environment-modules
evemu
execstack
exempi
exiv2
extra-cmake-modules
fabtests
facter
fakechroot
fakeroot
fapolicyd
fdk-aac-free
fdupes
fence-virt
fetchmail
fftw
filebench
fio
fipscheck
firewalld
fish
flac
flatbuffers
flite
fltk
fmt
fontawesome-fonts
fontpackages
fonts-rpm-macros
foomatic-db
freeglut
freeipmi
freeradius
freetds
freexl
fribidi
fros
frr
fsverity-utils
fuse-overlayfs
fuse-sshfs
fuse-zip
fuse3
future
fxload
gavl
gconf-editor
GConf2
gcovr
gcr
gdal
gdisk
gdk-pixbuf2
generic-logos
genwqe-tools
geoclue2
GeoIP
GeoIP-GeoLite-data
geolite2
geos
gfs2-utils
ghc-srpm-macros
giflib
gl-manpages
glew
glm
glog
glusterfs
gnome-desktop-testing
gnome-doc-utils
gnome-icon-theme
gnome-keyring
gnu-efi
go-rpm-macros
gom
google-api-python-client
google-crosextra-caladea-fonts
google-crosextra-carlito-fonts
google-guice
google-noto-cjk-fonts
google-noto-emoji-fonts
google-roboto-slab-fonts
gphoto2
gpm
gpsbabel
graphene
graphite2
graphviz
grubby
gsettings-desktop-schemas
gsl
gsm
gspell
gssdp
gssntlmssp
gstreamer1
gstreamer1-plugins-base
gtk-vnc
gtk2
gtk3
gtkspell
gupnp
gupnp-av
gupnp-dlna
gupnp-igd
hardening-check
hdf
hdf5
heimdal
help2man
hexedit
hicolor-icon-theme
hiera
highlight
hivex
hostname
hping3
hsakmt
htop
hunspell
hunspell-af
hunspell-ar
hunspell-as
hunspell-ast
hunspell-az
hunspell-be
hunspell-bg
hunspell-bn
hunspell-br
hunspell-ca
hunspell-cop
hunspell-csb
hunspell-cv
hunspell-cy
hunspell-da
hunspell-de
hunspell-dsb
hunspell-el
hunspell-en
hunspell-eo
hunspell-es
hunspell-et
hunspell-eu
hunspell-fa
hunspell-fj
hunspell-fo
hunspell-fr
hunspell-fur
hunspell-fy
hunspell-ga
hunspell-gd
hunspell-gl
hunspell-grc
hunspell-gu
hunspell-gv
hunspell-haw
hunspell-hi
hunspell-hil
hunspell-hr
hunspell-hsb
hunspell-ht
hunspell-hu
hunspell-hy
hunspell-ia
hunspell-id
hunspell-is
hunspell-it
hunspell-kk
hunspell-km
hunspell-kn
hunspell-ko
hunspell-ku
hunspell-ky
hunspell-la
hunspell-lb
hunspell-ln
hunspell-mai
hunspell-mg
hunspell-mi
hunspell-mk
hunspell-ml
hunspell-mn
hunspell-mos
hunspell-mr
hunspell-ms
hunspell-mt
hunspell-nds
hunspell-ne
hunspell-nl
hunspell-no
hunspell-nr
hunspell-nso
hunspell-ny
hunspell-om
hunspell-or
hunspell-pa
hunspell-pl
hunspell-pt
hunspell-quh
hunspell-ro
hunspell-ru
hunspell-rw
hunspell-se
hunspell-shs
hunspell-si
hunspell-sk
hunspell-sl
hunspell-smj
hunspell-so
hunspell-sq
hunspell-sr
hunspell-sv
hunspell-sw
hunspell-ta
hunspell-te
hunspell-tet
hunspell-th
hunspell-tk
hunspell-tl
hunspell-tn
hunspell-tpi
hunspell-ts
hunspell-uk
hunspell-uz
hunspell-ve
hunspell-vi
hunspell-wa
hunspell-xh
hunspell-yi
hwdata
hwloc
hyperscan
hyperv-daemons
hyphen
hyphen-as
hyphen-bg
hyphen-bn
hyphen-ca
hyphen-da
hyphen-de
hyphen-el
hyphen-es
hyphen-fa
hyphen-fo
hyphen-fr
hyphen-ga
hyphen-gl
hyphen-grc
hyphen-gu
hyphen-hi
hyphen-hsb
hyphen-hu
hyphen-ia
hyphen-id
hyphen-is
hyphen-it
hyphen-kn
hyphen-ku
hyphen-lt
hyphen-mi
hyphen-ml
hyphen-mn
hyphen-mr
hyphen-nl
hyphen-or
hyphen-pa
hyphen-pl
hyphen-pt
hyphen-ro
hyphen-ru
hyphen-sa
hyphen-sk
hyphen-sl
hyphen-sv
hyphen-ta
hyphen-te
hyphen-tk
hyphen-uk
ibus
ibus-chewing
ibus-hangul
ibus-kkc
ibus-libzhuyin
ibus-m17n
ibus-rawcode
ibus-sayura
ibus-table
ibus-table-chinese
icc-profiles-openicc
icon-naming-utils
icoutils
iftop
iio-sensor-proxy
ilmbase
im-chooser
imaptest
imsettings
indent
infinipath-psm
inih
iniparser
intel-cmt-cat
intel-ipsec-mb
ioping
IP2Location
ipa-pgothic-fonts
ipcalc
ipmitool
iprutils
iptraf-ng
iptstate
irssi
iscsi-initiator-utils
isns-utils
iso-codes
isomd5sum
iw
iwd
jabberpy
jasper
javapackages-bootstrap
javapackages-tools
jbigkit
jdom2
jemalloc
jfsutils
jimtcl
jose
js-jquery
jsoncpp
Judy
jurand
kata-containers
kde-filesystem
kde-settings
kexec-tools
keybinder3
keycloak-httpd-client-install
kf5
kf5-kconfig
kf5-kcoreaddons
kf5-ki18n
kf5-kwidgetsaddons
kpmcore
kronosnet
ksh
kyotocabinet
kyua
ladspa
lame
langtable
lapack
lasso
latencytop
lato-fonts
lcms2
lcov
ldns
leatherman
ledmon
lensfun
leveldb
lftp
libabw
libaec
libao
libappstream-glib
libart_lgpl
libasyncns
libatasmart
libavc1394
libblockdev
libbpf
libbsd
libburn
libbytesize
libcacard
libcanberra
libcdio
libcdio-paranoia
libcdr
libcgroup
libchewing
libcli
libcmis
libcmpiutil
libcomps
libcroco
libdaemon
libdap
libdatrie
libdazzle
libdbi
libdbi-drivers
libdbusmenu
libdc1394
libdeflate
libdmx
libdnf
libdrm
libdvdnav
libdvdread
libdwarf
libeasyfc
libecap
libecb
libell
libEMF
libeot
libepoxy
libepubgen
libesmtp
libetonyek
libev
libevdev
libewf
libexif
libexttextcat
libfabric
libfontenc
libfreehand
libftdi
libgadu
libgdither
libgee
libgee06
libgeotiff
libgexiv2
libgit2
libgit2-glib
libglade2
libglvnd
libgovirt
libgphoto2
libgsf
libgta
libguestfs
libgusb
libgxim
libgxps
libhangul
libhugetlbfs
libibcommon
libical
libICE
libicns
libid3tag
libIDL
libidn2
libiec61883
libieee1284
libimobiledevice
libindicator
libinput
libiodbc
libipt
libiptcdata
libiscsi
libisoburn
libisofs
libjcat
libkcapi
libkeepalive
libkkc
libkkc-data
libkml
liblangtag
libldb
libldm
liblerc
liblockfile
liblognorm
liblouis
liblqr-1
liblzf
libmad
libmediaart
libmicrohttpd
libmikmod
libmodman
libmodplug
libmodulemd1
libmpcdec
libmspub
libmtp
libmusicbrainz5
libmwaw
libnbd
libnet
libnetfilter_log
libnfs
libnotify
libntlm
libnumbertext
liboauth
libodfgen
libofa
libogg
liboggz
liboil
libomxil-bellagio
libopenraw
liboping
libosinfo
libotf
libotr
libpagemaker
libpaper
libpciaccess
libpeas
libpfm
libpinyin
libplist
libpmemobj-cpp
libpng12
libpng15
libproxy
libpsm2
libpwquality
libqb
libqxp
libraqm
LibRaw
libraw1394
libreport
libreswan
librevenge
librsvg2
librx
libsamplerate
libsass
libsecret
libsemanage
libsigc++20
libsigsegv
libslirp
libSM
libsmbios
libsmi
libsndfile
libsodium
libspiro
libsrtp
libssh
libstaroffice
libstemmer
libstoragemgmt
libtdb
libteam
libtevent
libthai
libtnc
libtomcrypt
libtommath
libtracecmd
libtraceevent
libtracefs
libtranslit
libucil
libunicap
libuninameslist
liburing
libusbmuxd
libuser
libutempter
libvarlink
libverto
libvirt-dbus
libvirt-glib
libvirt-java
libvirt-python
libvisio
libvisual
libvoikko
libvorbis
libvpx
libwacom
libwnck3
libwpd
libwpe
libwpg
libwps
libwvstreams
libX11
libXau
libXaw
libxcb
libXcomposite
libxcrypt
libXcursor
libXdamage
libXdmcp
libXext
libxfce4util
libXfixes
libXfont2
libXft
libXi
libXinerama
libxkbcommon
libxkbfile
libxklavier
libxmlb
libXmu
libXpm
libXrandr
libXrender
libXres
libXScrnSaver
libxshmfence
libXt
libXtst
libXv
libXxf86vm
libyami
libyang
libyubikey
libzip
libzmf
lilv
linuxconsoletools
linuxptp
lksctp-tools
lldpd
lockdev
logwatch
lpsolve
lrzsz
lua
lua-expat
lua-filesystem
lua-json
lua-lpeg
lua-lunit
lua-rpm-macros
lua-term
luajit
luksmeta
lutok
lv2
lzip
lzop
m17n-db
m17n-lib
mac-robber
mailcap
mailx
malaga
malaga-suomi-voikko
mallard-rng
man-pages-cs
man-pages-es
man-pages-it
man-pages-ja
man-pages-ko
man-pages-pl
man-pages-ru
man-pages-zh-CN
mariadb-connector-c
mariadb-connector-odbc
marisa
maven-compiler-plugin
maven-jar-plugin
maven-resolver
maven-resources-plugin
maven-surefire
maven-wagon
mcelog
mcpp
mcstrans
mdadm
mdds
meanwhile
mecab
mecab-ipadic
media-player-info
memcached
memkind
mesa
mesa-libGLU
metis
microcode_ctl
microdnf
minicom
minizip
mksh
mobile-broadband-provider-info
mock
mock-core-configs
mod_auth_gssapi
mod_auth_mellon
mod_auth_openidc
mod_authnz_pam
mod_fcgid
mod_http2
mod_intercept_form_submit
mod_lookup_identity
mod_md
mod_security
mod_security_crs
mod_wsgi
mokutil
moreutils
mosh
mpage
mrtg
mstflint
mt-st
mtdev
mtools
mtr
mtx
multilib-rpm-config
munge
mutt
mythes
mythes-bg
mythes-ca
mythes-cs
mythes-da
mythes-de
mythes-el
mythes-en
mythes-eo
mythes-es
mythes-fr
mythes-ga
mythes-hu
mythes-mi
mythes-ne
mythes-nl
mythes-pl
mythes-pt
mythes-ro
mythes-ru
mythes-sk
mythes-sl
mythes-sv
mythes-uk
nbd
nbdkit
neon
netavark
netcdf
netcf
netlabel_tools
netpbm
netsniff-ng
nfs4-acl-tools
nftables
nilfs-utils
nkf
nload
nlopt
nodejs-packaging
nss-mdns
nss-pam-ldapd
nss_nis
nss_wrapper
ntfs-3g
ntfs-3g-system-compression
numad
numatop
numpy
nvmetcli
nvml
oath-toolkit
ocaml
ocaml-alcotest
ocaml-astring
ocaml-base
ocaml-bigarray-compat
ocaml-bisect-ppx
ocaml-calendar
ocaml-camlp5
ocaml-camomile
ocaml-cinaps
ocaml-cmdliner
ocaml-compiler-libs-janestreet
ocaml-cppo
ocaml-csexp
ocaml-csv
ocaml-ctypes
ocaml-curses
ocaml-dune
ocaml-extlib
ocaml-fileutils
ocaml-findlib
ocaml-fmt
ocaml-fpath
ocaml-gettext
ocaml-integers
ocaml-libvirt
ocaml-luv
ocaml-lwt
ocaml-markup
ocaml-migrate-parsetree
ocaml-mmap
ocaml-num
ocaml-ocamlbuild
ocaml-ocplib-endian
ocaml-ounit
ocaml-parsexp
ocaml-ppx-derivers
ocaml-ppxlib
ocaml-re
ocaml-react
ocaml-result
ocaml-seq
ocaml-sexplib
ocaml-sexplib0
ocaml-stdio
ocaml-topkg
ocaml-tyxml
ocaml-uuidm
ocaml-uutf
ocaml-xml-light
ocaml-zarith
ocl-icd
oddjob
ogdi
omping
opa
opal
open-vm-tools
openblas
opencc
opencl-filesystem
opencl-headers
opencryptoki
opencsd
opendnssec
OpenEXR
openjade
openjpeg2
openmpi
openobex
openoffice-lv
openrdate
opensc
openslp
opensm
opensp
openssl
openssl-ibmpkcs11
openssl-pkcs11
openwsman
optipng
opus
opusfile
orangefs
ORBit2
orc
os-prober
osinfo-db
osinfo-db-tools
overpass-fonts
p11-kit
p7zip
pacemaker
pacrunner
pakchois
pam_krb5
pam_wrapper
papi
paps
parallel
patchelf
patchutils
pbzip2
pcp
pcsc-lite
pcsc-lite-ccid
PEGTL
perl
perl-Algorithm-C3
perl-Algorithm-Diff
perl-Alien-Build
perl-Alien-pkgconf
perl-AnyEvent
perl-AnyEvent-AIO
perl-AnyEvent-BDB
perl-App-cpanminus
perl-App-FatPacker
perl-AppConfig
perl-Archive-Extract
perl-Archive-Zip
perl-Authen-SASL
perl-B-Debug
perl-B-Hooks-EndOfScope
perl-B-Hooks-OP-Check
perl-B-Keywords
perl-B-Lint
perl-bareword-filehandles
perl-BDB
perl-Bit-Vector
perl-boolean
perl-Browser-Open
perl-BSD-Resource
perl-Business-ISBN
perl-Business-ISBN-Data
perl-Bytes-Random-Secure
perl-Capture-Tiny
perl-Carp-Clan
perl-CBOR-XS
perl-Class-Accessor
perl-Class-C3
perl-Class-C3-XS
perl-Class-Data-Inheritable
perl-Class-Factory-Util
perl-Class-Inspector
perl-Class-ISA
perl-Class-Load
perl-Class-Load-XS
perl-Class-Method-Modifiers
perl-Class-Singleton
perl-Class-Tiny
perl-Class-XSAccessor
perl-Clone
perl-Color-ANSI-Util
perl-Color-RGB-Util
perl-ColorThemeBase-Static
perl-ColorThemeRole-ANSI
perl-ColorThemes-Standard
perl-ColorThemeUtil-ANSI
perl-Compress-Bzip2
perl-Compress-LZF
perl-Compress-Raw-Lzma
perl-Config-AutoConf
perl-Config-INI
perl-Config-INI-Reader-Multiline
perl-Config-IniFiles
perl-Config-Simple
perl-Config-Tiny
perl-Const-Fast
perl-Convert-ASN1
perl-Convert-Bencode
perl-Coro
perl-Coro-Multicore
perl-CPAN-Changes
perl-CPAN-DistnameInfo
perl-CPAN-Meta-Check
perl-Cpanel-JSON-XS
perl-Crypt-CBC
perl-Crypt-DES
perl-Crypt-IDEA
perl-Crypt-OpenSSL-Bignum
perl-Crypt-OpenSSL-Guess
perl-Crypt-OpenSSL-Random
perl-Crypt-OpenSSL-RSA
perl-Crypt-PasswdMD5
perl-Crypt-Random-Seed
perl-CSS-Tiny
perl-Data-Dump
perl-Data-Munge
perl-Data-OptList
perl-Data-Peek
perl-Data-Section
perl-Data-UUID
perl-Date-Calc
perl-Date-ISO8601
perl-Date-Manip
perl-DateTime
perl-DateTime-Format-Builder
perl-DateTime-Format-DateParse
perl-DateTime-Format-HTTP
perl-DateTime-Format-IBeat
perl-DateTime-Format-ISO8601
perl-DateTime-Format-Mail
perl-DateTime-Format-Strptime
perl-DateTime-Locale
perl-DateTime-TimeZone
perl-DateTime-TimeZone-SystemV
perl-DateTime-TimeZone-Tzfile
perl-DBD-MySQL
perl-Devel-CallChecker
perl-Devel-Caller
perl-Devel-CheckBin
perl-Devel-CheckLib
perl-Devel-Cycle
perl-Devel-EnforceEncapsulation
perl-Devel-GlobalDestruction
perl-Devel-GlobalDestruction-XS
perl-Devel-Hide
perl-Devel-Leak
perl-Devel-LexAlias
perl-Devel-Size
perl-Devel-StackTrace
perl-Devel-Symdump
perl-Digest-BubbleBabble
perl-Digest-CRC
perl-Digest-HMAC
perl-Digest-SHA1
perl-Dist-CheckConflicts
perl-DynaLoader-Functions
perl-Email-Address
perl-Email-Date-Format
perl-Encode-Detect
perl-Encode-EUCJPASCII
perl-Encode-IMAPUTF7
perl-Encode-Locale
perl-Env-ShellWords
perl-Error
perl-EV
perl-Eval-Closure
perl-Event
perl-Exception-Class
perl-Expect
perl-ExtUtils-Config
perl-ExtUtils-Depends
perl-ExtUtils-Helpers
perl-ExtUtils-InstallPaths
perl-ExtUtils-PkgConfig
perl-FCGI
perl-Fedora-VSP
perl-FFI-CheckLib
perl-File-BaseDir
perl-File-BOM
perl-File-chdir
perl-File-CheckTree
perl-File-Copy-Recursive
perl-File-DesktopEntry
perl-File-Find-Object
perl-File-Find-Object-Rule
perl-File-Find-Rule
perl-File-Find-Rule-Perl
perl-File-Inplace
perl-File-Listing
perl-File-MimeInfo
perl-File-pushd
perl-File-ReadBackwards
perl-File-Remove
perl-File-ShareDir
perl-File-ShareDir-Install
perl-File-Slurp
perl-File-Slurp-Tiny
perl-File-Slurper
perl-File-Type
perl-Font-TTF
perl-FreezeThaw
perl-GD
perl-GD-Barcode
perl-generators
perl-Getopt-ArgvFile
perl-gettext
perl-Graphics-ColorNamesLite-WWW
perl-GSSAPI
perl-Guard
perl-Hook-LexWrap
perl-HTML-Parser
perl-HTML-Tagset
perl-HTML-Tree
perl-HTTP-Cookies
perl-HTTP-Daemon
perl-HTTP-Date
perl-HTTP-Message
perl-HTTP-Negotiate
perl-Image-Base
perl-Image-Info
perl-Image-Xbm
perl-Image-Xpm
perl-Import-Into
perl-Importer
perl-inc-latest
perl-indirect
perl-Inline-Files
perl-IO-AIO
perl-IO-All
perl-IO-CaptureOutput
perl-IO-Compress-Lzma
perl-IO-HTML
perl-IO-Multiplex
perl-IO-SessionData
perl-IO-Socket-INET6
perl-IO-String
perl-IO-stringy
perl-IO-Tty
perl-IPC-Run
perl-IPC-Run3
perl-IPC-System-Simple
perl-JSON
perl-JSON-Color
perl-JSON-MaybeXS
perl-LDAP
perl-libnet
perl-libwww-perl
perl-libxml-perl
perl-Lingua-EN-Inflect
perl-List-MoreUtils-XS
perl-local-lib
perl-Locale-Codes
perl-Locale-Maketext-Gettext
perl-Locale-Msgfmt
perl-Locale-PO
perl-Log-Message
perl-Log-Message-Simple
perl-LWP-MediaTypes
perl-LWP-Protocol-https
perl-Mail-AuthenticationResults
perl-Mail-DKIM
perl-Mail-IMAPTalk
perl-Mail-SPF
perl-MailTools
perl-Math-Int64
perl-Math-Random-ISAAC
perl-MIME-Charset
perl-MIME-Lite
perl-MIME-Types
perl-Mixin-Linewise
perl-MLDBM
perl-Mock-Config
perl-Module-Build-Tiny
perl-Module-CPANfile
perl-Module-Implementation
perl-Module-Install-AuthorRequires
perl-Module-Install-AuthorTests
perl-Module-Install-AutoLicense
perl-Module-Install-GithubMeta
perl-Module-Install-ManifestSkip
perl-Module-Install-ReadmeFromPod
perl-Module-Install-ReadmeMarkdownFromPod
perl-Module-Install-Repository
perl-Module-Install-TestBase
perl-Module-Load-Util
perl-Module-Manifest
perl-Module-Manifest-Skip
perl-Module-Package
perl-Module-Package-Au
perl-Module-Pluggable
perl-Module-Runtime
perl-Module-Signature
perl-Mojolicious
perl-Moo
perl-Mozilla-CA
perl-Mozilla-LDAP
perl-MRO-Compat
perl-multidimensional
perl-namespace-autoclean
perl-namespace-clean
perl-Net-CIDR-Lite
perl-Net-Daemon
perl-Net-DNS
perl-Net-DNS-Resolver-Mock
perl-Net-DNS-Resolver-Programmable
perl-Net-HTTP
perl-Net-IMAP-Simple
perl-Net-IMAP-Simple-SSL
perl-Net-IP
perl-Net-LibIDN2
perl-Net-Patricia
perl-Net-SMTP-SSL
perl-Net-SNMP
perl-Net-Telnet
perl-Newt
perl-NNTPClient
perl-NTLM
perl-Number-Compare
perl-Object-Deadly
perl-Object-HashBase
perl-Package-Anon
perl-Package-Constants
perl-Package-DeprecationManager
perl-Package-Generator
perl-Package-Stash
perl-Package-Stash-XS
perl-PadWalker
perl-Paper-Specs
perl-PAR-Dist
perl-Parallel-Iterator
perl-Params-Classify
perl-Params-Util
perl-Params-Validate
perl-Params-ValidationCompiler
perl-Parse-PMFile
perl-Parse-RecDescent
perl-Parse-Yapp
perl-Path-Tiny
perl-Perl-Critic
perl-Perl-Critic-More
perl-Perl-Destruct-Level
perl-Perl-MinimumVersion
perl-Perl4-CoreLibs
perl-PerlIO-gzip
perl-PerlIO-utf8_strict
perl-PkgConfig-LibPkgConf
perl-Pod-Coverage
perl-Pod-Coverage-TrustPod
perl-Pod-Escapes
perl-Pod-Eventual
perl-Pod-LaTeX
perl-Pod-Markdown
perl-Pod-Parser
perl-Pod-Plainer
perl-Pod-POM
perl-Pod-Spell
perl-PPI
perl-PPI-HTML
perl-PPIx-QuoteLike
perl-PPIx-Regexp
perl-PPIx-Utilities
perl-prefork
perl-Probe-Perl
perl-Razor-Agent
perl-Readonly
perl-Readonly-XS
perl-Ref-Util
perl-Ref-Util-XS
perl-Regexp-Pattern-Perl
perl-Return-MultiLevel
perl-Role-Tiny
perl-Scope-Guard
perl-Scope-Upper
perl-SGMLSpm
perl-SNMP_Session
perl-Socket6
perl-Software-License
perl-Sort-Versions
perl-Specio
perl-Spiffy
perl-strictures
perl-String-CRC32
perl-String-Format
perl-String-ShellQuote
perl-String-Similarity
perl-Sub-Exporter
perl-Sub-Exporter-Progressive
perl-Sub-Identify
perl-Sub-Info
perl-Sub-Install
perl-Sub-Name
perl-Sub-Quote
perl-Sub-Uplevel
perl-SUPER
perl-Switch
perl-Syntax-Highlight-Engine-Kate
perl-Sys-CPU
perl-Sys-MemInfo
perl-Sys-Virt
perl-Taint-Runtime
perl-Task-Weaken
perl-Term-Size-Any
perl-Term-Size-Perl
perl-Term-Table
perl-Term-UI
perl-TermReadKey
perl-Test-Base
perl-Test-ClassAPI
perl-Test-CPAN-Meta
perl-Test-CPAN-Meta-JSON
perl-Test-Deep
perl-Test-Differences
perl-Test-DistManifest
perl-Test-Distribution
perl-Test-EOL
perl-Test-Exception
perl-Test-Exit
perl-Test-FailWarnings
perl-Test-Fatal
perl-Test-File
perl-Test-File-ShareDir
perl-Test-Harness
perl-Test-HasVersion
perl-Test-InDistDir
perl-Test-Inter
perl-Test-LeakTrace
perl-Test-LongString
perl-Test-Manifest
perl-Test-Memory-Cycle
perl-Test-MinimumVersion
perl-Test-MockObject
perl-Test-MockRandom
perl-Test-Needs
perl-Test-NoTabs
perl-Test-NoWarnings
perl-Test-Object
perl-Test-Output
perl-Test-Pod
perl-Test-Pod-Coverage
perl-Test-Portability-Files
perl-Test-Requires
perl-Test-RequiresInternet
perl-Test-Script
perl-Test-Simple
perl-Test-SubCalls
perl-Test-Synopsis
perl-Test-Taint
perl-Test-TrailingSpace
perl-Test-utf8
perl-Test-Vars
perl-Test-Warn
perl-Test-Without-Module
perl-Test2-Plugin-NoWarnings
perl-Test2-Suite
perl-Test2-Tools-Explain
perl-Text-CharWidth
perl-Text-CSV_XS
perl-Text-Diff
perl-Text-Glob
perl-Text-Iconv
perl-Text-Soundex
perl-Text-Unidecode
perl-Text-WrapI18N
perl-Tie-IxHash
perl-Time-Duration
perl-TimeDate
perl-Tree-DAG_Node
perl-Unicode-EastAsianWidth
perl-Unicode-LineBreak
perl-Unicode-Map8
perl-Unicode-String
perl-Unicode-UTF8
perl-UNIVERSAL-can
perl-UNIVERSAL-isa
perl-Unix-Syslog
perl-URI
perl-Variable-Magic
perl-Version-Requirements
perl-WWW-RobotRules
perl-XML-Catalog
perl-XML-DOM
perl-XML-Dumper
perl-XML-Filter-BufferText
perl-XML-Generator
perl-XML-Grove
perl-XML-Handler-YAWriter
perl-XML-LibXML
perl-XML-LibXSLT
perl-XML-NamespaceSupport
perl-XML-Parser-Lite
perl-XML-RegExp
perl-XML-SAX
perl-XML-SAX-Base
perl-XML-SAX-Writer
perl-XML-Simple
perl-XML-TokeParser
perl-XML-TreeBuilder
perl-XML-Twig
perl-XML-Writer
perl-XML-XPath
perl-XML-XPathEngine
perl-XString
perl-YAML-LibYAML
perl-YAML-PP
perl-YAML-Syck
perltidy
pesign
phodav
php
php-pear
php-pecl-zip
physfs
picosat
pinfo
pipewire
pixman
pkcs11-helper
pkgconf
plexus-cipher
plexus-containers
plexus-sec-dispatcher
plotutils
pmdk-convert
pmix
pngcrush
pngnq
po4a
podman
poetry
policycoreutils
polkit-pkla-compat
portreserve
postfix
potrace
powertop
ppp
pps-tools
pptp
priv_wrapper
procmail
prometheus
prometheus-node-exporter
ps_mem
psacct
psutils
ptlib
publicsuffix-list
pugixml
pulseaudio
puppet
pwgen
pyatspi
pybind11
pycairo
pyelftools
pyflakes
pygobject3
PyGreSQL
pykickstart
pylint
pyparted
pyproject-rpm-macros
pyserial
python-absl-py
python-aiodns
python-aiohttp
python-alsa
python-argcomplete
python-astroid
python-astunparse
python-async-generator
python-augeas
python-azure-sdk
python-beautifulsoup4
python-betamax
python-blinker
python-blivet
python-cached_property
python-charset-normalizer
python-cheetah
python-click
python-cmd2
python-colorama
python-CommonMark
python-conda-package-handling
python-configshell
python-cpuinfo
python-cups
python-curio
python-cytoolz
python-d2to1
python-dbus-client-gen
python-dbus-python-client-gen
python-dbus-signature-pyparsing
python-dbusmock
python-ddt
python-debtcollector
python-decorator
python-distlib
python-dmidecode
python-dns
python-dtopt
python-dulwich
python-enchant
python-entrypoints
python-ethtool
python-evdev
python-extras
python-faker
python-fasteners
python-fields
python-filelock
python-fixtures
python-flake8
python-flask
python-flit
python-flit-core
python-fluidity-sm
python-frozendict
python-funcsigs
python-gast
python-genshi
python-google-auth
python-google-auth-oauthlib
python-greenlet
python-gssapi
python-h5py
python-hs-dbus-signature
python-html5lib
python-httplib2
python-humanize
python-hwdata
python-importlib-metadata
python-inotify
python-into-dbus-python
python-IPy
python-iso8601
python-isodate
python-isort
python-itsdangerous
python-junit-xml
python-justbases
python-justbytes
python-jwcrypto
python-jwt
python-kdcproxy
python-kerberos
python-kmod
python-kubernetes
python-lazy-object-proxy
python-ldap
python-linux-procfs
python-lit
python-markdown
python-mccabe
python-memcached
python-mimeparse
python-mock
python-monotonic
python-more-itertools
python-mpmath
python-msal
python-msrestazure
python-mutagen
python-networkx
python-nose2
python-ntlm-auth
python-oauth2client
python-openpyxl
python-openstackdocstheme
python-oslo-i18n
python-oslo-sphinx
python-paramiko
python-pefile
python-pexpect
python-pkgconfig
python-platformdirs
python-pluggy
python-podman-api
python-process-tests
python-productmd
python-ptyprocess
python-pycares
python-pycosat
python-pydbus
python-pymongo
python-PyMySQL
python-pyperclip
python-pyroute2
python-pyrsistent
python-pysocks
python-pytest-benchmark
python-pytest-cov
python-pytest-expect
python-pytest-flake8
python-pytest-forked
python-pytest-mock
python-pytest-relaxed
python-pytest-runner
python-pytest-subtests
python-pytest-timeout
python-pytest-xdist
python-pytoml
python-pyudev
python-pywbem
python-qrcode
python-rdflib
python-recommonmark
python-redis
python-requests-file
python-requests-ftp
python-requests-kerberos
python-requests-mock
python-requests-oauthlib
python-requests-toolbelt
python-requests_ntlm
python-responses
python-retrying
python-rfc3986
python-rpm-generators
python-rpmfluff
python-rtslib
python-ruamel-yaml
python-ruamel-yaml-clib
python-s3transfer
python-schedutils
python-semantic_version
python-should_dsl
python-simpleline
python-slip
python-sniffio
python-soupsieve
python-sphinx
python-sphinx-epytext
python-sphinx-theme-py3doc-enhanced
python-sphinx_rtd_theme
python-sphinxcontrib-apidoc
python-sphinxcontrib-applehelp
python-sphinxcontrib-devhelp
python-sphinxcontrib-htmlhelp
python-sphinxcontrib-httpdomain
python-sphinxcontrib-jsmath
python-sphinxcontrib-qthelp
python-sphinxcontrib-serializinghtml
python-sqlalchemy
python-suds
python-systemd
python-tempita
python-templated-dictionary
python-termcolor
python-testpath
python-testresources
python-testscenarios
python-testtools
python-tidy
python-toml
python-tomli
python-toolz
python-tornado
python-tox
python-tox-current-env
python-tqdm
python-trio
python-typing-extensions
python-uamqp
python-unittest2
python-uritemplate
python-urwid
python-varlink
python-virt-firmware
python-voluptuous
python-waitress
python-webencodings
python-webtest
python-wheel
python-whoosh
python-winrm
python-wrapt
python-xmltodict
python-yubico
python-zipp
python-zmq
python3-mallard-ducktype
python3-pytest-asyncio
python3-typed_ast
pyusb
pywbem
pyxattr
qemu
qhull
qpdf
qperf
qr-code-generator
qt5-qtbase
qt5-qtconnectivity
qt5-qtdeclarative
qt5-qtsensors
qt5-qtserialport
qt5-qtsvg
qt5-qttools
qt5-rpm-macros
quagga
quota
quotatool
radvd
ragel
raptor2
rarian
rasdaemon
rasqal
rcs
rdist
rdma-core
re2
re2c
realmd
rear
recode
redland
resource-agents
rest
rhash
rlwrap
rp-pppoe
rpm-mpi-hooks
rpmdevtools
rpmlint
rtkit
rtl-sdr
ruby-augeas
rubygem-bson
rubygem-coderay
rubygem-diff-lcs
rubygem-flexmock
rubygem-hpricot
rubygem-introspection
rubygem-liquid
rubygem-maruku
rubygem-metaclass
rubygem-mongo
rubygem-mustache
rubygem-mysql2
rubygem-pkg-config
rubygem-rake
rubygem-rake-compiler
rubygem-ronn
rubygem-rouge
rubygem-rspec
rubygem-rspec-expectations
rubygem-rspec-mocks
rubygem-rspec-support
rubygem-thread_order
rusers
rust-cbindgen
samba
sanlock
sassist
satyr
sbc
sblim-cim-client2
sblim-cmpi-base
sblim-cmpi-devel
sblim-cmpi-fsvol
sblim-cmpi-network
sblim-cmpi-nfsv3
sblim-cmpi-nfsv4
sblim-cmpi-params
sblim-cmpi-sysfs
sblim-cmpi-syslog
sblim-indication_helper
sblim-sfcb
sblim-sfcc
sblim-sfcCommon
sblim-testsuite
sblim-wbemcli
scl-utils
scotch
screen
scrub
SDL
SDL2
SDL_sound
sdparm
seabios
secilc
selinux-policy
sendmail
serd
setools
setserial
setuptool
sgabios
sgml-common
sgpio
shared-mime-info
sharutils
sip
sisu
skkdic
sleuthkit
slirp4netns
smartmontools
smc-tools
socket_wrapper
softhsm
sombok
sord
sos
sound-theme-freedesktop
soundtouch
sox
soxr
sparsehash
spausedd
speex
speexdsp
spice-protocol
spice-vdagent
spirv-headers
spirv-tools
splix
squashfs-tools
squid
sratom
sscg
star
startup-notification
stunnel
subscription-manager
suitesparse
SuperLU
supermin
switcheroo-control
symlinks
sympy
sysfsutils
systemd-bootchart
t1lib
t1utils
taglib
tang
targetcli
tbb
tcl-pgtcl
tclx
teckit
telnet
tidy
time
tini
tinycdb
tix
tk
tlog
tmpwatch
tn5250
tofrodos
tokyocabinet
tpm-quote-tools
tpm-tools
trace-cmd
tss2
ttembed
ttmkfdir
tuna
twolame
uchardet
uclibc-ng
ucpp
ucs-miscfixed-fonts
ucx
udftools
udica
udisks2
uglify-js
uid_wrapper
unicode-emoji
unicode-ucd
unique3
units
upower
uriparser
urlview
usb_modeswitch
usb_modeswitch-data
usbguard
usbip
usbmuxd
usbredir
usermode
ustr
uthash
uuid
uw-imap
v4l-utils
vhostmd
vino
virglrenderer
virt-p2v
virt-top
virt-what
virt-who
virtiofsd
vitess
vmem
volume_key
vorbis-tools
vte291
vulkan-headers
vulkan-loader
watchdog
wavpack
wayland
wayland-protocols
web-assets
webrtc-audio-processing
websocketpp
whois
wireguard-tools
wireless-regdb
wireshark
woff2
wordnet
words
wpebackend-fdo
wsmancli
wvdial
x3270
xapian-core
Xaw3d
xcb-proto
xcb-util
xcb-util-image
xcb-util-keysyms
xcb-util-renderutil
xcb-util-wm
xdelta
xdg-dbus-proxy
xdg-utils
xerces-c
xfconf
xfsdump
xhtml1-dtds
xkeyboard-config
xmlstarlet
xmltoman
xmvn
xorg-x11-apps
xorg-x11-drv-libinput
xorg-x11-font-utils
xorg-x11-fonts
xorg-x11-proto-devel
xorg-x11-server
xorg-x11-server-utils
xorg-x11-util-macros
xorg-x11-utils
xorg-x11-xauth
xorg-x11-xbitmaps
xorg-x11-xinit
xorg-x11-xkb-utils
xorg-x11-xtrans-devel
xrestop
xterm
xxhash
yajl
yaml-cpp
yasm
yelp-tools
yelp-xsl
ykclient
yp-tools
ypbind
ypserv
z3
zenity
zerofree
zfs-fuse
zipper
zopfli
zziplib | | Fedora (Copyright Remi Collet) | [CC-BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/legalcode) | libmemcached-awesome
librabbitmq | | Fedora (ISC) | [ISC License](https://github.com/sarugaku/resolvelib/blob/main/LICENSE) | python-resolvelib | | Magnus Edenhill Open Source | [Magnus Edenhill Open Source BSD License](https://github.com/jemalloc/jemalloc/blob/dev/COPYING) | librdkafka | diff --git a/SPECS/LICENSES-AND-NOTICES/data/licenses.json b/SPECS/LICENSES-AND-NOTICES/data/licenses.json index 4825eaf884f..822f66bb87c 100644 --- a/SPECS/LICENSES-AND-NOTICES/data/licenses.json +++ b/SPECS/LICENSES-AND-NOTICES/data/licenses.json @@ -762,7 +762,9 @@ "libtnc", "libtomcrypt", "libtommath", + "libtracecmd", "libtraceevent", + "libtracefs", "libtranslit", "libucil", "libunicap", @@ -2005,6 +2007,7 @@ "tokyocabinet", "tpm-quote-tools", "tpm-tools", + "trace-cmd", "tss2", "ttembed", "ttmkfdir", diff --git a/SPECS/application-gateway-kubernetes-ingress/CVE-2022-32149.patch b/SPECS/application-gateway-kubernetes-ingress/CVE-2022-32149.patch new file mode 100644 index 00000000000..cf9ed3f1975 --- /dev/null +++ b/SPECS/application-gateway-kubernetes-ingress/CVE-2022-32149.patch @@ -0,0 +1,35 @@ +From 7ee36713a66401f828dfe476196ca290f7c23ffe Mon Sep 17 00:00:00 2001 +From: Sindhu Karri +Date: Wed, 28 Aug 2024 05:01:17 +0000 +Subject: [PATCH] Fix CVE-2022-32149 + +--- + vendor/golang.org/x/text/language/parse.go | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/vendor/golang.org/x/text/language/parse.go b/vendor/golang.org/x/text/language/parse.go +index 11acfd8..11d11f4 100644 +--- a/vendor/golang.org/x/text/language/parse.go ++++ b/vendor/golang.org/x/text/language/parse.go +@@ -133,6 +133,7 @@ func update(b *language.Builder, part ...interface{}) (err error) { + } + + var errInvalidWeight = errors.New("ParseAcceptLanguage: invalid weight") ++var errTagListTooLarge = errors.New("tag list exceeds max length") + + // ParseAcceptLanguage parses the contents of an Accept-Language header as + // defined in http://www.ietf.org/rfc/rfc2616.txt and returns a list of Tags and +@@ -150,6 +151,10 @@ func ParseAcceptLanguage(s string) (tag []Tag, q []float32, err error) { + + entry, weight := split(entry, ';') + ++ if strings.Count(s, "-") > 1000 { ++ return nil, nil, errTagListTooLarge ++ } ++ + // Scan the language. + t, err := Parse(entry) + if err != nil { +-- +2.33.8 + diff --git a/SPECS/application-gateway-kubernetes-ingress/application-gateway-kubernetes-ingress.spec b/SPECS/application-gateway-kubernetes-ingress/application-gateway-kubernetes-ingress.spec index 1fe90c4c390..d78e22de786 100644 --- a/SPECS/application-gateway-kubernetes-ingress/application-gateway-kubernetes-ingress.spec +++ b/SPECS/application-gateway-kubernetes-ingress/application-gateway-kubernetes-ingress.spec @@ -2,7 +2,7 @@ Summary: Application Gateway Ingress Controller Name: application-gateway-kubernetes-ingress Version: 1.4.0 -Release: 21%{?dist} +Release: 23%{?dist} License: MIT Vendor: Microsoft Corporation Distribution: Mariner @@ -29,6 +29,7 @@ Source1: %{name}-%{version}-vendor.tar.gz Patch0: CVE-2022-21698.patch Patch1: CVE-2023-44487.patch Patch2: CVE-2021-44716.patch +Patch3: CVE-2022-32149.patch BuildRequires: golang %if %{with_check} @@ -67,6 +68,12 @@ cp appgw-ingress %{buildroot}%{_bindir}/ %{_bindir}/appgw-ingress %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 1.4.0-23 +- Bump release to rebuild with go 1.22.7 + +* Wed Aug 28 2024 Sindhu Karri - 1.4.0-22 +- Fix CVE-2022-32149 with a patch + * Wed Jul 17 2024 Muhammad Falak R Wani - 1.4.0-21 - Drop requirement on a specific version of golang diff --git a/SPECS/azcopy/azcopy.spec b/SPECS/azcopy/azcopy.spec index 8e6a3fa49d8..8f0a84b0eba 100644 --- a/SPECS/azcopy/azcopy.spec +++ b/SPECS/azcopy/azcopy.spec @@ -1,7 +1,7 @@ Summary: The new Azure Storage data transfer utility - AzCopy v10 Name: azcopy Version: 10.25.1 -Release: 1%{?dist} +Release: 2%{?dist} License: MIT Vendor: Microsoft Corporation Distribution: Mariner @@ -63,6 +63,9 @@ go test -mod=vendor %{_bindir}/azcopy %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 10.25.1-2 +- Bump release to rebuild with go 1.22.7 + * Thu Aug 01 2024 Archana Choudhary - 10.25.1-1 - Bump version to 10.25.1 to fix CVE-2024-35255 diff --git a/SPECS/blobfuse/blobfuse.spec b/SPECS/blobfuse/blobfuse.spec index 6ee94bedbcb..8a825fd967d 100644 --- a/SPECS/blobfuse/blobfuse.spec +++ b/SPECS/blobfuse/blobfuse.spec @@ -1,7 +1,7 @@ Summary: FUSE adapter - Azure Storage Blobs Name: blobfuse Version: 1.4.5 -Release: 15%{?dist} +Release: 16%{?dist} License: MIT Vendor: Microsoft Corporation Distribution: Mariner @@ -46,6 +46,9 @@ install -p -m 755 build/blobfuse %{buildroot}%{_bindir}/ %{_bindir}/blobfuse %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 1.4.5-16 +- Bump release to rebuild with go 1.22.7 + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 1.4.5-15 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS/blobfuse2/blobfuse2.spec b/SPECS/blobfuse2/blobfuse2.spec index 83731895ec5..57894415fac 100644 --- a/SPECS/blobfuse2/blobfuse2.spec +++ b/SPECS/blobfuse2/blobfuse2.spec @@ -7,7 +7,7 @@ Summary: FUSE adapter - Azure Storage Name: blobfuse2 Version: %{blobfuse2_version} -Release: 5%{?dist} +Release: 6%{?dist} License: MIT Vendor: Microsoft Corporation Distribution: Mariner @@ -80,6 +80,9 @@ install -D -m 0644 ./setup/blobfuse2-logrotate %{buildroot}%{_sysconfdir}/logrot %{_sysconfdir}/logrotate.d/blobfuse2 %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 2.1.2-6 +- Bump release to rebuild with go 1.22.7 + * Wed Jul 17 2024 Muhammad Falak R Wani - 2.1.2-5 - Drop requirement on a specific version of golang diff --git a/SPECS/cert-manager/CVE-2023-2253.patch b/SPECS/cert-manager/CVE-2023-2253.patch new file mode 100644 index 00000000000..8f5d096be22 --- /dev/null +++ b/SPECS/cert-manager/CVE-2023-2253.patch @@ -0,0 +1,90 @@ +From 521ea3d973cb0c7089ebbcdd4ccadc34be941f54 Mon Sep 17 00:00:00 2001 +From: "Jose D. Gomez R" +Date: Mon, 24 Apr 2023 18:52:27 +0200 +Subject: [PATCH] Fix runaway allocation on /v2/_catalog +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Introduced a Catalog entry in the configuration struct. With it, +it's possible to control the maximum amount of entries returned +by /v2/catalog (`GetCatalog` in registry/handlers/catalog.go). + +It's set to a default value of 1000. + +`GetCatalog` returns 100 entries by default if no `n` is +provided. When provided it will be validated to be between `0` +and `MaxEntries` defined in Configuration. When `n` is outside +the aforementioned boundary, ErrorCodePaginationNumberInvalid is +returned. + +`GetCatalog` now handles `n=0` gracefully with an empty response +as well. + +Signed-off-by: José D. Gómez R. <1josegomezr@gmail.com> +Co-authored-by: Cory Snider +--- + registry/api/v2/descriptors.go | 17 ++ + registry/api/v2/errors.go | 9 + + 2 files changed, 26 insertions(+), 0 deletions(-) + +diff --git a/vendor/github.com/docker/distribution/registry/api/v2/descriptors.go b/vendor/github.com/docker/distribution/registry/api/v2/descriptors.go +index a9616c58ad5..c3bf90f71d0 100644 +--- a/vendor/github.com/docker/distribution/registry/api/v2/descriptors.go ++++ b/vendor/github.com/docker/distribution/registry/api/v2/descriptors.go +@@ -134,6 +134,19 @@ var ( + }, + } + ++ invalidPaginationResponseDescriptor = ResponseDescriptor{ ++ Name: "Invalid pagination number", ++ Description: "The received parameter n was invalid in some way, as described by the error code. The client should resolve the issue and retry the request.", ++ StatusCode: http.StatusBadRequest, ++ Body: BodyDescriptor{ ++ ContentType: "application/json", ++ Format: errorsBody, ++ }, ++ ErrorCodes: []errcode.ErrorCode{ ++ ErrorCodePaginationNumberInvalid, ++ }, ++ } ++ + repositoryNotFoundResponseDescriptor = ResponseDescriptor{ + Name: "No Such Repository Error", + StatusCode: http.StatusNotFound, +@@ -490,6 +503,7 @@ var routeDescriptors = []RouteDescriptor{ + }, + }, + Failures: []ResponseDescriptor{ ++ invalidPaginationResponseDescriptor, + unauthorizedResponseDescriptor, + repositoryNotFoundResponseDescriptor, + deniedResponseDescriptor, +@@ -1578,6 +1592,9 @@ var routeDescriptors = []RouteDescriptor{ + }, + }, + }, ++ Failures: []ResponseDescriptor{ ++ invalidPaginationResponseDescriptor, ++ }, + }, + }, + }, +diff --git a/vendor/github.com/docker/distribution/registry/api/v2/errors.go b/vendor/github.com/docker/distribution/registry/api/v2/errors.go +index 97d6923aa03..87e9f3c14be 100644 +--- a/vendor/github.com/docker/distribution/registry/api/v2/errors.go ++++ b/vendor/github.com/docker/distribution/registry/api/v2/errors.go +@@ -133,4 +133,13 @@ var ( + longer proceed.`, + HTTPStatusCode: http.StatusNotFound, + }) ++ ++ ErrorCodePaginationNumberInvalid = errcode.Register(errGroup, errcode.ErrorDescriptor{ ++ Value: "PAGINATION_NUMBER_INVALID", ++ Message: "invalid number of results requested", ++ Description: `Returned when the "n" parameter (number of results ++ to return) is not an integer, "n" is negative or "n" is bigger than ++ the maximum allowed.`, ++ HTTPStatusCode: http.StatusBadRequest, ++ }) + ) diff --git a/SPECS/cert-manager/CVE-2023-3978.patch b/SPECS/cert-manager/CVE-2023-3978.patch new file mode 100644 index 00000000000..9b04a4f1b00 --- /dev/null +++ b/SPECS/cert-manager/CVE-2023-3978.patch @@ -0,0 +1,78 @@ +From 8ffa475fbdb33da97e8bf79cc5791ee8751fca5e Mon Sep 17 00:00:00 2001 +From: Roland Shoemaker +Date: Thu, 06 Jul 2023 10:25:47 -0700 +Subject: [PATCH] html: only render content literally in the HTML namespace + +Per the WHATWG HTML specification, section 13.3, only append the literal +content of a text node if we are in the HTML namespace. + +Thanks to Mohammad Thoriq Aziz for reporting this issue. + +Fixes golang/go#61615 +Fixes CVE-2023-3978 + +Change-Id: I332152904d4e7646bd2441602bcbe591fc655fa4 +Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1942896 +Reviewed-by: Tatiana Bradley +Run-TryBot: Roland Shoemaker +Reviewed-by: Damien Neil +TryBot-Result: Security TryBots +Reviewed-on: https://go-review.googlesource.com/c/net/+/514896 +Reviewed-by: Roland Shoemaker +TryBot-Result: Gopher Robot +Run-TryBot: Damien Neil +--- + +diff --git a/vendor/golang.org/x/net/html/render.go b/vendor/golang.org/x/net/html/render.go +index 8b28031..e8c1233 100644 +--- a/vendor/golang.org/x/net/html/render.go ++++ b/vendor/golang.org/x/net/html/render.go +@@ -194,9 +194,8 @@ + } + } + +- // Render any child nodes. +- switch n.Data { +- case "iframe", "noembed", "noframes", "noscript", "plaintext", "script", "style", "xmp": ++ // Render any child nodes ++ if childTextNodesAreLiteral(n) { + for c := n.FirstChild; c != nil; c = c.NextSibling { + if c.Type == TextNode { + if _, err := w.WriteString(c.Data); err != nil { +@@ -213,7 +212,7 @@ + // last element in the file, with no closing tag. + return plaintextAbort + } +- default: ++ } else { + for c := n.FirstChild; c != nil; c = c.NextSibling { + if err := render1(w, c); err != nil { + return err +@@ -231,6 +230,27 @@ + return w.WriteByte('>') + } + ++func childTextNodesAreLiteral(n *Node) bool { ++ // Per WHATWG HTML 13.3, if the parent of the current node is a style, ++ // script, xmp, iframe, noembed, noframes, or plaintext element, and the ++ // current node is a text node, append the value of the node's data ++ // literally. The specification is not explicit about it, but we only ++ // enforce this if we are in the HTML namespace (i.e. when the namespace is ++ // ""). ++ // NOTE: we also always include noscript elements, although the ++ // specification states that they should only be rendered as such if ++ // scripting is enabled for the node (which is not something we track). ++ if n.Namespace != "" { ++ return false ++ } ++ switch n.Data { ++ case "iframe", "noembed", "noframes", "noscript", "plaintext", "script", "style", "xmp": ++ return true ++ default: ++ return false ++ } ++} ++ + // writeQuoted writes s to w surrounded by quotes. Normally it will use double + // quotes, but if s contains a double quote, it will use single quotes. + // It is used for writing the identifiers in a doctype declaration. diff --git a/SPECS/cert-manager/CVE-2024-24786.patch b/SPECS/cert-manager/CVE-2024-24786.patch new file mode 100644 index 00000000000..2893ca89ffb --- /dev/null +++ b/SPECS/cert-manager/CVE-2024-24786.patch @@ -0,0 +1,40 @@ +From 6c1b60f80d28a7ac1b931ee04b516893c23700fa Mon Sep 17 00:00:00 2001 +From: Cameron Baird +Date: Thu, 22 Aug 2024 17:53:06 +0000 +Subject: [PATCH] Manually format patch for CVE-2024-24786 + +--- + .../protobuf/encoding/protojson/well_known_types.go | 3 +++ + .../protobuf/internal/encoding/json/decode.go | 2 +- + 2 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go b/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go +index c85f846..344c903 100644 +--- a/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go ++++ b/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go +@@ -348,6 +348,9 @@ func (d decoder) skipJSONValue() error { + } + } + } ++ ++ case json.EOF: ++ return errors.New("unexpected EOF") + } + return nil + } +diff --git a/vendor/google.golang.org/protobuf/internal/encoding/json/decode.go b/vendor/google.golang.org/protobuf/internal/encoding/json/decode.go +index b13fd29..b2be4e8 100644 +--- a/vendor/google.golang.org/protobuf/internal/encoding/json/decode.go ++++ b/vendor/google.golang.org/protobuf/internal/encoding/json/decode.go +@@ -121,7 +121,7 @@ func (d *Decoder) Read() (Token, error) { + + case ObjectClose: + if len(d.openStack) == 0 || +- d.lastToken.kind == comma || ++ d.lastToken.kind&(Name|comma) != 0 || + d.openStack[len(d.openStack)-1] != ObjectOpen { + return Token{}, d.newSyntaxError(tok.pos, unexpectedFmt, tok.RawString()) + } +-- +2.34.1 + diff --git a/SPECS/cert-manager/CVE-2024-28180.patch b/SPECS/cert-manager/CVE-2024-28180.patch new file mode 100644 index 00000000000..9c2f14dabc3 --- /dev/null +++ b/SPECS/cert-manager/CVE-2024-28180.patch @@ -0,0 +1,84 @@ +From 0dd4dd541c665fb292d664f77604ba694726f298 Mon Sep 17 00:00:00 2001 +From: Jacob Hoffman-Andrews +Date: Thu, 7 Mar 2024 14:25:21 -0800 +Subject: [PATCH] v2: backport decompression limit fix (#109) + +Backport from #107. +--- + +diff --git a/vendor/gopkg.in/square/go-jose.v2/crypter.go b/vendor/gopkg.in/square/go-jose.v2/crypter.go +index 73aab0f..0ae2e5e 100644 +--- a/vendor/gopkg.in/square/go-jose.v2/crypter.go ++++ b/vendor/gopkg.in/square/go-jose.v2/crypter.go +@@ -406,6 +406,9 @@ func (ctx *genericEncrypter) Options() EncrypterOptions { + // Decrypt and validate the object and return the plaintext. Note that this + // function does not support multi-recipient, if you desire multi-recipient + // decryption use DecryptMulti instead. ++// ++// Automatically decompresses plaintext, but returns an error if the decompressed ++// data would be >250kB or >10x the size of the compressed data, whichever is larger. + func (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error) { + headers := obj.mergedHeaders(nil) + +@@ -470,6 +473,9 @@ func (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error) + // with support for multiple recipients. It returns the index of the recipient + // for which the decryption was successful, the merged headers for that recipient, + // and the plaintext. ++// ++// Automatically decompresses plaintext, but returns an error if the decompressed ++// data would be >250kB or >3x the size of the compressed data, whichever is larger. + func (obj JSONWebEncryption) DecryptMulti(decryptionKey interface{}) (int, Header, []byte, error) { + globalHeaders := obj.mergedHeaders(nil) + +diff --git a/vendor/gopkg.in/square/go-jose.v2/encoding.go b/vendor/gopkg.in/square/go-jose.v2/encoding.go +index 40b688b..636f6c8 100644 +--- a/vendor/gopkg.in/square/go-jose.v2/encoding.go ++++ b/vendor/gopkg.in/square/go-jose.v2/encoding.go +@@ -21,6 +21,7 @@ import ( + "compress/flate" + "encoding/base64" + "encoding/binary" ++ "fmt" + "io" + "math/big" + "strings" +@@ -85,7 +86,7 @@ func decompress(algorithm CompressionAlgorithm, input []byte) ([]byte, error) { + } + } + +-// Compress with DEFLATE ++// deflate compresses the input. + func deflate(input []byte) ([]byte, error) { + output := new(bytes.Buffer) + +@@ -97,15 +98,27 @@ func deflate(input []byte) ([]byte, error) { + return output.Bytes(), err + } + +-// Decompress with DEFLATE ++// inflate decompresses the input. ++// ++// Errors if the decompressed data would be >250kB or >10x the size of the ++// compressed data, whichever is larger. + func inflate(input []byte) ([]byte, error) { + output := new(bytes.Buffer) + reader := flate.NewReader(bytes.NewBuffer(input)) + +- _, err := io.Copy(output, reader) +- if err != nil { ++ maxCompressedSize := 10 * int64(len(input)) ++ if maxCompressedSize < 250000 { ++ maxCompressedSize = 250000 ++ } ++ ++ limit := maxCompressedSize + 1 ++ n, err := io.CopyN(output, reader, limit) ++ if err != nil && err != io.EOF { + return nil, err + } ++ if n == limit { ++ return nil, fmt.Errorf("uncompressed data would be too large (>%d bytes)", maxCompressedSize) ++ } + + err = reader.Close() + return output.Bytes(), err diff --git a/SPECS/cert-manager/cert-manager.spec b/SPECS/cert-manager/cert-manager.spec index 28ccc114bca..de7595a54f5 100644 --- a/SPECS/cert-manager/cert-manager.spec +++ b/SPECS/cert-manager/cert-manager.spec @@ -1,7 +1,7 @@ Summary: Automatically provision and manage TLS certificates in Kubernetes Name: cert-manager Version: 1.11.2 -Release: 13%{?dist} +Release: 15%{?dist} License: ASL 2.0 Vendor: Microsoft Corporation Distribution: Mariner @@ -24,6 +24,10 @@ Patch1: CVE-2023-45288.patch Patch2: CVE-2024-26147.patch Patch3: CVE-2024-25620.patch Patch4: CVE-2024-6104.patch +Patch5: CVE-2023-3978.patch +Patch6: CVE-2024-24786.patch +Patch7: CVE-2024-28180.patch +Patch8: CVE-2023-2253.patch BuildRequires: golang Requires: %{name}-acmesolver Requires: %{name}-cainjector @@ -116,6 +120,12 @@ install -D -m0755 bin/webhook %{buildroot}%{_bindir}/ %{_bindir}/webhook %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 1.11.2-15 +- Bump release to rebuild with go 1.22.7 + +* Wed Aug 21 2024 Cameron Baird - 1.11.2-14 +- Patch for CVE-2023-3978, CVE-2024-24786, CVE-2024-28180, CVE-2023-2253 + * Mon Aug 19 2023 Bala - 1.11.2-13 - Patch for CVE-2024-6104 diff --git a/SPECS/cf-cli/CVE-2022-32149.patch b/SPECS/cf-cli/CVE-2022-32149.patch new file mode 100644 index 00000000000..e8fe13e3575 --- /dev/null +++ b/SPECS/cf-cli/CVE-2022-32149.patch @@ -0,0 +1,66 @@ +From 434eadcdbc3b0256971992e8c70027278364c72c Mon Sep 17 00:00:00 2001 +From: Roland Shoemaker +Date: Fri, 2 Sep 2022 09:35:37 -0700 +Subject: [PATCH] language: reject excessively large Accept-Language strings + +The BCP 47 tag parser has quadratic time complexity due to inherent +aspects of its design. Since the parser is, by design, exposed to +untrusted user input, this can be leveraged to force a program to +consume significant time parsing Accept-Language headers. + +The parser cannot be easily rewritten to fix this behavior for +various reasons. Instead the solution implemented in this CL is to +limit the total complexity of tags passed into ParseAcceptLanguage +by limiting the number of dashes in the string to 1000. This should +be more than enough for the majority of real world use cases, where +the number of tags being sent is likely to be in the single digits. + +Thanks to the OSS-Fuzz project for discovering this issue and to Adam +Korczynski (ADA Logics) for writing the fuzz case and for reporting the +issue. + +Fixes CVE-2022-32149 +Fixes golang/go#56152 + +Change-Id: I7bda1d84cee2b945039c203f26869d58ee9374ae +Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1565112 +Reviewed-by: Damien Neil +Reviewed-by: Tatiana Bradley +Reviewed-on: https://go-review.googlesource.com/c/text/+/442235 +TryBot-Result: Gopher Robot +Auto-Submit: Roland Shoemaker +Run-TryBot: Roland Shoemaker + +Modified to apply to vendored code by: Jiri Appl + - Adjusted paths + - Removed reference to parse_test.go +--- + vendor/golang.org/x/text/language/parse.go | 5 +++++ + 1 files changed, 18 insertions(+) + +diff --git a/vendor/golang.org/x/text/language/parse.go b/vendor/golang.org/x/text/language/parse.go +index 59b0410..b982d9e 100644 +--- a/vendor/golang.org/x/text/language/parse.go ++++ b/vendor/golang.org/x/text/language/parse.go +@@ -147,6 +147,7 @@ func update(b *language.Builder, part ...interface{}) (err error) { + } + + var errInvalidWeight = errors.New("ParseAcceptLanguage: invalid weight") ++var errTagListTooLarge = errors.New("tag list exceeds max length") + + // ParseAcceptLanguage parses the contents of an Accept-Language header as + // defined in http://www.ietf.org/rfc/rfc2616.txt and returns a list of Tags and +@@ -164,6 +165,10 @@ func ParseAcceptLanguage(s string) (tag []Tag, q []float32, err error) { + } + }() + ++ if strings.Count(s, "-") > 1000 { ++ return nil, nil, errTagListTooLarge ++ } ++ + var entry string + for s != "" { + if entry, s = split(s, ','); entry == "" { +-- +2.34.1 + diff --git a/SPECS/cf-cli/cf-cli.spec b/SPECS/cf-cli/cf-cli.spec index 5238cb5dcfa..041c316033d 100644 --- a/SPECS/cf-cli/cf-cli.spec +++ b/SPECS/cf-cli/cf-cli.spec @@ -1,7 +1,7 @@ Summary: The official command line client for Cloud Foundry. Name: cf-cli Version: 8.4.0 -Release: 19%{?dist} +Release: 21%{?dist} License: Apache-2.0 Vendor: Microsoft Corporation Distribution: Mariner @@ -30,6 +30,9 @@ Source1: cli-%{version}-vendor.tar.gz Patch0: CVE-2023-44487.patch Patch1: CVE-2021-44716.patch Patch2: CVE-2021-43565.patch +# Produced by git clone https://github.com/golang/text && cd text && +# git checkout 434eadcdbc3b0256971992e8c70027278364c72c && git format-patch -1 HEAD +Patch3: CVE-2022-32149.patch BuildRequires: golang %global debug_package %{nil} @@ -64,6 +67,12 @@ install -p -m 755 -t %{buildroot}%{_bindir} ./out/cf %{_bindir}/cf %changelog +* Tue Sep 17 2024 Jiri Appl - 8.4.0-21 +- Patch CVE-2022-32149 bringing upstream patch over the vendored golang.org/x/text module + +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 8.4.0-20 +- Bump release to rebuild with go 1.22.7 + * Mon Jul 22 2024 Archana Choudhary - 8.4.0-19.cm2 - Patch CVE-2021-43565 diff --git a/SPECS/cloud-hypervisor-cvm/0001-hypervisor-mshv-Fix-panic-when-rejecting-extended-gu.patch b/SPECS/cloud-hypervisor-cvm/0001-hypervisor-mshv-Fix-panic-when-rejecting-extended-gu.patch new file mode 100644 index 00000000000..096ad952db0 --- /dev/null +++ b/SPECS/cloud-hypervisor-cvm/0001-hypervisor-mshv-Fix-panic-when-rejecting-extended-gu.patch @@ -0,0 +1,32 @@ +From 234ac402dd04cac78033fb2334cdeb7d96526648 Mon Sep 17 00:00:00 2001 +From: Tom Dohrmann +Date: Wed, 14 Aug 2024 16:02:39 +0200 +Subject: [PATCH] hypervisor: mshv: Fix panic when rejecting extended guest + report + +swei2_rw_gpa_arg.data is an array of size 16 and value.to_le_bytes() is +only 8 bytes. + +Co-authored-by: Paul Meyer <49727155+katexochen@users.noreply.github.com> +Signed-off-by: Tom Dohrmann +--- + hypervisor/src/mshv/mod.rs | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/hypervisor/src/mshv/mod.rs b/hypervisor/src/mshv/mod.rs +index 62e0dfa5..5d23492f 100644 +--- a/hypervisor/src/mshv/mod.rs ++++ b/hypervisor/src/mshv/mod.rs +@@ -1012,7 +1012,8 @@ impl cpu::Vcpu for MshvVcpu { + byte_count: std::mem::size_of::() as u32, + ..Default::default() + }; +- swei2_rw_gpa_arg.data.copy_from_slice(&value.to_le_bytes()); ++ swei2_rw_gpa_arg.data[0..8] ++ .copy_from_slice(&value.to_le_bytes()); + self.fd + .gpa_write(&mut swei2_rw_gpa_arg) + .map_err(|e| cpu::HypervisorCpuError::GpaWrite(e.into()))?; +-- +2.39.4 + diff --git a/SPECS/cloud-hypervisor-cvm/cloud-hypervisor-cvm.signatures.json b/SPECS/cloud-hypervisor-cvm/cloud-hypervisor-cvm.signatures.json index 1e149de90d7..9efe9c19108 100644 --- a/SPECS/cloud-hypervisor-cvm/cloud-hypervisor-cvm.signatures.json +++ b/SPECS/cloud-hypervisor-cvm/cloud-hypervisor-cvm.signatures.json @@ -1,6 +1,6 @@ { "Signatures": { - "cloud-hypervisor-cvm-38.0.72.2-cargo.tar.gz": "12190a4f2fbd29b2c6c197388a958eab5dff91e8d75927841669d81d794eadf4", + "cloud-hypervisor-cvm-38.0.72.2-2-cargo.tar.gz": "68d1dc8f2a70fddad934e9131ccad7ce2c96323869433419e2f488062396bcc8", "cloud-hypervisor-cvm-38.0.72.2.tar.gz": "1a357a0805f7b6d90993d5ae246c2dedff88cf98c9c0eab0903dc8071be0dae2", "config.toml": "74c28b7520c157109b8990b325fe8f13504e56561a9bac51499d4c6bf4a66e52" } diff --git a/SPECS/cloud-hypervisor-cvm/cloud-hypervisor-cvm.spec b/SPECS/cloud-hypervisor-cvm/cloud-hypervisor-cvm.spec index 84841bfe584..9c73eab8a2e 100644 --- a/SPECS/cloud-hypervisor-cvm/cloud-hypervisor-cvm.spec +++ b/SPECS/cloud-hypervisor-cvm/cloud-hypervisor-cvm.spec @@ -5,7 +5,7 @@ Name: cloud-hypervisor-cvm Summary: Cloud Hypervisor CVM is an open source Virtual Machine Monitor (VMM) that enables running SEV SNP enabled VMs on top of MSHV using the IGVM file format as payload. Version: 38.0.72.2 -Release: 1%{?dist} +Release: 3%{?dist} License: ASL 2.0 OR BSD-3-clause Vendor: Microsoft Corporation Distribution: Mariner @@ -15,14 +15,23 @@ Source0: https://github.com/microsoft/cloud-hypervisor/archive/refs/tags/ %if 0%{?using_vendored_crates} # Note: the %%{name}-%%{version}-cargo.tar.gz file contains a cache created by capturing the contents downloaded into $CARGO_HOME. # To update the cache and config.toml run: -# tar -xf %{name}-%{version}.tar.gz -# cd %{name}-%{version} +# tar -xf %%{name}-%%{version}.tar.gz +# cd %%{name}-%%{version} +# patch -u -p0 < ../upgrade-openssl-to-3.3.2-to-address-CVE-2024-6119.patch # cargo vendor > config.toml -# tar -czf %{name}-%{version}-cargo.tar.gz vendor/ -# rename the tarball to %{name}-%{version}-cargo.tar.gz when updating version -Source1: %{name}-%{version}-cargo.tar.gz +# tar -czf %%{name}-%%{version}-cargo.tar.gz vendor/ +# rename the tarball to %%{name}-%%{version}-2-cargo.tar.gz when updating version +# (feel free to drop -2 and this comment on version change) +Source1: %{name}-%{version}-2-cargo.tar.gz Source2: config.toml %endif +# Generated using: +# tar -xf %%{name}-%%{version}.tar.gz +# cd %%{name}-%%{version} +# cargo update -p openssl-src --precise 300.3.2+3.3.2 +# diff -u ../cloud-hypervisor-msft-v38.0.72.2.backup/Cargo.lock Cargo.lock > ../upgrade-openssl-to-3.3.2-to-address-CVE-2024-6119.patch +Patch0: upgrade-openssl-to-3.3.2-to-address-CVE-2024-6119.patch +Patch1: 0001-hypervisor-mshv-Fix-panic-when-rejecting-extended-gu.patch Conflicts: cloud-hypervisor @@ -77,6 +86,9 @@ tar xf %{SOURCE1} mkdir -p .cargo cp %{SOURCE2} .cargo/ %endif +# The vendored archive has been populated based on the patch, so we need to +# repatch here as well in order to use the same versions +%autopatch -p1 %install install -d %{buildroot}%{_bindir} @@ -138,6 +150,12 @@ cargo build --release --target=%{rust_musl_target} %{cargo_pkg_feature_opts} %{c %license LICENSE-BSD-3-Clause %changelog +* Mon Sep 23 2024 Manuel Huber - 38.0.72.2-3 +- Add upstream patch to prevent crash + +* Tue Sep 17 2024 Jiri Appl - 38.0.72.2-2 +- Patch openssl in the vendored archive to 3.3.2 to address CVE-2024-6119 + * Thu Jul 04 2024 Archana Choudhary - 38.0.72.2-1 - Upgrade to v38.0.72.2 - Fixes CVE-2023-45853, CVE-2018-25032, CVE-2023-5363, CVE-2023-5678, CVE-2023-6129, CVE-2023-6237, CVE-2024-0727, CVE-2024-4603 diff --git a/SPECS/cloud-hypervisor-cvm/upgrade-openssl-to-3.3.2-to-address-CVE-2024-6119.patch b/SPECS/cloud-hypervisor-cvm/upgrade-openssl-to-3.3.2-to-address-CVE-2024-6119.patch new file mode 100644 index 00000000000..133532e02ea --- /dev/null +++ b/SPECS/cloud-hypervisor-cvm/upgrade-openssl-to-3.3.2-to-address-CVE-2024-6119.patch @@ -0,0 +1,14 @@ +--- a/../cloud-hypervisor-msft-v38.0.72.2.backup/Cargo.lock 2024-09-17 12:55:41.269905595 -0700 ++++ b/Cargo.lock 2024-09-17 13:49:15.579003678 -0700 +@@ -1421,9 +1421,9 @@ + + [[package]] + name = "openssl-src" +-version = "300.3.1+3.3.1" ++version = "300.3.2+3.3.2" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "7259953d42a81bf137fbbd73bd30a8e1914d6dce43c2b90ed575783a22608b91" ++checksum = "a211a18d945ef7e648cc6e0058f4c548ee46aab922ea203e0d30e966ea23647b" + dependencies = [ + "cc", + ] diff --git a/SPECS/cloud-init/0001-add-PPS-support-for-azure-proxy-agent.patch b/SPECS/cloud-init/0001-add-PPS-support-for-azure-proxy-agent.patch new file mode 100644 index 00000000000..016a6458fe7 --- /dev/null +++ b/SPECS/cloud-init/0001-add-PPS-support-for-azure-proxy-agent.patch @@ -0,0 +1,94 @@ +From 19442eedae2a3f96d424626dad20e037f10f147b Mon Sep 17 00:00:00 2001 +From: Ksenija Stanojevic +Date: Tue, 13 Aug 2024 09:44:25 -0700 +Subject: [PATCH] add PPS support for azure-proxy-agent + +--- + cloudinit/sources/DataSourceAzure.py | 23 +++++++++++++++++++++-- + cloudinit/sources/azure/errors.py | 5 +---- + tests/unittests/sources/test_azure.py | 5 ++++- + 3 files changed, 26 insertions(+), 7 deletions(-) + +diff --git a/cloudinit/sources/DataSourceAzure.py b/cloudinit/sources/DataSourceAzure.py +index c2f74e173..aed740b89 100644 +--- a/cloudinit/sources/DataSourceAzure.py ++++ b/cloudinit/sources/DataSourceAzure.py +@@ -504,15 +504,31 @@ class DataSourceAzure(sources.DataSource): + ] + out, err = subp.subp(cmd) + report_diagnostic_event( +- "Running azure-proxy-agent %s resulted" +- "in stderr output: %s with stdout: %s" % (cmd, err, out), ++ "Executing %s resulted " ++ "in stderr=%r with stdout=%r" % (cmd, err, out), + logger_func=LOG.debug, + ) + except subp.ProcessExecutionError as error: + if isinstance(error.reason, FileNotFoundError): ++ LOG.error( ++ "Failed to activate Azure Guest Proxy Agent: " ++ "azure-proxy-agent not found" ++ ) + report_error = errors.ReportableErrorProxyAgentNotFound() + self._report_failure(report_error) + else: ++ report_diagnostic_event( ++ "Failed to activate Azure Guest Proxy Agent: " ++ "status check failed " ++ "cmd=%r stderr=%r stdout=%r exit_code=%s" ++ % ( ++ error.cmd, ++ error.stderr, ++ error.stdout, ++ error.exit_code, ++ ), ++ logger_func=LOG.error, ++ ) + reportable_error = ( + errors.ReportableErrorProxyAgentStatusFailure(error) + ) +@@ -637,6 +653,9 @@ class DataSourceAzure(sources.DataSource): + self._wait_for_pps_unknown_reuse() + + md, userdata_raw, cfg, files = self._reprovision() ++ if cfg.get("ProvisionGuestProxyAgent"): ++ self._check_azure_proxy_agent_status() ++ + # fetch metadata again as it has changed after reprovisioning + imds_md = self.get_metadata_from_imds(report_failure=True) + +diff --git a/cloudinit/sources/azure/errors.py b/cloudinit/sources/azure/errors.py +index b331cd686..6595ceda9 100644 +--- a/cloudinit/sources/azure/errors.py ++++ b/cloudinit/sources/azure/errors.py +@@ -155,10 +155,7 @@ class ReportableErrorUnhandledException(ReportableError): + + class ReportableErrorProxyAgentNotFound(ReportableError): + def __init__(self) -> None: +- super().__init__( +- "Unable to activate Azure Guest Proxy Agent." +- "azure-proxy-agent not found" +- ) ++ super().__init__("azure-proxy-agent not found") + + + class ReportableErrorProxyAgentStatusFailure(ReportableError): +diff --git a/tests/unittests/sources/test_azure.py b/tests/unittests/sources/test_azure.py +index 9b6672e1e..446d5bf31 100644 +--- a/tests/unittests/sources/test_azure.py ++++ b/tests/unittests/sources/test_azure.py +@@ -4532,7 +4532,10 @@ class TestCheckAzureProxyAgent: + subp.SubpResult("Guest Proxy Agent running", ""), + ] + self.azure_ds._check_azure_proxy_agent_status() +- assert "Running azure-proxy-agent" in self.caplog.text ++ assert ( ++ "Executing ['azure-proxy-agent', '--status', '--wait', '120']" ++ in self.caplog.text ++ ) + assert self.mock_wrapping_report_failure.mock_calls == [] + + def test_check_azure_proxy_agent_status_notfound(self): +-- +2.34.1 + diff --git a/SPECS/cloud-init/0001-feat-azure-Add-ProvisionGuestProxyAgent-OVF-setting.patch b/SPECS/cloud-init/0001-feat-azure-Add-ProvisionGuestProxyAgent-OVF-setting.patch new file mode 100644 index 00000000000..2031eeeb0c9 --- /dev/null +++ b/SPECS/cloud-init/0001-feat-azure-Add-ProvisionGuestProxyAgent-OVF-setting.patch @@ -0,0 +1,114 @@ +From 402e9331a72d543e779898667488a51ad3e3ec13 Mon Sep 17 00:00:00 2001 +From: Ksenija Stanojevic +Date: Fri, 9 Feb 2024 13:32:19 -0800 +Subject: [PATCH 1/3] feat(azure): Add ProvisionGuestProxyAgent OVF setting + (#4860) + +Add ProvisionGuestProxyAgent Boolean configuration setting into the OvfEnv class. +This PR is only logging the value of ProvisionGuestProxyAgent. +--- + cloudinit/sources/DataSourceAzure.py | 6 ++++++ + cloudinit/sources/helpers/azure.py | 8 ++++++++ + tests/unittests/sources/test_azure.py | 15 +++++++++++++++ + 3 files changed, 29 insertions(+) + +diff --git a/cloudinit/sources/DataSourceAzure.py b/cloudinit/sources/DataSourceAzure.py +index 5a82aa34e..dc2b79a3a 100644 +--- a/cloudinit/sources/DataSourceAzure.py ++++ b/cloudinit/sources/DataSourceAzure.py +@@ -1784,6 +1784,12 @@ def read_azure_ovf(contents): + "PreprovisionedVMType: %s" % ovf_env.preprovisioned_vm_type, + logger_func=LOG.info, + ) ++ ++ cfg["ProvisionGuestProxyAgent"] = ovf_env.provision_guest_proxy_agent ++ report_diagnostic_event( ++ "ProvisionGuestProxyAgent: %s" % ovf_env.provision_guest_proxy_agent, ++ logger_func=LOG.info, ++ ) + return (md, ud, cfg) + + +diff --git a/cloudinit/sources/helpers/azure.py b/cloudinit/sources/helpers/azure.py +index 6e5c1f433..2847a9e53 100644 +--- a/cloudinit/sources/helpers/azure.py ++++ b/cloudinit/sources/helpers/azure.py +@@ -1064,6 +1064,7 @@ class OvfEnvXml: + public_keys: Optional[List[dict]] = None, + preprovisioned_vm: bool = False, + preprovisioned_vm_type: Optional[str] = None, ++ provision_guest_proxy_agent: bool = False, + ) -> None: + self.username = username + self.password = password +@@ -1073,6 +1074,7 @@ class OvfEnvXml: + self.public_keys: List[dict] = public_keys or [] + self.preprovisioned_vm = preprovisioned_vm + self.preprovisioned_vm_type = preprovisioned_vm_type ++ self.provision_guest_proxy_agent = provision_guest_proxy_agent + + def __eq__(self, other) -> bool: + return self.__dict__ == other.__dict__ +@@ -1216,6 +1218,12 @@ class OvfEnvXml: + "PreprovisionedVMType", + required=False, + ) ++ self.provision_guest_proxy_agent = self._parse_property( ++ platform_settings, ++ "ProvisionGuestProxyAgent", ++ default=False, ++ required=False, ++ ) + + def _parse_ssh_section(self, config_set): + self.public_keys = [] +diff --git a/tests/unittests/sources/test_azure.py b/tests/unittests/sources/test_azure.py +index 1ddbd3f39..6afde95fd 100644 +--- a/tests/unittests/sources/test_azure.py ++++ b/tests/unittests/sources/test_azure.py +@@ -356,6 +356,7 @@ def construct_ovf_env( + disable_ssh_password_auth=None, + preprovisioned_vm=None, + preprovisioned_vm_type=None, ++ provision_guest_proxy_agent=None, + ): + content = [ + '', +@@ -426,6 +427,11 @@ def construct_ovf_env( + "%s" + % preprovisioned_vm_type + ) ++ if provision_guest_proxy_agent is not None: ++ content.append( ++ "%s" ++ % provision_guest_proxy_agent ++ ) + content += [ + "", + "", +@@ -1316,6 +1322,7 @@ scbus-1 on xpt0 bus 0 + expected_cfg = { + "PreprovisionedVMType": None, + "PreprovisionedVm": False, ++ "ProvisionGuestProxyAgent": False, + "system_info": {"default_user": {"name": "myuser"}}, + } + expected_metadata = { +@@ -2668,6 +2675,14 @@ class TestPreprovisioningReadAzureOvfFlag(CiTestCase): + self.assertTrue(cfg["PreprovisionedVm"]) + self.assertEqual("Savable", cfg["PreprovisionedVMType"]) + ++ def test_read_azure_ovf_with_proxy_guest_agent(self): ++ """The read_azure_ovf method should set ProvisionGuestProxyAgent ++ cfg flag to True.""" ++ content = construct_ovf_env(provision_guest_proxy_agent=True) ++ ret = dsaz.read_azure_ovf(content) ++ cfg = ret[2] ++ self.assertTrue(cfg["ProvisionGuestProxyAgent"]) ++ + + @pytest.mark.parametrize( + "ovf_cfg,imds_md,pps_type", +-- +2.34.1 + diff --git a/SPECS/cloud-init/0002-feat-azure-parse-ProvisionGuestProxyAgent-as-bool-51.patch b/SPECS/cloud-init/0002-feat-azure-parse-ProvisionGuestProxyAgent-as-bool-51.patch new file mode 100644 index 00000000000..f61cbc5b10f --- /dev/null +++ b/SPECS/cloud-init/0002-feat-azure-parse-ProvisionGuestProxyAgent-as-bool-51.patch @@ -0,0 +1,54 @@ +From e3ba5800d26065df9ce03ee2ac58ec6f08506423 Mon Sep 17 00:00:00 2001 +From: Ksenija Stanojevic +Date: Fri, 5 Apr 2024 16:52:26 -0700 +Subject: [PATCH 2/3] feat(azure): parse ProvisionGuestProxyAgent as bool + (#5126) + +--- + cloudinit/sources/helpers/azure.py | 1 + + tests/unittests/sources/test_azure.py | 12 ++++++++++-- + 2 files changed, 11 insertions(+), 2 deletions(-) + +diff --git a/cloudinit/sources/helpers/azure.py b/cloudinit/sources/helpers/azure.py +index 2847a9e53..165f47429 100644 +--- a/cloudinit/sources/helpers/azure.py ++++ b/cloudinit/sources/helpers/azure.py +@@ -1221,6 +1221,7 @@ class OvfEnvXml: + self.provision_guest_proxy_agent = self._parse_property( + platform_settings, + "ProvisionGuestProxyAgent", ++ parse_bool=True, + default=False, + required=False, + ) +diff --git a/tests/unittests/sources/test_azure.py b/tests/unittests/sources/test_azure.py +index 6afde95fd..255991ec3 100644 +--- a/tests/unittests/sources/test_azure.py ++++ b/tests/unittests/sources/test_azure.py +@@ -2675,13 +2675,21 @@ class TestPreprovisioningReadAzureOvfFlag(CiTestCase): + self.assertTrue(cfg["PreprovisionedVm"]) + self.assertEqual("Savable", cfg["PreprovisionedVMType"]) + +- def test_read_azure_ovf_with_proxy_guest_agent(self): ++ def test_read_azure_ovf_with_proxy_guest_agent_true(self): + """The read_azure_ovf method should set ProvisionGuestProxyAgent + cfg flag to True.""" + content = construct_ovf_env(provision_guest_proxy_agent=True) + ret = dsaz.read_azure_ovf(content) + cfg = ret[2] +- self.assertTrue(cfg["ProvisionGuestProxyAgent"]) ++ assert cfg["ProvisionGuestProxyAgent"] is True ++ ++ def test_read_azure_ovf_with_proxy_guest_agent_false(self): ++ """The read_azure_ovf method should set ProvisionGuestProxyAgent ++ cfg flag to False.""" ++ content = construct_ovf_env(provision_guest_proxy_agent=False) ++ ret = dsaz.read_azure_ovf(content) ++ cfg = ret[2] ++ assert cfg["ProvisionGuestProxyAgent"] is False + + + @pytest.mark.parametrize( +-- +2.34.1 + diff --git a/SPECS/cloud-init/0003-feat-azure-add-support-for-azure-proxy-agent.patch b/SPECS/cloud-init/0003-feat-azure-add-support-for-azure-proxy-agent.patch new file mode 100644 index 00000000000..fd1bc8a9417 --- /dev/null +++ b/SPECS/cloud-init/0003-feat-azure-add-support-for-azure-proxy-agent.patch @@ -0,0 +1,408 @@ +From 8932242a65bae5504ba45134091767f215a441fa Mon Sep 17 00:00:00 2001 +From: Ksenija Stanojevic +Date: Mon, 15 Jul 2024 18:48:19 -0700 +Subject: [PATCH 3/3] feat(azure): add support for azure-proxy-agent + +NOTE change for azurelinux : + +This patch has some addtional modifications in the test_azure.py. Those changes remove +some tests which would fail to run: +1. removing unit tests for imds.headers_cb in test_no_pps, which is not implement +in our current version of cloud-init +2. remove checking for distro=self.azure_ds.distro in test_no_pps, this is due to +a behavior difference in mock_azure_get_metadata_from_fabric which would not return +self.azure_ds.distro +3. remove mock_report_dmesg_to_kvp test in test_no_pps, as mock_report_dmesg_to_kvp is not +implemented in our current version of cloud-init + +--- + cloudinit/sources/DataSourceAzure.py | 40 ++++ + cloudinit/sources/azure/errors.py | 19 +- + tests/unittests/sources/test_azure.py | 254 ++++++++++++++++++++++++++ + 3 files changed, 312 insertions(+), 1 deletion(-) + +diff --git a/cloudinit/sources/DataSourceAzure.py b/cloudinit/sources/DataSourceAzure.py +index dc2b79a3a..c2f74e173 100644 +--- a/cloudinit/sources/DataSourceAzure.py ++++ b/cloudinit/sources/DataSourceAzure.py +@@ -483,6 +483,41 @@ class DataSourceAzure(sources.DataSource): + or self._ephemeral_dhcp_ctx.lease is None + ) + ++ def _check_azure_proxy_agent_status(self) -> None: ++ """Check if azure-proxy-agent is ready for communication with WS/IMDS. ++ If ProvisionGuestProxyAgent is true, query azure-proxy-agent status, ++ waiting up to 120 seconds for the proxy to negotiate with Wireserver ++ and configure an eBPF proxy. Once azure-proxy-agent is ready, ++ it will exit with code 0 and cloud-init can then expect to be able to ++ communicate with these services. ++ Fail deployment if azure-proxy-agent is not found or otherwise returns ++ an error. ++ For more information, check out: ++ https://github.com/azure/guestproxyagent ++ """ ++ try: ++ cmd = [ ++ "azure-proxy-agent", ++ "--status", ++ "--wait", ++ "120", ++ ] ++ out, err = subp.subp(cmd) ++ report_diagnostic_event( ++ "Running azure-proxy-agent %s resulted" ++ "in stderr output: %s with stdout: %s" % (cmd, err, out), ++ logger_func=LOG.debug, ++ ) ++ except subp.ProcessExecutionError as error: ++ if isinstance(error.reason, FileNotFoundError): ++ report_error = errors.ReportableErrorProxyAgentNotFound() ++ self._report_failure(report_error) ++ else: ++ reportable_error = ( ++ errors.ReportableErrorProxyAgentStatusFailure(error) ++ ) ++ self._report_failure(reportable_error) ++ + @azure_ds_telemetry_reporter + def crawl_metadata(self): + """Walk all instance metadata sources returning a dict on success. +@@ -566,6 +601,11 @@ class DataSourceAzure(sources.DataSource): + + imds_md = {} + if self._is_ephemeral_networking_up(): ++ # check if azure-proxy-agent is enabled in the ovf-env.xml file. ++ # azure-proxy-agent feature is opt-in and disabled by default. ++ if cfg.get("ProvisionGuestProxyAgent"): ++ self._check_azure_proxy_agent_status() ++ + imds_md = self.get_metadata_from_imds(report_failure=True) + + if not imds_md and ovf_source is None: +diff --git a/cloudinit/sources/azure/errors.py b/cloudinit/sources/azure/errors.py +index 966725b00..b331cd686 100644 +--- a/cloudinit/sources/azure/errors.py ++++ b/cloudinit/sources/azure/errors.py +@@ -12,7 +12,7 @@ from typing import Any, Dict, List, Optional + + import requests + +-from cloudinit import version ++from cloudinit import subp, version + from cloudinit.sources.azure import identity + from cloudinit.url_helper import UrlError + +@@ -151,3 +151,20 @@ class ReportableErrorUnhandledException(ReportableError): + + self.supporting_data["exception"] = repr(exception) + self.supporting_data["traceback_base64"] = trace_base64 ++ ++ ++class ReportableErrorProxyAgentNotFound(ReportableError): ++ def __init__(self) -> None: ++ super().__init__( ++ "Unable to activate Azure Guest Proxy Agent." ++ "azure-proxy-agent not found" ++ ) ++ ++ ++class ReportableErrorProxyAgentStatusFailure(ReportableError): ++ def __init__(self, exception: subp.ProcessExecutionError) -> None: ++ super().__init__("azure-proxy-agent status failure") ++ ++ self.supporting_data["exit_code"] = exception.exit_code ++ self.supporting_data["stdout"] = exception.stdout ++ self.supporting_data["stderr"] = exception.stderr +diff -ruN a/tests/unittests/sources/test_azure.py b/tests/unittests/sources/test_azure.py +--- a/tests/unittests/sources/test_azure.py 2023-08-28 09:20:24.000000000 -0700 ++++ b/tests/unittests/sources/test_azure.py 2024-09-06 11:30:27.992040291 -0700 +@@ -1,6 +1,7 @@ + # This file is part of cloud-init. See LICENSE file for license information. + + import copy ++import datetime + import json + import os + import stat +@@ -49,6 +50,16 @@ + + + @pytest.fixture ++def mock_wrapping_report_failure(azure_ds): ++ with mock.patch.object( ++ azure_ds, ++ "_report_failure", ++ wraps=azure_ds._report_failure, ++ ) as m: ++ yield m ++ ++ ++@pytest.fixture + def mock_azure_helper_readurl(): + with mock.patch( + "cloudinit.sources.helpers.azure.url_helper.readurl", autospec=True +@@ -254,6 +265,14 @@ + + + @pytest.fixture ++def mock_timestamp(): ++ timestamp = datetime.datetime.utcnow() ++ with mock.patch.object(errors, "datetime", autospec=True) as m: ++ m.utcnow.return_value = timestamp ++ yield timestamp ++ ++ ++@pytest.fixture + def mock_util_ensure_dir(): + with mock.patch( + MOCKPATH + "util.ensure_dir", +@@ -3649,6 +3668,76 @@ + } + + def test_no_pps(self): ++ ovf = construct_ovf_env(provision_guest_proxy_agent=False) ++ md, ud, cfg = dsaz.read_azure_ovf(ovf) ++ self.mock_util_mount_cb.return_value = (md, ud, cfg, {}) ++ self.mock_readurl.side_effect = [ ++ mock.MagicMock(contents=json.dumps(self.imds_md).encode()), ++ ] ++ self.mock_azure_get_metadata_from_fabric.return_value = [] ++ ++ self.azure_ds._check_and_get_data() ++ ++ assert self.mock_subp_subp.mock_calls == [] ++ ++ # Verify DHCP is setup once. ++ assert self.mock_wrapping_setup_ephemeral_networking.mock_calls == [ ++ mock.call(timeout_minutes=20) ++ ] ++ assert self.mock_net_dhcp_maybe_perform_dhcp_discovery.mock_calls == [ ++ mock.call( ++ self.azure_ds.distro, ++ None, ++ dsaz.dhcp_log_cb, ++ ) ++ ] ++ assert self.azure_ds._wireserver_endpoint == "10.11.12.13" ++ assert self.azure_ds._is_ephemeral_networking_up() is False ++ ++ # Verify DMI usage. ++ assert self.mock_dmi_read_dmi_data.mock_calls == [ ++ mock.call("chassis-asset-tag"), ++ mock.call("system-uuid"), ++ ] ++ assert ( ++ self.azure_ds.metadata["instance-id"] ++ == "50109936-ef07-47fe-ac82-890c853f60d5" ++ ) ++ ++ # Verify IMDS metadata. ++ assert self.azure_ds.metadata["imds"] == self.imds_md ++ ++ # Verify reporting ready once. ++ assert self.mock_azure_get_metadata_from_fabric.mock_calls == [ ++ mock.call( ++ endpoint="10.11.12.13", ++ iso_dev="/dev/sr0", ++ pubkey_info=None, ++ ) ++ ] ++ ++ # Verify netlink. ++ assert self.mock_netlink.mock_calls == [] ++ ++ # Verify no reported_ready marker written. ++ assert self.wrapped_util_write_file.mock_calls == [] ++ assert self.patched_reported_ready_marker_path.exists() is False ++ ++ # Verify reports via KVP. ++ assert len(self.mock_kvp_report_failure_to_host.mock_calls) == 0 ++ assert len(self.mock_azure_report_failure_to_fabric.mock_calls) == 0 ++ assert len(self.mock_kvp_report_success_to_host.mock_calls) == 1 ++ ++ ++ def test_no_pps_gpa(self): ++ """test full provisioning scope when azure-proxy-agent ++ is enabled and running.""" ++ self.mock_subp_subp.side_effect = [ ++ subp.SubpResult("Guest Proxy Agent running", ""), ++ ] ++ ovf = construct_ovf_env(provision_guest_proxy_agent=True) ++ md, ud, cfg = dsaz.read_azure_ovf(ovf) ++ self.mock_util_mount_cb.return_value = (md, ud, cfg, {}) + self.mock_readurl.side_effect = [ + mock.MagicMock(contents=json.dumps(self.imds_md).encode()), + ] +@@ -3656,6 +3745,11 @@ + + self.azure_ds._check_and_get_data() + ++ assert self.mock_subp_subp.mock_calls == [ ++ mock.call( ++ ["azure-proxy-agent", "--status", "--wait", "120"], ++ ), ++ ] + assert self.mock_readurl.mock_calls == [ + mock.call( + "http://169.254.169.254/metadata/instance?" +@@ -3713,6 +3807,92 @@ + + # Verify reports via KVP. + assert len(self.mock_kvp_report_failure_to_host.mock_calls) == 0 ++ assert len(self.mock_azure_report_failure_to_fabric.mock_calls) == 0 ++ assert len(self.mock_kvp_report_success_to_host.mock_calls) == 1 ++ ++ def test_no_pps_gpa_fail(self): ++ """test full provisioning scope when azure-proxy-agent is enabled and ++ throwing an exception during provisioning.""" ++ self.mock_subp_subp.side_effect = [ ++ subp.ProcessExecutionError( ++ cmd=["failed", "azure-proxy-agent"], ++ stdout="test_stdout", ++ stderr="test_stderr", ++ exit_code=4, ++ ), ++ ] ++ ovf = construct_ovf_env(provision_guest_proxy_agent=True) ++ md, ud, cfg = dsaz.read_azure_ovf(ovf) ++ self.mock_util_mount_cb.return_value = (md, ud, cfg, {}) ++ self.mock_readurl.side_effect = [ ++ mock.MagicMock(contents=json.dumps(self.imds_md).encode()), ++ ] ++ self.mock_azure_get_metadata_from_fabric.return_value = [] ++ ++ self.azure_ds._check_and_get_data() ++ assert self.mock_subp_subp.mock_calls == [ ++ mock.call( ++ ["azure-proxy-agent", "--status", "--wait", "120"], ++ ), ++ ] ++ assert self.mock_readurl.mock_calls == [ ++ mock.call( ++ "http://169.254.169.254/metadata/instance?" ++ "api-version=2021-08-01&extended=true", ++ timeout=30, ++ headers={"Metadata": "true"}, ++ exception_cb=mock.ANY, ++ infinite=True, ++ log_req_resp=True, ++ ), ++ ] ++ ++ # Verify DHCP is setup once. ++ assert self.mock_wrapping_setup_ephemeral_networking.mock_calls == [ ++ mock.call(timeout_minutes=20) ++ ] ++ assert self.mock_net_dhcp_maybe_perform_dhcp_discovery.mock_calls == [ ++ mock.call( ++ self.azure_ds.distro, ++ None, ++ dsaz.dhcp_log_cb, ++ ) ++ ] ++ assert self.azure_ds._wireserver_endpoint == "10.11.12.13" ++ assert self.azure_ds._is_ephemeral_networking_up() is False ++ ++ # Verify DMI usage. ++ assert self.mock_dmi_read_dmi_data.mock_calls == [ ++ mock.call("chassis-asset-tag"), ++ mock.call("system-uuid"), ++ mock.call("system-uuid"), ++ ] ++ assert ( ++ self.azure_ds.metadata["instance-id"] ++ == "50109936-ef07-47fe-ac82-890c853f60d5" ++ ) ++ ++ # Verify IMDS metadata. ++ assert self.azure_ds.metadata["imds"] == self.imds_md ++ ++ ### BACKPORT NOTE: 23.3 _will_ report ready later after failure. ++ ### In newer versions there will be no call to report ready after failure. ++ assert self.mock_azure_get_metadata_from_fabric.mock_calls == [ ++ mock.call( ++ endpoint="10.11.12.13", iso_dev="/dev/sr0", pubkey_info=None ++ ) ++ ] ++ ++ # Verify netlink. ++ assert self.mock_netlink.mock_calls == [] ++ ++ # Verify no reported_ready marker written. ++ assert self.wrapped_util_write_file.mock_calls == [] ++ assert self.patched_reported_ready_marker_path.exists() is False ++ ++ # Verify reports via KVP. ++ assert len(self.mock_kvp_report_failure_to_host.mock_calls) == 1 ++ assert len(self.mock_azure_report_failure_to_fabric.mock_calls) == 1 + assert len(self.mock_kvp_report_success_to_host.mock_calls) == 1 + + def test_running_pps(self): +@@ -4292,6 +4472,64 @@ + assert len(self.mock_kvp_report_success_to_host.mock_calls) == 1 + + ++class TestCheckAzureProxyAgent: ++ @pytest.fixture(autouse=True) ++ def proxy_setup( ++ self, ++ azure_ds, ++ mock_subp_subp, ++ caplog, ++ mock_wrapping_report_failure, ++ mock_timestamp, ++ ): ++ self.azure_ds = azure_ds ++ self.mock_subp_subp = mock_subp_subp ++ self.caplog = caplog ++ self.mock_wrapping_report_failure = mock_wrapping_report_failure ++ self.mock_timestamp = mock_timestamp ++ ++ def test_check_azure_proxy_agent_status(self): ++ self.mock_subp_subp.side_effect = [ ++ subp.SubpResult("Guest Proxy Agent running", ""), ++ ] ++ self.azure_ds._check_azure_proxy_agent_status() ++ assert "Running azure-proxy-agent" in self.caplog.text ++ assert self.mock_wrapping_report_failure.mock_calls == [] ++ ++ def test_check_azure_proxy_agent_status_notfound(self): ++ exception = subp.ProcessExecutionError(reason=FileNotFoundError()) ++ self.mock_subp_subp.side_effect = [ ++ exception, ++ ] ++ self.azure_ds._check_azure_proxy_agent_status() ++ assert "azure-proxy-agent not found" in self.caplog.text ++ assert self.mock_wrapping_report_failure.mock_calls == [ ++ mock.call( ++ errors.ReportableErrorProxyAgentNotFound(), ++ ), ++ ] ++ ++ def test_check_azure_proxy_agent_status_failure(self): ++ exception = subp.ProcessExecutionError( ++ cmd=["failed", "azure-proxy-agent"], ++ stdout="test_stdout", ++ stderr="test_stderr", ++ exit_code=4, ++ ) ++ self.mock_subp_subp.side_effect = [ ++ exception, ++ ] ++ self.azure_ds._check_azure_proxy_agent_status() ++ assert "azure-proxy-agent status failure" in self.caplog.text ++ assert self.mock_wrapping_report_failure.mock_calls == [ ++ mock.call( ++ errors.ReportableErrorProxyAgentStatusFailure( ++ exception=exception ++ ), ++ ), ++ ] ++ ++ + class TestGetMetadataFromImds: + @pytest.mark.parametrize("report_failure", [False, True]) + @pytest.mark.parametrize( +-- +2.34.1 + diff --git a/SPECS/cloud-init/cloud-init.spec b/SPECS/cloud-init/cloud-init.spec index ffe61e76ee8..04e50b4f6a8 100644 --- a/SPECS/cloud-init/cloud-init.spec +++ b/SPECS/cloud-init/cloud-init.spec @@ -5,7 +5,7 @@ Summary: Cloud instance init scripts Name: cloud-init Epoch: 1 Version: %{package_version} -Release: 3%{?dist} +Release: 5%{?dist} License: GPLv3 Vendor: Microsoft Corporation Distribution: Mariner @@ -16,6 +16,10 @@ Source1: 10-azure-kvp.cfg Patch0: overrideDatasourceDetection.patch Patch1: exec_cmd_error_handling.patch Patch2: Add-Network-Interface-Renaming-Support-for-CAPM3-Met.patch +Patch3: 0001-feat-azure-Add-ProvisionGuestProxyAgent-OVF-setting.patch +Patch4: 0002-feat-azure-parse-ProvisionGuestProxyAgent-as-bool-51.patch +Patch5: 0003-feat-azure-add-support-for-azure-proxy-agent.patch +Patch6: 0001-add-PPS-support-for-azure-proxy-agent.patch %define cl_services cloud-config.service cloud-config.target cloud-final.service cloud-init.service cloud-init.target cloud-init-local.service BuildRequires: automake BuildRequires: dbus @@ -151,7 +155,13 @@ make check %{?_smp_mflags} %config(noreplace) %{_sysconfdir}/cloud/cloud.cfg.d/10-azure-kvp.cfg %changelog -* Wed May 8 2024 Sharath Srikanth Chellappa - 1:23.3-3 +* Fri Sep 13 2024 Minghe Ren - 1:23.3-5 +- Add patche to have PPS support for azure-proxy-agent. + +* Wed Sep 04 2024 Minghe Ren - 1:23.3-4 +- Add patches to support azure-proxy-agent. + +* Wed May 08 2024 Sharath Srikanth Chellappa - 1:23.3-3 - Add patch to add network interface renaming support for CAPM3 Met. * Wed Apr 03 2024 Rachel Menge - 1:23.3-2 diff --git a/SPECS/cmake/CVE-2023-27533.patch b/SPECS/cmake/CVE-2023-27533.patch new file mode 100644 index 00000000000..93fc34e7737 --- /dev/null +++ b/SPECS/cmake/CVE-2023-27533.patch @@ -0,0 +1,60 @@ +From 7aee1a49cb796ad199f02746222808d3313fbe9b Mon Sep 17 00:00:00 2001 +From: Suresh Thelkar +Date: Tue, 17 Sep 2024 12:38:59 +0530 +Subject: [PATCH] Backporting patch for CVE-2023-27533 + +Upstream patch details are given below. +https://github.com/curl/curl/pull/10728/commits +--- + Utilities/cmcurl/lib/telnet.c | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/Utilities/cmcurl/lib/telnet.c b/Utilities/cmcurl/lib/telnet.c +index fdd137fb..c8af4c95 100644 +--- a/Utilities/cmcurl/lib/telnet.c ++++ b/Utilities/cmcurl/lib/telnet.c +@@ -770,6 +770,17 @@ static void printsub(struct Curl_easy *data, + } + } + ++static bool str_is_nonascii(const char *str) ++{ ++ size_t len = strlen(str); ++ while(len--) { ++ if(*str & 0x80) ++ return TRUE; ++ str++; ++ } ++ return FALSE; ++} ++ + static CURLcode check_telnet_options(struct Curl_easy *data) + { + struct curl_slist *head; +@@ -784,6 +795,8 @@ static CURLcode check_telnet_options(struct Curl_easy *data) + /* Add the user name as an environment variable if it + was given on the command line */ + if(conn->bits.user_passwd) { ++ if(str_is_nonascii(conn->user)) ++ return CURLE_BAD_FUNCTION_ARGUMENT; + msnprintf(option_arg, sizeof(option_arg), "USER,%s", conn->user); + beg = curl_slist_append(tn->telnet_vars, option_arg); + if(!beg) { +@@ -796,6 +809,14 @@ static CURLcode check_telnet_options(struct Curl_easy *data) + } + + for(head = data->set.telnet_options; head; head = head->next) { ++ char *option = head->data; ++ char *arg; ++ char *sep = strchr(option, '='); ++ if(sep) { ++ arg = ++sep; ++ if(str_is_nonascii(arg)) ++ continue; ++ } + if(sscanf(head->data, "%127[^= ]%*[ =]%255s", + option_keyword, option_arg) == 2) { + +-- +2.34.1 + diff --git a/SPECS/cmake/CVE-2023-27534.patch b/SPECS/cmake/CVE-2023-27534.patch new file mode 100644 index 00000000000..044957fbe13 --- /dev/null +++ b/SPECS/cmake/CVE-2023-27534.patch @@ -0,0 +1,119 @@ +From 851e92133dcb67015af8f7d3402fb58fa5df051e Mon Sep 17 00:00:00 2001 +From: Suresh Thelkar +Date: Wed, 18 Sep 2024 15:14:00 +0530 +Subject: [PATCH] Patch for CVE-2023-27534 + +Upstream patch details are given below. +https://github.com/curl/curl/pull/10729/commits/01345b13d4c4d1222387f5c02dfb6244a9cade33#diff-86c8ab4ca5332fd50f646ad37656e92fc41839ba34e0ddab1ec7728439cbe5f1 +--- + Utilities/cmcurl/lib/curl_path.c | 72 ++++++++++++++++---------------- + 1 file changed, 36 insertions(+), 36 deletions(-) + +diff --git a/Utilities/cmcurl/lib/curl_path.c b/Utilities/cmcurl/lib/curl_path.c +index 65106188..28eb41ad 100644 +--- a/Utilities/cmcurl/lib/curl_path.c ++++ b/Utilities/cmcurl/lib/curl_path.c +@@ -30,6 +30,8 @@ + #include "escape.h" + #include "memdebug.h" + ++#define MAX_SSHPATH_LEN 100000 /* arbitrary */ ++ + /* figure out the path to work with in this particular request */ + CURLcode Curl_getworkingpath(struct Curl_easy *data, + char *homedir, /* when SFTP is used */ +@@ -39,57 +41,55 @@ CURLcode Curl_getworkingpath(struct Curl_easy *data, + char *real_path = NULL; + char *working_path; + size_t working_path_len; ++ struct dynbuf npath; + CURLcode result = + Curl_urldecode(data, data->state.up.path, 0, &working_path, + &working_path_len, REJECT_ZERO); + if(result) + return result; + ++ /* new path to switch to in case we need to */ ++ Curl_dyn_init(&npath, MAX_SSHPATH_LEN); ++ + /* Check for /~/, indicating relative to the user's home directory */ +- if(data->conn->handler->protocol & CURLPROTO_SCP) { +- real_path = malloc(working_path_len + 1); +- if(!real_path) { ++ if((data->conn->handler->protocol & CURLPROTO_SCP) && ++ (working_path_len > 3) && (!memcmp(working_path, "/~/", 3))) { ++ /* It is referenced to the home directory, so strip the leading '/~/' */ ++ if(Curl_dyn_addn(&npath, &working_path[3], working_path_len - 3)) { + free(working_path); + return CURLE_OUT_OF_MEMORY; + } +- if((working_path_len > 3) && (!memcmp(working_path, "/~/", 3))) +- /* It is referenced to the home directory, so strip the leading '/~/' */ +- memcpy(real_path, working_path + 3, working_path_len - 2); +- else +- memcpy(real_path, working_path, 1 + working_path_len); + } +- else if(data->conn->handler->protocol & CURLPROTO_SFTP) { +- if((working_path_len > 1) && (working_path[1] == '~')) { +- size_t homelen = strlen(homedir); +- real_path = malloc(homelen + working_path_len + 1); +- if(!real_path) { +- free(working_path); +- return CURLE_OUT_OF_MEMORY; +- } +- /* It is referenced to the home directory, so strip the +- leading '/' */ +- memcpy(real_path, homedir, homelen); +- real_path[homelen] = '/'; +- real_path[homelen + 1] = '\0'; +- if(working_path_len > 3) { +- memcpy(real_path + homelen + 1, working_path + 3, +- 1 + working_path_len -3); +- } ++ else if((data->conn->handler->protocol & CURLPROTO_SFTP) && ++ (working_path_len > 2) && !memcmp(working_path, "/~/", 3)) { ++ size_t len; ++ const char *p; ++ int copyfrom = 3; ++ if(Curl_dyn_add(&npath, homedir)) { ++ free(working_path); ++ return CURLE_OUT_OF_MEMORY; + } +- else { +- real_path = malloc(working_path_len + 1); +- if(!real_path) { +- free(working_path); +- return CURLE_OUT_OF_MEMORY; +- } +- memcpy(real_path, working_path, 1 + working_path_len); ++ /* Copy a separating '/' if homedir does not end with one */ ++ len = Curl_dyn_len(&npath); ++ p = Curl_dyn_ptr(&npath); ++ if(len && (p[len-1] != '/')) ++ copyfrom = 2; ++ ++ if(Curl_dyn_addn(&npath, ++ &working_path[copyfrom], working_path_len - copyfrom)) { ++ free(working_path); ++ return CURLE_OUT_OF_MEMORY; + } + } + +- free(working_path); +- +- /* store the pointer for the caller to receive */ +- *path = real_path; ++ if(Curl_dyn_len(&npath)) { ++ free(working_path); ++ ++ /* store the pointer for the caller to receive */ ++ *path = Curl_dyn_ptr(&npath); ++ } ++ else ++ *path = working_path + + return CURLE_OK; + } +-- +2.34.1 + diff --git a/SPECS/cmake/cmake.spec b/SPECS/cmake/cmake.spec index 3bf920bff39..5a4cf0f5655 100644 --- a/SPECS/cmake/cmake.spec +++ b/SPECS/cmake/cmake.spec @@ -2,7 +2,7 @@ Summary: Cmake Name: cmake Version: 3.21.4 -Release: 11%{?dist} +Release: 12%{?dist} License: BSD AND LGPLv2+ Vendor: Microsoft Corporation Distribution: Mariner @@ -21,6 +21,8 @@ Patch6: CVE-2023-38545.patch Patch7: CVE-2023-38546.patch Patch8: cve-2023-44487.patch Patch9: CVE-2023-28320.patch +Patch10: CVE-2023-27533.patch +Patch11: CVE-2023-27534.patch BuildRequires: bzip2 BuildRequires: bzip2-devel BuildRequires: curl @@ -86,6 +88,9 @@ bin/ctest --force-new-ctest-process --rerun-failed --output-on-failure %{_prefix}/doc/%{name}-*/* %changelog +* Wed Sep 18 2024 Suresh Thelkar - 3.21.4-12 +- Patch CVE-2023-27533 and CVE-2023-27534 + * Fri Jul 26 2024 Zhichun Wan - 3.21.4-11 - Patch CVE-2023-28320.patch diff --git a/SPECS/cni-plugins/cni-plugins.spec b/SPECS/cni-plugins/cni-plugins.spec index 8427f8eeb2a..fb6fbf1ffc5 100644 --- a/SPECS/cni-plugins/cni-plugins.spec +++ b/SPECS/cni-plugins/cni-plugins.spec @@ -1,7 +1,7 @@ Summary: Container Network Interface (CNI) plugins Name: cni-plugins Version: 1.3.0 -Release: 4%{?dist} +Release: 5%{?dist} License: ASL 2.0 Vendor: Microsoft Corporation Distribution: Mariner @@ -39,6 +39,9 @@ make -k check |& tee %{_specdir}/%{name}-check-log || %{nocheck} %{_default_cni_plugins_dir}/* %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 1.3.0-5 +- Bump release to rebuild with go 1.22.7 + * Wed Jul 17 2024 Muhammad Falak R Wani - 1.3.0-4 - Drop requirement on a specific version of golang diff --git a/SPECS/cni/cni.spec b/SPECS/cni/cni.spec index 9ea0223e0a3..2ec686611e9 100644 --- a/SPECS/cni/cni.spec +++ b/SPECS/cni/cni.spec @@ -24,7 +24,7 @@ Summary: Container Network Interface - networking for Linux containers Name: cni Version: 1.0.1 -Release: 17%{?dist} +Release: 18%{?dist} License: Apache-2.0 Vendor: Microsoft Corporation Distribution: Mariner @@ -113,6 +113,9 @@ install -m 755 -d "%{buildroot}%{cni_doc_dir}" %{_sbindir}/cnitool %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 1.0.1-18 +- Bump release to rebuild with go 1.22.7 + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 1.0.1-17 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS/containerized-data-importer/CVE-2022-32149.patch b/SPECS/containerized-data-importer/CVE-2022-32149.patch new file mode 100644 index 00000000000..9c597159cee --- /dev/null +++ b/SPECS/containerized-data-importer/CVE-2022-32149.patch @@ -0,0 +1,59 @@ +From 434eadcdbc3b0256971992e8c70027278364c72c Mon Sep 17 00:00:00 2001 +From: Roland Shoemaker +Date: Fri, 2 Sep 2022 09:35:37 -0700 +Subject: [PATCH] language: reject excessively large Accept-Language strings + +The BCP 47 tag parser has quadratic time complexity due to inherent +aspects of its design. Since the parser is, by design, exposed to +untrusted user input, this can be leveraged to force a program to +consume significant time parsing Accept-Language headers. + +The parser cannot be easily rewritten to fix this behavior for +various reasons. Instead the solution implemented in this CL is to +limit the total complexity of tags passed into ParseAcceptLanguage +by limiting the number of dashes in the string to 1000. This should +be more than enough for the majority of real world use cases, where +the number of tags being sent is likely to be in the single digits. + +Thanks to the OSS-Fuzz project for discovering this issue and to Adam +Korczynski (ADA Logics) for writing the fuzz case and for reporting the +issue. + +Fixes CVE-2022-32149 +Fixes golang/go#56152 + +Change-Id: I7bda1d84cee2b945039c203f26869d58ee9374ae +Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1565112 +Reviewed-by: Damien Neil +Reviewed-by: Tatiana Bradley +Reviewed-on: https://go-review.googlesource.com/c/text/+/442235 +TryBot-Result: Gopher Robot +Auto-Submit: Roland Shoemaker +Run-TryBot: Roland Shoemaker +--- + vendor/golang.org/x/text/language/parse.go | 5 +++++ + 1 files changed, 5 insertions(+) + +diff --git a/vendor/golang.org/x/text/language/parse.go b/vendor/golang.org/x/text/language/parse.go +index 59b04100..b982d9e4 100644 +--- a/vendor/golang.org/x/text/language/parse.go ++++ b/vendor/golang.org/x/text/language/parse.go +@@ -147,6 +147,7 @@ func update(b *language.Builder, part ...interface{}) (err error) { + } + + var errInvalidWeight = errors.New("ParseAcceptLanguage: invalid weight") ++var errTagListTooLarge = errors.New("tag list exceeds max length") + + // ParseAcceptLanguage parses the contents of an Accept-Language header as + // defined in http://www.ietf.org/rfc/rfc2616.txt and returns a list of Tags and +@@ -164,6 +165,10 @@ func ParseAcceptLanguage(s string) (tag []Tag, q []float32, err error) { + } + }() + ++ if strings.Count(s, "-") > 1000 { ++ return nil, nil, errTagListTooLarge ++ } ++ + var entry string + for s != "" { + if entry, s = split(s, ','); entry == "" { diff --git a/SPECS/containerized-data-importer/CVE-2022-41717.patch b/SPECS/containerized-data-importer/CVE-2022-41717.patch new file mode 100644 index 00000000000..8a9227ad35c --- /dev/null +++ b/SPECS/containerized-data-importer/CVE-2022-41717.patch @@ -0,0 +1,70 @@ +From 1e63c2f08a10a150fa02c50ece89b340ae64efe4 Mon Sep 17 00:00:00 2001 +From: Damien Neil +Date: Tue, 06 Dec 2022 11:57:53 -0800 +Subject: [PATCH] http2: limit canonical header cache by bytes, not entries + +The canonical header cache is a per-connection cache mapping header +keys to their canonicalized form. (For example, "foo-bar" => "Foo-Bar"). +We limit the number of entries in the cache to prevent an attacker +from consuming unbounded amounts of memory by sending many unique +keys, but a small number of very large keys can still consume an +unreasonable amount of memory. + +Track the amount of memory consumed by the cache and limit it based +on memory rather than number of entries. + +Thanks to Josselin Costanzi for reporting this issue. + +For golang/go#56350 + +Change-Id: I41db4c9823ed5bf371a9881accddff1268489b16 +Reviewed-on: https://go-review.googlesource.com/c/net/+/455635 +Reviewed-by: Jenny Rakoczy +Run-TryBot: Damien Neil +TryBot-Result: Gopher Robot +--- + +diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go +index e35a76c..4eb7617 100644 +--- a/vendor/golang.org/x/net/http2/server.go ++++ b/vendor/golang.org/x/net/http2/server.go +@@ -527,6 +527,7 @@ + headerTableSize uint32 + peerMaxHeaderListSize uint32 // zero means unknown (default) + canonHeader map[string]string // http2-lower-case -> Go-Canonical-Case ++ canonHeaderKeysSize int // canonHeader keys size in bytes + writingFrame bool // started writing a frame (on serve goroutine or separate) + writingFrameAsync bool // started a frame on its own goroutine but haven't heard back on wroteFrameCh + needsFrameFlush bool // last frame write wasn't a flush +@@ -766,6 +767,13 @@ + } + } + ++// maxCachedCanonicalHeadersKeysSize is an arbitrarily-chosen limit on the size ++// of the entries in the canonHeader cache. ++// This should be larger than the size of unique, uncommon header keys likely to ++// be sent by the peer, while not so high as to permit unreasonable memory usage ++// if the peer sends an unbounded number of unique header keys. ++const maxCachedCanonicalHeadersKeysSize = 2048 ++ + func (sc *serverConn) canonicalHeader(v string) string { + sc.serveG.check() + buildCommonHeaderMapsOnce() +@@ -781,14 +789,10 @@ + sc.canonHeader = make(map[string]string) + } + cv = http.CanonicalHeaderKey(v) +- // maxCachedCanonicalHeaders is an arbitrarily-chosen limit on the number of +- // entries in the canonHeader cache. This should be larger than the number +- // of unique, uncommon header keys likely to be sent by the peer, while not +- // so high as to permit unreasonable memory usage if the peer sends an unbounded +- // number of unique header keys. +- const maxCachedCanonicalHeaders = 32 +- if len(sc.canonHeader) < maxCachedCanonicalHeaders { ++ size := 100 + len(v)*2 // 100 bytes of map overhead + key + value ++ if sc.canonHeaderKeysSize+size <= maxCachedCanonicalHeadersKeysSize { + sc.canonHeader[v] = cv ++ sc.canonHeaderKeysSize += size + } + return cv + } diff --git a/SPECS/containerized-data-importer/CVE-2024-28180.patch b/SPECS/containerized-data-importer/CVE-2024-28180.patch new file mode 100644 index 00000000000..8a093225a92 --- /dev/null +++ b/SPECS/containerized-data-importer/CVE-2024-28180.patch @@ -0,0 +1,180 @@ +From 0dd4dd541c665fb292d664f77604ba694726f298 Mon Sep 17 00:00:00 2001 +From: Jacob Hoffman-Andrews +Date: Thu, 7 Mar 2024 14:25:21 -0800 +Subject: [PATCH] v2: backport decompression limit fix (#109) + +Backport from #107. +--- + CHANGELOG.md | 84 ++++++++++++++++++++++++++++++++++++++++++++++++ + crypter.go | 6 ++++ + encoding.go | 21 +++++++++--- + encoding_test.go | 34 ++++++++++++++++++++ + 4 files changed, 141 insertions(+), 4 deletions(-) + create mode 100644 CHANGELOG.md + +diff --git a/CHANGELOG.md b/CHANGELOG.md +new file mode 100644 +index 0000000..8e6e913 +--- /dev/null ++++ b/CHANGELOG.md +@@ -0,0 +1,84 @@ ++# v4.0.1 ++ ++## Fixed ++ ++ - An attacker could send a JWE containing compressed data that used large ++ amounts of memory and CPU when decompressed by `Decrypt` or `DecryptMulti`. ++ Those functions now return an error if the decompressed data would exceed ++ 250kB or 10x the compressed size (whichever is larger). Thanks to ++ Enze Wang@Alioth and Jianjun Chen@Zhongguancun Lab (@zer0yu and @chenjj) ++ for reporting. ++ ++# v4.0.0 ++ ++This release makes some breaking changes in order to more thoroughly ++address the vulnerabilities discussed in [Three New Attacks Against JSON Web ++Tokens][1], "Sign/encrypt confusion", "Billion hash attack", and "Polyglot ++token". ++ ++## Changed ++ ++ - Limit JWT encryption types (exclude password or public key types) (#78) ++ - Enforce minimum length for HMAC keys (#85) ++ - jwt: match any audience in a list, rather than requiring all audiences (#81) ++ - jwt: accept only Compact Serialization (#75) ++ - jws: Add expected algorithms for signatures (#74) ++ - Require specifying expected algorithms for ParseEncrypted, ++ ParseSigned, ParseDetached, jwt.ParseEncrypted, jwt.ParseSigned, ++ jwt.ParseSignedAndEncrypted (#69, #74) ++ - Usually there is a small, known set of appropriate algorithms for a program ++ to use and it's a mistake to allow unexpected algorithms. For instance the ++ "billion hash attack" relies in part on programs accepting the PBES2 ++ encryption algorithm and doing the necessary work even if they weren't ++ specifically configured to allow PBES2. ++ - Revert "Strip padding off base64 strings" (#82) ++ - The specs require base64url encoding without padding. ++ - Minimum supported Go version is now 1.21 ++ ++## Added ++ ++ - ParseSignedCompact, ParseSignedJSON, ParseEncryptedCompact, ParseEncryptedJSON. ++ - These allow parsing a specific serialization, as opposed to ParseSigned and ++ ParseEncrypted, which try to automatically detect which serialization was ++ provided. It's common to require a specific serialization for a specific ++ protocol - for instance JWT requires Compact serialization. ++ ++[1]: https://i.blackhat.com/BH-US-23/Presentations/US-23-Tervoort-Three-New-Attacks-Against-JSON-Web-Tokens.pdf ++ ++# v3.0.3 ++ ++## Fixed ++ ++ - Limit decompression output size to prevent a DoS. Backport from v4.0.1. ++ ++# v3.0.2 ++ ++## Fixed ++ ++ - DecryptMulti: handle decompression error (#19) ++ ++## Changed ++ ++ - jwe/CompactSerialize: improve performance (#67) ++ - Increase the default number of PBKDF2 iterations to 600k (#48) ++ - Return the proper algorithm for ECDSA keys (#45) ++ ++## Added ++ ++ - Add Thumbprint support for opaque signers (#38) ++ ++# v3.0.1 ++ ++## Fixed ++ ++ - Security issue: an attacker specifying a large "p2c" value can cause ++ JSONWebEncryption.Decrypt and JSONWebEncryption.DecryptMulti to consume large ++ amounts of CPU, causing a DoS. Thanks to Matt Schwager (@mschwager) for the ++ disclosure and to Tom Tervoort for originally publishing the category of attack. ++ https://i.blackhat.com/BH-US-23/Presentations/US-23-Tervoort-Three-New-Attacks-Against-JSON-Web-Tokens.pdf ++ ++# v2.6.3 ++ ++## Fixed ++ ++ - Limit decompression output size to prevent a DoS. Backport from v4.0.1. +diff --git a/vendor/gopkg.in/square/go-jose.v2/crypter.go b/vendor/gopkg.in/square/go-jose.v2/crypter.go +index 73aab0f..0ae2e5e 100644 +--- a/vendor/gopkg.in/square/go-jose.v2/crypter.go ++++ b/vendor/gopkg.in/square/go-jose.v2/crypter.go +@@ -406,6 +406,9 @@ func (ctx *genericEncrypter) Options() EncrypterOptions { + // Decrypt and validate the object and return the plaintext. Note that this + // function does not support multi-recipient, if you desire multi-recipient + // decryption use DecryptMulti instead. ++// ++// Automatically decompresses plaintext, but returns an error if the decompressed ++// data would be >250kB or >10x the size of the compressed data, whichever is larger. + func (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error) { + headers := obj.mergedHeaders(nil) + +@@ -470,6 +473,9 @@ func (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error) + // with support for multiple recipients. It returns the index of the recipient + // for which the decryption was successful, the merged headers for that recipient, + // and the plaintext. ++// ++// Automatically decompresses plaintext, but returns an error if the decompressed ++// data would be >250kB or >3x the size of the compressed data, whichever is larger. + func (obj JSONWebEncryption) DecryptMulti(decryptionKey interface{}) (int, Header, []byte, error) { + globalHeaders := obj.mergedHeaders(nil) + +diff --git a/vendor/gopkg.in/square/go-jose.v2/encoding.go b/vendor/gopkg.in/square/go-jose.v2/encoding.go +index 40b688b..636f6c8 100644 +--- a/vendor/gopkg.in/square/go-jose.v2/encoding.go ++++ b/vendor/gopkg.in/square/go-jose.v2/encoding.go +@@ -21,6 +21,7 @@ import ( + "compress/flate" + "encoding/base64" + "encoding/binary" ++ "fmt" + "io" + "math/big" + "strings" +@@ -85,7 +86,7 @@ func decompress(algorithm CompressionAlgorithm, input []byte) ([]byte, error) { + } + } + +-// Compress with DEFLATE ++// deflate compresses the input. + func deflate(input []byte) ([]byte, error) { + output := new(bytes.Buffer) + +@@ -97,15 +98,27 @@ func deflate(input []byte) ([]byte, error) { + return output.Bytes(), err + } + +-// Decompress with DEFLATE ++// inflate decompresses the input. ++// ++// Errors if the decompressed data would be >250kB or >10x the size of the ++// compressed data, whichever is larger. + func inflate(input []byte) ([]byte, error) { + output := new(bytes.Buffer) + reader := flate.NewReader(bytes.NewBuffer(input)) + +- _, err := io.Copy(output, reader) +- if err != nil { ++ maxCompressedSize := 10 * int64(len(input)) ++ if maxCompressedSize < 250000 { ++ maxCompressedSize = 250000 ++ } ++ ++ limit := maxCompressedSize + 1 ++ n, err := io.CopyN(output, reader, limit) ++ if err != nil && err != io.EOF { + return nil, err + } ++ if n == limit { ++ return nil, fmt.Errorf("uncompressed data would be too large (>%d bytes)", maxCompressedSize) ++ } + + err = reader.Close() + return output.Bytes(), err diff --git a/SPECS/containerized-data-importer/containerized-data-importer.spec b/SPECS/containerized-data-importer/containerized-data-importer.spec index 99bef2011b7..fc6de401ba8 100644 --- a/SPECS/containerized-data-importer/containerized-data-importer.spec +++ b/SPECS/containerized-data-importer/containerized-data-importer.spec @@ -18,7 +18,7 @@ Summary: Container native virtualization Name: containerized-data-importer Version: 1.55.0 -Release: 19%{?dist} +Release: 21%{?dist} License: ASL 2.0 Vendor: Microsoft Corporation Distribution: Mariner @@ -35,6 +35,9 @@ Provides: cdi = %{version}-%{release} ExclusiveArch: x86_64 aarch64 Patch0: CVE-2023-44487.patch Patch1: CVE-2024-3727.patch +Patch2: CVE-2022-41717.patch +Patch3: CVE-2022-32149.patch +Patch4: CVE-2024-28180.patch %description Containerized-Data-Importer (CDI) is a persistent storage management add-on for Kubernetes @@ -202,6 +205,14 @@ install -m 0644 _out/manifests/release/cdi-cr.yaml %{buildroot}%{_datadir}/cdi/m %{_datadir}/cdi/manifests %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 1.55.0-21 +- Bump release to rebuild with go 1.22.7 + +* Wed Aug 06 2024 Brian Fjeldstad - 1.55.0-20 +- Address CVE-2022-41717 +- Address CVE-2022-32149 +- Address CVE-2024-28180 + * Thu Jun 06 2024 Brian Fjeldstad - 1.55.0-19 - Address CVE-2024-3727 by patching vendored github.com/containers/image diff --git a/SPECS/coredns/coredns.spec b/SPECS/coredns/coredns.spec index 70917ebc1c7..3108cb1d631 100644 --- a/SPECS/coredns/coredns.spec +++ b/SPECS/coredns/coredns.spec @@ -3,7 +3,7 @@ Summary: Fast and flexible DNS server Name: coredns Version: 1.11.1 -Release: 10%{?dist} +Release: 11%{?dist} License: Apache License 2.0 Vendor: Microsoft Corporation Distribution: Mariner @@ -74,6 +74,9 @@ install -p -m 755 -t %{buildroot}%{_bindir} %{name} %{_bindir}/%{name} %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 1.11.1-11 +- Bump release to rebuild with go 1.22.7 + * Wed Jul 17 2024 Muhammad Falak R Wani - 1.11.1-10 - Drop requirement on a specific version of golang diff --git a/SPECS/cri-o/CVE-2022-32149.patch b/SPECS/cri-o/CVE-2022-32149.patch new file mode 100644 index 00000000000..1b7c9c922af --- /dev/null +++ b/SPECS/cri-o/CVE-2022-32149.patch @@ -0,0 +1,68 @@ +From b293cbe0fda9dcbedf27b41767d0b19e08ef51c6 Mon Sep 17 00:00:00 2001 +From: Sindhu Karri +Date: Fri, 13 Sep 2024 06:35:51 +0000 +Subject: [PATCH] Fix CVE-2022-32149 + +--- +From 434eadcdbc3b0256971992e8c70027278364c72c Mon Sep 17 00:00:00 2001 +From: Roland Shoemaker +Date: Fri, 2 Sep 2022 09:35:37 -0700 +Subject: [PATCH] language: reject excessively large Accept-Language strings + +The BCP 47 tag parser has quadratic time complexity due to inherent +aspects of its design. Since the parser is, by design, exposed to +untrusted user input, this can be leveraged to force a program to +consume significant time parsing Accept-Language headers. + +The parser cannot be easily rewritten to fix this behavior for +various reasons. Instead the solution implemented in this CL is to +limit the total complexity of tags passed into ParseAcceptLanguage +by limiting the number of dashes in the string to 1000. This should +be more than enough for the majority of real world use cases, where +the number of tags being sent is likely to be in the single digits. + +Thanks to the OSS-Fuzz project for discovering this issue and to Adam +Korczynski (ADA Logics) for writing the fuzz case and for reporting the +issue. + +Fixes CVE-2022-32149 +Fixes golang/go#56152 + +Change-Id: I7bda1d84cee2b945039c203f26869d58ee9374ae +Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1565112 +Reviewed-by: Damien Neil +Reviewed-by: Tatiana Bradley +Reviewed-on: https://go-review.googlesource.com/c/text/+/442235 +TryBot-Result: Gopher Robot +Auto-Submit: Roland Shoemaker +Run-TryBot: Roland Shoemaker +--- + vendor/golang.org/x/text/language/parse.go | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/vendor/golang.org/x/text/language/parse.go b/vendor/golang.org/x/text/language/parse.go +index 11acfd8..3bba19f 100644 +--- a/vendor/golang.org/x/text/language/parse.go ++++ b/vendor/golang.org/x/text/language/parse.go +@@ -133,6 +133,7 @@ func update(b *language.Builder, part ...interface{}) (err error) { + } + + var errInvalidWeight = errors.New("ParseAcceptLanguage: invalid weight") ++var errTagListTooLarge = errors.New("tag list exceeds max length") + + // ParseAcceptLanguage parses the contents of an Accept-Language header as + // defined in http://www.ietf.org/rfc/rfc2616.txt and returns a list of Tags and +@@ -142,6 +143,10 @@ var errInvalidWeight = errors.New("ParseAcceptLanguage: invalid weight") + // Tags with a weight of zero will be dropped. An error will be returned if the + // input could not be parsed. + func ParseAcceptLanguage(s string) (tag []Tag, q []float32, err error) { ++ if strings.Count(s, "-") > 1000 { ++ return nil, nil, errTagListTooLarge ++ } ++ + var entry string + for s != "" { + if entry, s = split(s, ','); entry == "" { +-- +2.33.8 + diff --git a/SPECS/cri-o/cri-o.spec b/SPECS/cri-o/cri-o.spec index e64bfb2cb60..a4bd3fe899f 100644 --- a/SPECS/cri-o/cri-o.spec +++ b/SPECS/cri-o/cri-o.spec @@ -26,7 +26,7 @@ Summary: OCI-based implementation of Kubernetes Container Runtime Interfa # Define macros for further referenced sources Name: cri-o Version: 1.22.3 -Release: 6%{?dist} +Release: 8%{?dist} License: ASL 2.0 Vendor: Microsoft Corporation Distribution: Mariner @@ -67,6 +67,7 @@ Patch11: CVE-2024-3154.patch Patch12: CVE-2024-3727.patch Patch13: CVE-2021-43565.patch Patch14: CVE-2024-6104.patch +Patch15: CVE-2022-32149.patch BuildRequires: btrfs-progs-devel BuildRequires: device-mapper-devel BuildRequires: fdupes @@ -219,6 +220,12 @@ mkdir -p /opt/cni/bin %{_fillupdir}/sysconfig.kubelet %changelog +* Thu Sep 12 2024 Sindhu Karri - 1.22.3-8 +- Patch CVE-2022-32149 + +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 1.22.3-7 +- Bump release to rebuild with go 1.22.7 + * Thu Aug 01 2024 Bala - 1.22.3-6 - Patch CVE-2024-6104 diff --git a/SPECS/cri-tools/cri-tools.spec b/SPECS/cri-tools/cri-tools.spec index 3d71383c42e..d80306151ef 100644 --- a/SPECS/cri-tools/cri-tools.spec +++ b/SPECS/cri-tools/cri-tools.spec @@ -7,7 +7,7 @@ Summary: CRI tools Name: cri-tools Version: 1.29.0 -Release: 3%{?dist} +Release: 4%{?dist} License: Apache-2.0 Vendor: Microsoft Corporation Distribution: Mariner @@ -46,6 +46,9 @@ install -p -m 755 -t %{buildroot}%{_bindir} "${BUILD_FOLDER}/critest" %{_bindir}/critest %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 1.29.0-4 +- Bump release to rebuild with go 1.22.7 + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 1.29.0-3 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS/csi-driver-lvm/csi-driver-lvm.spec b/SPECS/csi-driver-lvm/csi-driver-lvm.spec index d0abb402a1d..c68b3a354b0 100644 --- a/SPECS/csi-driver-lvm/csi-driver-lvm.spec +++ b/SPECS/csi-driver-lvm/csi-driver-lvm.spec @@ -1,7 +1,7 @@ Summary: Container storage interface for logical volume management Name: csi-driver-lvm Version: 0.4.1 -Release: 16%{?dist} +Release: 17%{?dist} License: MIT Vendor: Microsoft Corporation Distribution: Mariner @@ -70,6 +70,9 @@ install -D -m0755 bin/lvmplugin %{buildroot}%{_bindir}/ %{_bindir}/lvmplugin %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 0.4.1-17 +- Bump release to rebuild with go 1.22.7 + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 0.4.1-16 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS/curl/CVE-2024-6197.patch b/SPECS/curl/CVE-2024-6197.patch new file mode 100644 index 00000000000..d65b828d359 --- /dev/null +++ b/SPECS/curl/CVE-2024-6197.patch @@ -0,0 +1,21 @@ +From 3a537a4db9e65e545ec45b1b5d5575ee09a2569d Mon Sep 17 00:00:00 2001 +From: z2_ <88509734+z2-2z@users.noreply.github.com> +Date: Fri, 28 Jun 2024 14:45:47 +0200 +Subject: [PATCH] x509asn1: remove superfluous free() + +--- + lib/vtls/x509asn1.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/lib/vtls/x509asn1.c b/lib/vtls/x509asn1.c +index f71ab0b90a5931..1bc4243ddae343 100644 +--- a/lib/vtls/x509asn1.c ++++ b/lib/vtls/x509asn1.c +@@ -390,7 +390,6 @@ utf8asn1str(struct dynbuf *to, int type, const char *from, const char *end) + if(wc >= 0x00000800) { + if(wc >= 0x00010000) { + if(wc >= 0x00200000) { +- free(buf); + /* Invalid char. size for target encoding. */ + return CURLE_WEIRD_SERVER_REPLY; + } diff --git a/SPECS/curl/curl.spec b/SPECS/curl/curl.spec index 8925abc73f6..c4d5b5fb2dd 100644 --- a/SPECS/curl/curl.spec +++ b/SPECS/curl/curl.spec @@ -1,13 +1,14 @@ Summary: An URL retrieval utility and library Name: curl Version: 8.8.0 -Release: 1%{?dist} +Release: 2%{?dist} License: curl Vendor: Microsoft Corporation Distribution: Mariner Group: System Environment/NetworkingLibraries URL: https://curl.haxx.se Source0: https://curl.haxx.se/download/%{name}-%{version}.tar.gz +Patch0: CVE-2024-6197.patch BuildRequires: krb5-devel BuildRequires: libssh2-devel BuildRequires: nghttp2-devel @@ -85,6 +86,9 @@ find %{buildroot} -type f -name "*.la" -delete -print %{_libdir}/libcurl.so.* %changelog +* Wed Sep 4 2024 Aadhar Agarwal - 8.8.0-2 +- Patch CVE-2024-6197 + * Mon Jul 15 2024 Muhammad Falak - 8.8.0-1 - Bump version to 8.8.0 to address CVE-2024-2398 diff --git a/SPECS/dcos-cli/dcos-cli.spec b/SPECS/dcos-cli/dcos-cli.spec index baaee408de4..f5f474f9ec9 100644 --- a/SPECS/dcos-cli/dcos-cli.spec +++ b/SPECS/dcos-cli/dcos-cli.spec @@ -1,7 +1,7 @@ Summary: The command line for DC/OS Name: dcos-cli Version: 1.2.0 -Release: 17%{?dist} +Release: 18%{?dist} License: Apache-2.0 Vendor: Microsoft Corporation Distribution: Mariner @@ -45,6 +45,9 @@ go test -mod=vendor %{_bindir}/dcos %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 1.2.0-18 +- Bump release to rebuild with go 1.22.7 + * Wed Jul 17 2024 Muhammad Falak R Wani - 1.2.0-17 - Drop requirement on a specific version of golang diff --git a/SPECS/edk2/CVE-2022-36763.patch b/SPECS/edk2/CVE-2022-36763.patch new file mode 100644 index 00000000000..0efce427602 --- /dev/null +++ b/SPECS/edk2/CVE-2022-36763.patch @@ -0,0 +1,2526 @@ +From 1deb95a849d6071427bef6804fced194d7928916 Mon Sep 17 00:00:00 2001 +From: "Douglas Flick [MSFT]" +Date: Fri, 12 Jan 2024 02:16:01 +0800 +Subject: [PATCH 1/6] SecurityPkg: DxeTpm2MeasureBootLib: SECURITY PATCH 4117 - + CVE 2022-36763 + +This commit contains the patch files and tests for DxeTpm2MeasureBootLib +CVE 2022-36763. + +Cc: Jiewen Yao + +Signed-off-by: Doug Flick [MSFT] +--- + .../DxeTpm2MeasureBootLib.c | 69 ++-- + .../DxeTpm2MeasureBootLib.inf | 4 +- + .../DxeTpm2MeasureBootLibSanitization.c | 275 ++++++++++++++++ + .../DxeTpm2MeasureBootLibSanitization.h | 113 +++++++ + .../DxeTpm2MeasureBootLibSanitizationTest.c | 303 ++++++++++++++++++ + ...Tpm2MeasureBootLibSanitizationTestHost.inf | 28 ++ + .../DxeTpmMeasureBootLibSanitizationTest.c | 301 +++++++++++++++++ + ...eTpmMeasureBootLibSanitizationTestHost.inf | 28 ++ + SecurityPkg/SecurityPkg.ci.yaml | 1 + + SecurityPkg/Test/SecurityPkgHostTest.dsc | 1 + + 10 files changed, 1093 insertions(+), 30 deletions(-) + create mode 100644 SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c + create mode 100644 SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h + create mode 100644 SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c + create mode 100644 SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTestHost.inf + create mode 100644 SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c + create mode 100644 SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTestHost.inf + +diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c +index 36a256a..0475103 100644 +--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c ++++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c +@@ -20,6 +20,8 @@ Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
+ (C) Copyright 2015 Hewlett Packard Enterprise Development LP
+ SPDX-License-Identifier: BSD-2-Clause-Patent + ++Copyright (c) Microsoft Corporation.
++SPDX-License-Identifier: BSD-2-Clause-Patent + **/ + + #include +@@ -44,6 +46,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent + #include + #include + ++#include "DxeTpm2MeasureBootLibSanitization.h" ++ + typedef struct { + EFI_TCG2_PROTOCOL *Tcg2Protocol; + EFI_CC_MEASUREMENT_PROTOCOL *CcProtocol; +@@ -144,10 +148,11 @@ Tcg2MeasureGptTable ( + EFI_TCG2_EVENT *Tcg2Event; + EFI_CC_EVENT *CcEvent; + EFI_GPT_DATA *GptData; +- UINT32 EventSize; ++ UINT32 TcgEventSize; + EFI_TCG2_PROTOCOL *Tcg2Protocol; + EFI_CC_MEASUREMENT_PROTOCOL *CcProtocol; + EFI_CC_MR_INDEX MrIndex; ++ UINT32 AllocSize; + + if (mTcg2MeasureGptCount > 0) { + return EFI_SUCCESS; +@@ -195,25 +200,22 @@ Tcg2MeasureGptTable ( + BlockIo->Media->BlockSize, + (UINT8 *)PrimaryHeader + ); +- if (EFI_ERROR (Status)) { +- DEBUG ((DEBUG_ERROR, "Failed to Read Partition Table Header!\n")); ++ if (EFI_ERROR (Status) || EFI_ERROR (SanitizeEfiPartitionTableHeader (PrimaryHeader, BlockIo))) { ++ DEBUG ((DEBUG_ERROR, "Failed to read Partition Table Header or invalid Partition Table Header!\n")); + FreePool (PrimaryHeader); + return EFI_DEVICE_ERROR; + } + + // +- // PrimaryHeader->SizeOfPartitionEntry should not be zero ++ // Read the partition entry. + // +- if (PrimaryHeader->SizeOfPartitionEntry == 0) { +- DEBUG ((DEBUG_ERROR, "SizeOfPartitionEntry should not be zero!\n")); ++ Status = SanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSize); ++ if (EFI_ERROR (Status)) { + FreePool (PrimaryHeader); + return EFI_BAD_BUFFER_SIZE; + } + +- // +- // Read the partition entry. +- // +- EntryPtr = (UINT8 *)AllocatePool (PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry); ++ EntryPtr = (UINT8 *)AllocatePool (AllocSize); + if (EntryPtr == NULL) { + FreePool (PrimaryHeader); + return EFI_OUT_OF_RESOURCES; +@@ -223,7 +225,7 @@ Tcg2MeasureGptTable ( + DiskIo, + BlockIo->Media->MediaId, + MultU64x32 (PrimaryHeader->PartitionEntryLBA, BlockIo->Media->BlockSize), +- PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry, ++ AllocSize, + EntryPtr + ); + if (EFI_ERROR (Status)) { +@@ -248,16 +250,21 @@ Tcg2MeasureGptTable ( + // + // Prepare Data for Measurement (CcProtocol and Tcg2Protocol) + // +- EventSize = (UINT32)(sizeof (EFI_GPT_DATA) - sizeof (GptData->Partitions) +- + NumberOfPartition * PrimaryHeader->SizeOfPartitionEntry); +- EventPtr = (UINT8 *)AllocateZeroPool (EventSize + sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event)); ++ Status = SanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfPartition, &TcgEventSize); ++ if (EFI_ERROR (Status)) { ++ FreePool (PrimaryHeader); ++ FreePool (EntryPtr); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ EventPtr = (UINT8 *)AllocateZeroPool (TcgEventSize); + if (EventPtr == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + + Tcg2Event = (EFI_TCG2_EVENT *)EventPtr; +- Tcg2Event->Size = EventSize + sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event); ++ Tcg2Event->Size = TcgEventSize; + Tcg2Event->Header.HeaderSize = sizeof (EFI_TCG2_EVENT_HEADER); + Tcg2Event->Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION; + Tcg2Event->Header.PCRIndex = 5; +@@ -310,7 +317,7 @@ Tcg2MeasureGptTable ( + CcProtocol, + 0, + (EFI_PHYSICAL_ADDRESS)(UINTN)(VOID *)GptData, +- (UINT64)EventSize, ++ (UINT64)TcgEventSize - OFFSET_OF (EFI_TCG2_EVENT, Event), + CcEvent + ); + if (!EFI_ERROR (Status)) { +@@ -326,7 +333,7 @@ Tcg2MeasureGptTable ( + Tcg2Protocol, + 0, + (EFI_PHYSICAL_ADDRESS)(UINTN)(VOID *)GptData, +- (UINT64)EventSize, ++ (UINT64)TcgEventSize - OFFSET_OF (EFI_TCG2_EVENT, Event), + Tcg2Event + ); + if (!EFI_ERROR (Status)) { +@@ -443,11 +450,13 @@ Tcg2MeasurePeImage ( + Tcg2Event->Header.PCRIndex = 2; + break; + default: +- DEBUG (( +- DEBUG_ERROR, +- "Tcg2MeasurePeImage: Unknown subsystem type %d", +- ImageType +- )); ++ DEBUG ( ++ ( ++ DEBUG_ERROR, ++ "Tcg2MeasurePeImage: Unknown subsystem type %d", ++ ImageType ++ ) ++ ); + goto Finish; + } + +@@ -515,7 +524,7 @@ Finish: + + @param MeasureBootProtocols Pointer to the located measure boot protocol instances. + +- @retval EFI_SUCCESS Sucessfully locate the measure boot protocol instances (at least one instance). ++ @retval EFI_SUCCESS Successfully locate the measure boot protocol instances (at least one instance). + @retval EFI_UNSUPPORTED Measure boot is not supported. + **/ + EFI_STATUS +@@ -646,12 +655,14 @@ DxeTpm2MeasureBootHandler ( + return EFI_SUCCESS; + } + +- DEBUG (( +- DEBUG_INFO, +- "Tcg2Protocol = %p, CcMeasurementProtocol = %p\n", +- MeasureBootProtocols.Tcg2Protocol, +- MeasureBootProtocols.CcProtocol +- )); ++ DEBUG ( ++ ( ++ DEBUG_INFO, ++ "Tcg2Protocol = %p, CcMeasurementProtocol = %p\n", ++ MeasureBootProtocols.Tcg2Protocol, ++ MeasureBootProtocols.CcProtocol ++ ) ++ ); + + // + // Copy File Device Path +diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf +index 6dca79a..28995f4 100644 +--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf ++++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf +@@ -37,6 +37,8 @@ + + [Sources] + DxeTpm2MeasureBootLib.c ++ DxeTpm2MeasureBootLibSanitization.c ++ DxeTpm2MeasureBootLibSanitization.h + + [Packages] + MdePkg/MdePkg.dec +@@ -46,6 +48,7 @@ + + [LibraryClasses] + BaseMemoryLib ++ SafeIntLib + DebugLib + MemoryAllocationLib + DevicePathLib +@@ -65,4 +68,3 @@ + gEfiFirmwareVolumeBlockProtocolGuid ## SOMETIMES_CONSUMES + gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES + gEfiDiskIoProtocolGuid ## SOMETIMES_CONSUMES +- +diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c +new file mode 100644 +index 0000000..e230965 +--- /dev/null ++++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c +@@ -0,0 +1,275 @@ ++/** @file ++ The library instance provides security service of TPM2 measure boot and ++ Confidential Computing (CC) measure boot. ++ ++ Caution: This file requires additional review when modified. ++ This library will have external input - PE/COFF image and GPT partition. ++ This external input must be validated carefully to avoid security issue like ++ buffer overflow, integer overflow. ++ ++ This file will pull out the validation logic from the following functions, in an ++ attempt to validate the untrusted input in the form of unit tests ++ ++ These are those functions: ++ ++ DxeTpm2MeasureBootLibImageRead() function will make sure the PE/COFF image content ++ read is within the image buffer. ++ ++ Tcg2MeasureGptTable() function will receive untrusted GPT partition table, and parse ++ partition data carefully. ++ ++ Copyright (c) Microsoft Corporation.
++ SPDX-License-Identifier: BSD-2-Clause-Patent ++**/ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "DxeTpm2MeasureBootLibSanitization.h" ++ ++#define GPT_HEADER_REVISION_V1 0x00010000 ++ ++/** ++ This function will validate the EFI_PARTITION_TABLE_HEADER structure is safe to parse ++ However this function will not attempt to verify the validity of the GPT partition ++ It will check the following: ++ - Signature ++ - Revision ++ - AlternateLBA ++ - FirstUsableLBA ++ - LastUsableLBA ++ - PartitionEntryLBA ++ - NumberOfPartitionEntries ++ - SizeOfPartitionEntry ++ - BlockIo ++ ++ @param[in] PrimaryHeader ++ Pointer to the EFI_PARTITION_TABLE_HEADER structure. ++ ++ @param[in] BlockIo ++ Pointer to the EFI_BLOCK_IO_PROTOCOL structure. ++ ++ @retval EFI_SUCCESS ++ The EFI_PARTITION_TABLE_HEADER structure is valid. ++ ++ @retval EFI_INVALID_PARAMETER ++ The EFI_PARTITION_TABLE_HEADER structure is invalid. ++**/ ++EFI_STATUS ++EFIAPI ++SanitizeEfiPartitionTableHeader ( ++ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, ++ IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo ++ ) ++{ ++ // ++ // Verify that the input parameters are safe to use ++ // ++ if (PrimaryHeader == NULL) { ++ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header!\n")); ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if ((BlockIo == NULL) || (BlockIo->Media == NULL)) { ++ DEBUG ((DEBUG_ERROR, "Invalid BlockIo!\n")); ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // The signature must be EFI_PTAB_HEADER_ID ("EFI PART" in ASCII) ++ // ++ if (PrimaryHeader->Header.Signature != EFI_PTAB_HEADER_ID) { ++ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // ++ // The version must be GPT_HEADER_REVISION_V1 (0x00010000) ++ // ++ if (PrimaryHeader->Header.Revision != GPT_HEADER_REVISION_V1) { ++ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header Revision!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // ++ // The HeaderSize must be greater than or equal to 92 and must be less than or equal to the logical block size ++ // ++ if ((PrimaryHeader->Header.HeaderSize < sizeof (EFI_PARTITION_TABLE_HEADER)) || (PrimaryHeader->Header.HeaderSize > BlockIo->Media->BlockSize)) { ++ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header HeaderSize!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // ++ // The partition entries should all be before the first usable block ++ // ++ if (PrimaryHeader->FirstUsableLBA <= PrimaryHeader->PartitionEntryLBA) { ++ DEBUG ((DEBUG_ERROR, "GPT PartitionEntryLBA is not less than FirstUsableLBA!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // ++ // Check that the PartitionEntryLBA greater than the Max LBA ++ // This will be used later for multiplication ++ // ++ if (PrimaryHeader->PartitionEntryLBA > DivU64x32 (MAX_UINT64, BlockIo->Media->BlockSize)) { ++ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header PartitionEntryLBA!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // ++ // Check that the number of partition entries is greater than zero ++ // ++ if (PrimaryHeader->NumberOfPartitionEntries == 0) { ++ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header NumberOfPartitionEntries!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // ++ // SizeOfPartitionEntry must be 128, 256, 512... improper size may lead to accessing uninitialized memory ++ // ++ if ((PrimaryHeader->SizeOfPartitionEntry < 128) || ((PrimaryHeader->SizeOfPartitionEntry & (PrimaryHeader->SizeOfPartitionEntry - 1)) != 0)) { ++ DEBUG ((DEBUG_ERROR, "SizeOfPartitionEntry shall be set to a value of 128 x 2^n where n is an integer greater than or equal to zero (e.g., 128, 256, 512, etc.)!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // ++ // This check is to prevent overflow when calculating the allocation size for the partition entries ++ // This check will be used later for multiplication ++ // ++ if (PrimaryHeader->NumberOfPartitionEntries > DivU64x32 (MAX_UINT64, PrimaryHeader->SizeOfPartitionEntry)) { ++ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header NumberOfPartitionEntries!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ return EFI_SUCCESS; ++} ++ ++/** ++ This function will validate that the allocation size from the primary header is sane ++ It will check the following: ++ - AllocationSize does not overflow ++ ++ @param[in] PrimaryHeader ++ Pointer to the EFI_PARTITION_TABLE_HEADER structure. ++ ++ @param[out] AllocationSize ++ Pointer to the allocation size. ++ ++ @retval EFI_SUCCESS ++ The allocation size is valid. ++ ++ @retval EFI_OUT_OF_RESOURCES ++ The allocation size is invalid. ++**/ ++EFI_STATUS ++EFIAPI ++SanitizePrimaryHeaderAllocationSize ( ++ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, ++ OUT UINT32 *AllocationSize ++ ) ++{ ++ EFI_STATUS Status; ++ ++ if (PrimaryHeader == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if (AllocationSize == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // Replacing logic: ++ // PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry; ++ // ++ Status = SafeUint32Mult (PrimaryHeader->NumberOfPartitionEntries, PrimaryHeader->SizeOfPartitionEntry, AllocationSize); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "Allocation Size would have overflowed!\n")); ++ return EFI_BAD_BUFFER_SIZE; ++ } ++ ++ return EFI_SUCCESS; ++} ++ ++/** ++ This function will validate that the Gpt Event Size calculated from the primary header is sane ++ It will check the following: ++ - EventSize does not overflow ++ ++ Important: This function includes the entire length of the allocated space, including ++ (sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event)) . When hashing the buffer allocated with this ++ size, the caller must subtract the size of the (sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event)) ++ from the size of the buffer before hashing. ++ ++ @param[in] PrimaryHeader - Pointer to the EFI_PARTITION_TABLE_HEADER structure. ++ @param[in] NumberOfPartition - Number of partitions. ++ @param[out] EventSize - Pointer to the event size. ++ ++ @retval EFI_SUCCESS ++ The event size is valid. ++ ++ @retval EFI_OUT_OF_RESOURCES ++ Overflow would have occurred. ++ ++ @retval EFI_INVALID_PARAMETER ++ One of the passed parameters was invalid. ++**/ ++EFI_STATUS ++SanitizePrimaryHeaderGptEventSize ( ++ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, ++ IN UINTN NumberOfPartition, ++ OUT UINT32 *EventSize ++ ) ++{ ++ EFI_STATUS Status; ++ UINT32 SafeNumberOfPartitions; ++ ++ if (PrimaryHeader == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if (EventSize == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // We shouldn't even attempt to perform the multiplication if the number of partitions is greater than the maximum value of UINT32 ++ // ++ Status = SafeUintnToUint32 (NumberOfPartition, &SafeNumberOfPartitions); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "NumberOfPartition would have overflowed!\n")); ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // Replacing logic: ++ // (UINT32)(sizeof (EFI_GPT_DATA) - sizeof (GptData->Partitions) + NumberOfPartition * PrimaryHeader.SizeOfPartitionEntry); ++ // ++ Status = SafeUint32Mult (SafeNumberOfPartitions, PrimaryHeader->SizeOfPartitionEntry, EventSize); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "Event Size would have overflowed!\n")); ++ return EFI_BAD_BUFFER_SIZE; ++ } ++ ++ // ++ // Replacing logic: ++ // *EventSize + sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event); ++ // ++ Status = SafeUint32Add ( ++ OFFSET_OF (EFI_TCG2_EVENT, Event) + OFFSET_OF (EFI_GPT_DATA, Partitions), ++ *EventSize, ++ EventSize ++ ); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "Event Size would have overflowed because of GPTData!\n")); ++ return EFI_BAD_BUFFER_SIZE; ++ } ++ ++ return EFI_SUCCESS; ++} +diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h +new file mode 100644 +index 0000000..048b738 +--- /dev/null ++++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h +@@ -0,0 +1,113 @@ ++/** @file ++ This file includes the function prototypes for the sanitization functions. ++ ++ These are those functions: ++ ++ DxeTpm2MeasureBootLibImageRead() function will make sure the PE/COFF image content ++ read is within the image buffer. ++ ++ Tcg2MeasureGptTable() function will receive untrusted GPT partition table, and parse ++ partition data carefully. ++ ++ Copyright (c) Microsoft Corporation.
++ SPDX-License-Identifier: BSD-2-Clause-Patent ++ ++**/ ++ ++#ifndef DXE_TPM2_MEASURE_BOOT_LIB_SANITATION_ ++#define DXE_TPM2_MEASURE_BOOT_LIB_SANITATION_ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/** ++ This function will validate the EFI_PARTITION_TABLE_HEADER structure is safe to parse ++ However this function will not attempt to verify the validity of the GPT partition ++ It will check the following: ++ - Signature ++ - Revision ++ - AlternateLBA ++ - FirstUsableLBA ++ - LastUsableLBA ++ - PartitionEntryLBA ++ - NumberOfPartitionEntries ++ - SizeOfPartitionEntry ++ - BlockIo ++ ++ @param[in] PrimaryHeader ++ Pointer to the EFI_PARTITION_TABLE_HEADER structure. ++ ++ @param[in] BlockIo ++ Pointer to the EFI_BLOCK_IO_PROTOCOL structure. ++ ++ @retval EFI_SUCCESS ++ The EFI_PARTITION_TABLE_HEADER structure is valid. ++ ++ @retval EFI_INVALID_PARAMETER ++ The EFI_PARTITION_TABLE_HEADER structure is invalid. ++**/ ++EFI_STATUS ++EFIAPI ++SanitizeEfiPartitionTableHeader ( ++ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, ++ IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo ++ ); ++ ++/** ++ This function will validate that the allocation size from the primary header is sane ++ It will check the following: ++ - AllocationSize does not overflow ++ ++ @param[in] PrimaryHeader ++ Pointer to the EFI_PARTITION_TABLE_HEADER structure. ++ ++ @param[out] AllocationSize ++ Pointer to the allocation size. ++ ++ @retval EFI_SUCCESS ++ The allocation size is valid. ++ ++ @retval EFI_OUT_OF_RESOURCES ++ The allocation size is invalid. ++**/ ++EFI_STATUS ++EFIAPI ++SanitizePrimaryHeaderAllocationSize ( ++ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, ++ OUT UINT32 *AllocationSize ++ ); ++ ++/** ++ This function will validate that the Gpt Event Size calculated from the primary header is sane ++ It will check the following: ++ - EventSize does not overflow ++ ++ Important: This function includes the entire length of the allocated space, including ++ (sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event)) . When hashing the buffer allocated with this ++ size, the caller must subtract the size of the (sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event)) ++ from the size of the buffer before hashing. ++ ++ @param[in] PrimaryHeader - Pointer to the EFI_PARTITION_TABLE_HEADER structure. ++ @param[in] NumberOfPartition - Number of partitions. ++ @param[out] EventSize - Pointer to the event size. ++ ++ @retval EFI_SUCCESS ++ The event size is valid. ++ ++ @retval EFI_OUT_OF_RESOURCES ++ Overflow would have occurred. ++ ++ @retval EFI_INVALID_PARAMETER ++ One of the passed parameters was invalid. ++**/ ++EFI_STATUS ++SanitizePrimaryHeaderGptEventSize ( ++ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, ++ IN UINTN NumberOfPartition, ++ OUT UINT32 *EventSize ++ ); ++ ++#endif // DXE_TPM2_MEASURE_BOOT_LIB_SANITATION_ +diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c +new file mode 100644 +index 0000000..3eb9763 +--- /dev/null ++++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c +@@ -0,0 +1,303 @@ ++/** @file ++ This file includes the unit test cases for the DxeTpm2MeasureBootLibSanitizationTest.c. ++ ++ Copyright (c) Microsoft Corporation.
++ SPDX-License-Identifier: BSD-2-Clause-Patent ++**/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "../DxeTpm2MeasureBootLibSanitization.h" ++ ++#define UNIT_TEST_NAME "DxeTpm2MeasureBootLibSanitizationTest" ++#define UNIT_TEST_VERSION "1.0" ++ ++#define DEFAULT_PRIMARY_TABLE_HEADER_REVISION 0x00010000 ++#define DEFAULT_PRIMARY_TABLE_HEADER_NUMBER_OF_PARTITION_ENTRIES 1 ++#define DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY 128 ++ ++/** ++ This function tests the SanitizeEfiPartitionTableHeader function. ++ It's intent is to test that a malicious EFI_PARTITION_TABLE_HEADER ++ structure will not cause undefined or unexpected behavior. ++ ++ In general the TPM should still be able to measure the data, but ++ be the header should be sanitized to prevent any unexpected behavior. ++ ++ @param[in] Context The unit test context. ++ ++ @retval UNIT_TEST_PASSED The test passed. ++ @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. ++**/ ++UNIT_TEST_STATUS ++EFIAPI ++TestSanitizeEfiPartitionTableHeader ( ++ IN UNIT_TEST_CONTEXT Context ++ ) ++{ ++ EFI_STATUS Status; ++ EFI_PARTITION_TABLE_HEADER PrimaryHeader; ++ EFI_BLOCK_IO_PROTOCOL BlockIo; ++ EFI_BLOCK_IO_MEDIA BlockMedia; ++ ++ // Generate EFI_BLOCK_IO_MEDIA test data ++ BlockMedia.MediaId = 1; ++ BlockMedia.RemovableMedia = FALSE; ++ BlockMedia.MediaPresent = TRUE; ++ BlockMedia.LogicalPartition = FALSE; ++ BlockMedia.ReadOnly = FALSE; ++ BlockMedia.WriteCaching = FALSE; ++ BlockMedia.BlockSize = 512; ++ BlockMedia.IoAlign = 1; ++ BlockMedia.LastBlock = 0; ++ ++ // Generate EFI_BLOCK_IO_PROTOCOL test data ++ BlockIo.Revision = 1; ++ BlockIo.Media = &BlockMedia; ++ BlockIo.Reset = NULL; ++ BlockIo.ReadBlocks = NULL; ++ BlockIo.WriteBlocks = NULL; ++ BlockIo.FlushBlocks = NULL; ++ ++ // Geneate EFI_PARTITION_TABLE_HEADER test data ++ PrimaryHeader.Header.Signature = EFI_PTAB_HEADER_ID; ++ PrimaryHeader.Header.Revision = DEFAULT_PRIMARY_TABLE_HEADER_REVISION; ++ PrimaryHeader.Header.HeaderSize = sizeof (EFI_PARTITION_TABLE_HEADER); ++ PrimaryHeader.MyLBA = 1; ++ PrimaryHeader.AlternateLBA = 2; ++ PrimaryHeader.FirstUsableLBA = 3; ++ PrimaryHeader.LastUsableLBA = 4; ++ PrimaryHeader.PartitionEntryLBA = 5; ++ PrimaryHeader.NumberOfPartitionEntries = DEFAULT_PRIMARY_TABLE_HEADER_NUMBER_OF_PARTITION_ENTRIES; ++ PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; ++ PrimaryHeader.PartitionEntryArrayCRC32 = 0; // Purposely invalid ++ ++ // Calculate the CRC32 of the PrimaryHeader ++ PrimaryHeader.Header.CRC32 = CalculateCrc32 ((UINT8 *)&PrimaryHeader, PrimaryHeader.Header.HeaderSize); ++ ++ // Test that a normal PrimaryHeader passes validation ++ Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ UT_ASSERT_NOT_EFI_ERROR (Status); ++ ++ // Test that when number of partition entries is 0, the function returns EFI_DEVICE_ERROR ++ // Should print "Invalid Partition Table Header NumberOfPartitionEntries!"" ++ PrimaryHeader.NumberOfPartitionEntries = 0; ++ Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); ++ PrimaryHeader.NumberOfPartitionEntries = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; ++ ++ // Test that when the header size is too small, the function returns EFI_DEVICE_ERROR ++ // Should print "Invalid Partition Table Header Size!" ++ PrimaryHeader.Header.HeaderSize = 0; ++ Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); ++ PrimaryHeader.Header.HeaderSize = sizeof (EFI_PARTITION_TABLE_HEADER); ++ ++ // Test that when the SizeOfPartitionEntry is too small, the function returns EFI_DEVICE_ERROR ++ // should print: "SizeOfPartitionEntry shall be set to a value of 128 x 2^n where n is an integer greater than or equal to zero (e.g., 128, 256, 512, etc.)!" ++ PrimaryHeader.SizeOfPartitionEntry = 1; ++ Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); ++ ++ DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); ++ ++ return UNIT_TEST_PASSED; ++} ++ ++/** ++ This function tests the SanitizePrimaryHeaderAllocationSize function. ++ It's intent is to test that the untrusted input from a EFI_PARTITION_TABLE_HEADER ++ structure will not cause an overflow when calculating the allocation size. ++ ++ @param[in] Context The unit test context. ++ ++ @retval UNIT_TEST_PASSED The test passed. ++ @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. ++**/ ++UNIT_TEST_STATUS ++EFIAPI ++TestSanitizePrimaryHeaderAllocationSize ( ++ IN UNIT_TEST_CONTEXT Context ++ ) ++{ ++ UINT32 AllocationSize; ++ ++ EFI_STATUS Status; ++ EFI_PARTITION_TABLE_HEADER PrimaryHeader; ++ ++ // Test that a normal PrimaryHeader passes validation ++ PrimaryHeader.NumberOfPartitionEntries = 5; ++ PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; ++ ++ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ UT_ASSERT_NOT_EFI_ERROR (Status); ++ ++ // Test that the allocation size is correct compared to the existing logic ++ UT_ASSERT_EQUAL (AllocationSize, PrimaryHeader.NumberOfPartitionEntries * PrimaryHeader.SizeOfPartitionEntry); ++ ++ // Test that an overflow is detected ++ PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32; ++ PrimaryHeader.SizeOfPartitionEntry = 5; ++ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); ++ ++ // Test the inverse ++ PrimaryHeader.NumberOfPartitionEntries = 5; ++ PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; ++ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); ++ ++ // Test the worst case scenario ++ PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32; ++ PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; ++ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); ++ ++ DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); ++ ++ return UNIT_TEST_PASSED; ++} ++ ++/** ++ This function tests the SanitizePrimaryHeaderGptEventSize function. ++ It's intent is to test that the untrusted input from a EFI_GPT_DATA structure ++ will not cause an overflow when calculating the event size. ++ ++ @param[in] Context The unit test context. ++ ++ @retval UNIT_TEST_PASSED The test passed. ++ @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. ++**/ ++UNIT_TEST_STATUS ++EFIAPI ++TestSanitizePrimaryHeaderGptEventSize ( ++ IN UNIT_TEST_CONTEXT Context ++ ) ++{ ++ UINT32 EventSize; ++ UINT32 ExistingLogicEventSize; ++ EFI_STATUS Status; ++ EFI_PARTITION_TABLE_HEADER PrimaryHeader; ++ UINTN NumberOfPartition; ++ EFI_GPT_DATA *GptData; ++ EFI_TCG2_EVENT *Tcg2Event; ++ ++ Tcg2Event = NULL; ++ GptData = NULL; ++ ++ // Test that a normal PrimaryHeader passes validation ++ PrimaryHeader.NumberOfPartitionEntries = 5; ++ PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; ++ ++ // set the number of partitions ++ NumberOfPartition = 13; ++ ++ // that the primary event size is correct ++ Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); ++ UT_ASSERT_NOT_EFI_ERROR (Status); ++ ++ // Calculate the existing logic event size ++ ExistingLogicEventSize = (UINT32)(OFFSET_OF (EFI_TCG2_EVENT, Event) + OFFSET_OF (EFI_GPT_DATA, Partitions) ++ + NumberOfPartition * PrimaryHeader.SizeOfPartitionEntry); ++ ++ // Check that the event size is correct ++ UT_ASSERT_EQUAL (EventSize, ExistingLogicEventSize); ++ ++ // Tests that the primary event size may not overflow ++ Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, MAX_UINT32, &EventSize); ++ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); ++ ++ // Test that the size of partition entries may not overflow ++ PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; ++ Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); ++ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); ++ ++ DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); ++ ++ return UNIT_TEST_PASSED; ++} ++ ++// *--------------------------------------------------------------------* ++// * Unit Test Code Main Function ++// *--------------------------------------------------------------------* ++ ++/** ++ This function acts as the entry point for the unit tests. ++ ++ @retval UNIT_TEST_PASSED The test passed. ++ @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. ++ @retval others The test failed. ++**/ ++EFI_STATUS ++EFIAPI ++UefiTestMain ( ++ VOID ++ ) ++{ ++ EFI_STATUS Status; ++ UNIT_TEST_FRAMEWORK_HANDLE Framework; ++ UNIT_TEST_SUITE_HANDLE Tcg2MeasureBootLibValidationTestSuite; ++ ++ Framework = NULL; ++ ++ DEBUG ((DEBUG_INFO, "%a: TestMain() - Start\n", UNIT_TEST_NAME)); ++ ++ Status = InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCallerBaseName, UNIT_TEST_VERSION); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%a: Failed in InitUnitTestFramework. Status = %r\n", UNIT_TEST_NAME, Status)); ++ goto EXIT; ++ } ++ ++ Status = CreateUnitTestSuite (&Tcg2MeasureBootLibValidationTestSuite, Framework, "Tcg2MeasureBootLibValidationTestSuite", "Common.Tcg2MeasureBootLibValidation", NULL, NULL); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%s: Failed in CreateUnitTestSuite for Tcg2MeasureBootLibValidationTestSuite\n", UNIT_TEST_NAME)); ++ Status = EFI_OUT_OF_RESOURCES; ++ goto EXIT; ++ } ++ ++ // -----------Suite---------------------------------Description----------------------------Class----------------------------------Test Function------------------------Pre---Clean-Context ++ AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Validating EFI Partition Table", "Common.Tcg2MeasureBootLibValidation", TestSanitizeEfiPartitionTableHeader, NULL, NULL, NULL); ++ AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Primary header gpt event checks for overflow", "Common.Tcg2MeasureBootLibValidation", TestSanitizePrimaryHeaderAllocationSize, NULL, NULL, NULL); ++ AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Primary header allocation size checks for overflow", "Common.Tcg2MeasureBootLibValidation", TestSanitizePrimaryHeaderGptEventSize, NULL, NULL, NULL); ++ ++ Status = RunAllTestSuites (Framework); ++ ++EXIT: ++ if (Framework != NULL) { ++ FreeUnitTestFramework (Framework); ++ } ++ ++ DEBUG ((DEBUG_INFO, "%a: TestMain() - End\n", UNIT_TEST_NAME)); ++ return Status; ++} ++ ++/// ++/// Avoid ECC error for function name that starts with lower case letter ++/// ++#define DxeTpm2MeasureBootLibUnitTestMain main ++ ++/** ++ Standard POSIX C entry point for host based unit test execution. ++ ++ @param[in] Argc Number of arguments ++ @param[in] Argv Array of pointers to arguments ++ ++ @retval 0 Success ++ @retval other Error ++**/ ++INT32 ++DxeTpm2MeasureBootLibUnitTestMain ( ++ IN INT32 Argc, ++ IN CHAR8 *Argv[] ++ ) ++{ ++ return (INT32)UefiTestMain (); ++} +diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTestHost.inf b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTestHost.inf +new file mode 100644 +index 0000000..2999aa2 +--- /dev/null ++++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTestHost.inf +@@ -0,0 +1,28 @@ ++## @file ++# This file builds the unit tests for DxeTpm2MeasureBootLib ++# ++# Copyright (C) Microsoft Corporation.
++# SPDX-License-Identifier: BSD-2-Clause-Patent ++## ++ ++[Defines] ++ INF_VERSION = 0x00010006 ++ BASE_NAME = DxeTpm2MeasuredBootLibTest ++ FILE_GUID = 144d757f-d423-484e-9309-a23695fad5bd ++ MODULE_TYPE = HOST_APPLICATION ++ VERSION_STRING = 1.0 ++ ENTRY_POINT = main ++ ++[Sources] ++ DxeTpm2MeasureBootLibSanitizationTest.c ++ ../DxeTpm2MeasureBootLibSanitization.c ++ ++[Packages] ++ MdePkg/MdePkg.dec ++ ++[LibraryClasses] ++ BaseLib ++ DebugLib ++ UnitTestLib ++ PrintLib ++ SafeIntLib +diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c +new file mode 100644 +index 0000000..eeb928c +--- /dev/null ++++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c +@@ -0,0 +1,301 @@ ++/** @file ++This file includes the unit test cases for the DxeTpmMeasureBootLibSanitizationTest.c. ++ ++Copyright (c) Microsoft Corporation.
++SPDX-License-Identifier: BSD-2-Clause-Patent ++**/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "../DxeTpmMeasureBootLibSanitization.h" ++ ++#define UNIT_TEST_NAME "DxeTpmMeasureBootLibSanitizationTest" ++#define UNIT_TEST_VERSION "1.0" ++ ++#define DEFAULT_PRIMARY_TABLE_HEADER_REVISION 0x00010000 ++#define DEFAULT_PRIMARY_TABLE_HEADER_NUMBER_OF_PARTITION_ENTRIES 1 ++#define DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY 128 ++ ++/** ++ This function tests the SanitizeEfiPartitionTableHeader function. ++ It's intent is to test that a malicious EFI_PARTITION_TABLE_HEADER ++ structure will not cause undefined or unexpected behavior. ++ ++ In general the TPM should still be able to measure the data, but ++ be the header should be sanitized to prevent any unexpected behavior. ++ ++ @param[in] Context The unit test context. ++ ++ @retval UNIT_TEST_PASSED The test passed. ++ @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. ++**/ ++UNIT_TEST_STATUS ++EFIAPI ++TestSanitizeEfiPartitionTableHeader ( ++ IN UNIT_TEST_CONTEXT Context ++ ) ++{ ++ EFI_STATUS Status; ++ EFI_PARTITION_TABLE_HEADER PrimaryHeader; ++ EFI_BLOCK_IO_PROTOCOL BlockIo; ++ EFI_BLOCK_IO_MEDIA BlockMedia; ++ ++ // Generate EFI_BLOCK_IO_MEDIA test data ++ BlockMedia.MediaId = 1; ++ BlockMedia.RemovableMedia = FALSE; ++ BlockMedia.MediaPresent = TRUE; ++ BlockMedia.LogicalPartition = FALSE; ++ BlockMedia.ReadOnly = FALSE; ++ BlockMedia.WriteCaching = FALSE; ++ BlockMedia.BlockSize = 512; ++ BlockMedia.IoAlign = 1; ++ BlockMedia.LastBlock = 0; ++ ++ // Generate EFI_BLOCK_IO_PROTOCOL test data ++ BlockIo.Revision = 1; ++ BlockIo.Media = &BlockMedia; ++ BlockIo.Reset = NULL; ++ BlockIo.ReadBlocks = NULL; ++ BlockIo.WriteBlocks = NULL; ++ BlockIo.FlushBlocks = NULL; ++ ++ // Geneate EFI_PARTITION_TABLE_HEADER test data ++ PrimaryHeader.Header.Signature = EFI_PTAB_HEADER_ID; ++ PrimaryHeader.Header.Revision = DEFAULT_PRIMARY_TABLE_HEADER_REVISION; ++ PrimaryHeader.Header.HeaderSize = sizeof (EFI_PARTITION_TABLE_HEADER); ++ PrimaryHeader.MyLBA = 1; ++ PrimaryHeader.AlternateLBA = 2; ++ PrimaryHeader.FirstUsableLBA = 3; ++ PrimaryHeader.LastUsableLBA = 4; ++ PrimaryHeader.PartitionEntryLBA = 5; ++ PrimaryHeader.NumberOfPartitionEntries = DEFAULT_PRIMARY_TABLE_HEADER_NUMBER_OF_PARTITION_ENTRIES; ++ PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; ++ PrimaryHeader.PartitionEntryArrayCRC32 = 0; // Purposely invalid ++ ++ // Calculate the CRC32 of the PrimaryHeader ++ PrimaryHeader.Header.CRC32 = CalculateCrc32 ((UINT8 *)&PrimaryHeader, PrimaryHeader.Header.HeaderSize); ++ ++ // Test that a normal PrimaryHeader passes validation ++ Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ UT_ASSERT_NOT_EFI_ERROR (Status); ++ ++ // Test that when number of partition entries is 0, the function returns EFI_DEVICE_ERROR ++ // Should print "Invalid Partition Table Header NumberOfPartitionEntries!"" ++ PrimaryHeader.NumberOfPartitionEntries = 0; ++ Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); ++ PrimaryHeader.NumberOfPartitionEntries = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; ++ ++ // Test that when the header size is too small, the function returns EFI_DEVICE_ERROR ++ // Should print "Invalid Partition Table Header Size!" ++ PrimaryHeader.Header.HeaderSize = 0; ++ Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); ++ PrimaryHeader.Header.HeaderSize = sizeof (EFI_PARTITION_TABLE_HEADER); ++ ++ // Test that when the SizeOfPartitionEntry is too small, the function returns EFI_DEVICE_ERROR ++ // should print: "SizeOfPartitionEntry shall be set to a value of 128 x 2^n where n is an integer greater than or equal to zero (e.g., 128, 256, 512, etc.)!" ++ PrimaryHeader.SizeOfPartitionEntry = 1; ++ Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); ++ ++ DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); ++ ++ return UNIT_TEST_PASSED; ++} ++ ++/** ++ This function tests the SanitizePrimaryHeaderAllocationSize function. ++ It's intent is to test that the untrusted input from a EFI_PARTITION_TABLE_HEADER ++ structure will not cause an overflow when calculating the allocation size. ++ ++ @param[in] Context The unit test context. ++ ++ @retval UNIT_TEST_PASSED The test passed. ++ @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. ++**/ ++UNIT_TEST_STATUS ++EFIAPI ++TestSanitizePrimaryHeaderAllocationSize ( ++ IN UNIT_TEST_CONTEXT Context ++ ) ++{ ++ UINT32 AllocationSize; ++ ++ EFI_STATUS Status; ++ EFI_PARTITION_TABLE_HEADER PrimaryHeader; ++ ++ // Test that a normal PrimaryHeader passes validation ++ PrimaryHeader.NumberOfPartitionEntries = 5; ++ PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; ++ ++ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ UT_ASSERT_NOT_EFI_ERROR (Status); ++ ++ // Test that the allocation size is correct compared to the existing logic ++ UT_ASSERT_EQUAL (AllocationSize, PrimaryHeader.NumberOfPartitionEntries * PrimaryHeader.SizeOfPartitionEntry); ++ ++ // Test that an overflow is detected ++ PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32; ++ PrimaryHeader.SizeOfPartitionEntry = 5; ++ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); ++ ++ // Test the inverse ++ PrimaryHeader.NumberOfPartitionEntries = 5; ++ PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; ++ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); ++ ++ // Test the worst case scenario ++ PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32; ++ PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; ++ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); ++ ++ DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); ++ ++ return UNIT_TEST_PASSED; ++} ++ ++/** ++ This function tests the SanitizePrimaryHeaderGptEventSize function. ++ It's intent is to test that the untrusted input from a EFI_GPT_DATA structure ++ will not cause an overflow when calculating the event size. ++ ++ @param[in] Context The unit test context. ++ ++ @retval UNIT_TEST_PASSED The test passed. ++ @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. ++**/ ++UNIT_TEST_STATUS ++EFIAPI ++TestSanitizePrimaryHeaderGptEventSize ( ++ IN UNIT_TEST_CONTEXT Context ++ ) ++{ ++ UINT32 EventSize; ++ UINT32 ExistingLogicEventSize; ++ EFI_STATUS Status; ++ EFI_PARTITION_TABLE_HEADER PrimaryHeader; ++ UINTN NumberOfPartition; ++ EFI_GPT_DATA *GptData; ++ ++ GptData = NULL; ++ ++ // Test that a normal PrimaryHeader passes validation ++ PrimaryHeader.NumberOfPartitionEntries = 5; ++ PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; ++ ++ // set the number of partitions ++ NumberOfPartition = 13; ++ ++ // that the primary event size is correct ++ Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); ++ UT_ASSERT_NOT_EFI_ERROR (Status); ++ ++ // Calculate the existing logic event size ++ ExistingLogicEventSize = (UINT32)(sizeof (TCG_PCR_EVENT_HDR) + OFFSET_OF (EFI_GPT_DATA, Partitions) ++ + NumberOfPartition * PrimaryHeader.SizeOfPartitionEntry); ++ ++ // Check that the event size is correct ++ UT_ASSERT_EQUAL (EventSize, ExistingLogicEventSize); ++ ++ // Tests that the primary event size may not overflow ++ Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, MAX_UINT32, &EventSize); ++ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); ++ ++ // Test that the size of partition entries may not overflow ++ PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; ++ Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); ++ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); ++ ++ DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); ++ ++ return UNIT_TEST_PASSED; ++} ++ ++// *--------------------------------------------------------------------* ++// * Unit Test Code Main Function ++// *--------------------------------------------------------------------* ++ ++/** ++ This function acts as the entry point for the unit tests. ++ ++ @param argc - The number of command line arguments ++ @param argv - The command line arguments ++ ++ @return int - The status of the test ++**/ ++EFI_STATUS ++EFIAPI ++UefiTestMain ( ++ VOID ++ ) ++{ ++ EFI_STATUS Status; ++ UNIT_TEST_FRAMEWORK_HANDLE Framework; ++ UNIT_TEST_SUITE_HANDLE TcgMeasureBootLibValidationTestSuite; ++ ++ Framework = NULL; ++ ++ DEBUG ((DEBUG_INFO, "%a: TestMain() - Start\n", UNIT_TEST_NAME)); ++ ++ Status = InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCallerBaseName, UNIT_TEST_VERSION); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%a: Failed in InitUnitTestFramework. Status = %r\n", UNIT_TEST_NAME, Status)); ++ goto EXIT; ++ } ++ ++ Status = CreateUnitTestSuite (&TcgMeasureBootLibValidationTestSuite, Framework, "TcgMeasureBootLibValidationTestSuite", "Common.TcgMeasureBootLibValidation", NULL, NULL); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%s: Failed in CreateUnitTestSuite for TcgMeasureBootLibValidationTestSuite\n", UNIT_TEST_NAME)); ++ Status = EFI_OUT_OF_RESOURCES; ++ goto EXIT; ++ } ++ ++ // -----------Suite---------------------------------Description----------------------------Class----------------------------------Test Function------------------------Pre---Clean-Context ++ AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Validating EFI Partition Table", "Common.TcgMeasureBootLibValidation", TestSanitizeEfiPartitionTableHeader, NULL, NULL, NULL); ++ AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Primary header gpt event checks for overflow", "Common.TcgMeasureBootLibValidation", TestSanitizePrimaryHeaderAllocationSize, NULL, NULL, NULL); ++ AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Primary header allocation size checks for overflow", "Common.TcgMeasureBootLibValidation", TestSanitizePrimaryHeaderGptEventSize, NULL, NULL, NULL); ++ ++ Status = RunAllTestSuites (Framework); ++ ++EXIT: ++ if (Framework != NULL) { ++ FreeUnitTestFramework (Framework); ++ } ++ ++ DEBUG ((DEBUG_INFO, "%a: TestMain() - End\n", UNIT_TEST_NAME)); ++ return Status; ++} ++ ++/// ++/// Avoid ECC error for function name that starts with lower case letter ++/// ++#define DxeTpmMeasureBootLibUnitTestMain main ++ ++/** ++ Standard POSIX C entry point for host based unit test execution. ++ ++ @param[in] Argc Number of arguments ++ @param[in] Argv Array of pointers to arguments ++ ++ @retval 0 Success ++ @retval other Error ++**/ ++INT32 ++DxeTpmMeasureBootLibUnitTestMain ( ++ IN INT32 Argc, ++ IN CHAR8 *Argv[] ++ ) ++{ ++ return (INT32)UefiTestMain (); ++} +diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTestHost.inf b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTestHost.inf +new file mode 100644 +index 0000000..47b0811 +--- /dev/null ++++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTestHost.inf +@@ -0,0 +1,28 @@ ++## @file ++# This file builds the unit tests for DxeTpmMeasureBootLib ++# ++# Copyright (C) Microsoft Corporation.
++# SPDX-License-Identifier: BSD-2-Clause-Patent ++## ++ ++[Defines] ++ INF_VERSION = 0x00010006 ++ BASE_NAME = DxeTpmMeasuredBootLibTest ++ FILE_GUID = eb01bc38-309c-4d3e-967e-9f078c90772f ++ MODULE_TYPE = HOST_APPLICATION ++ VERSION_STRING = 1.0 ++ ENTRY_POINT = main ++ ++[Sources] ++ DxeTpmMeasureBootLibSanitizationTest.c ++ ../DxeTpmMeasureBootLibSanitization.c ++ ++[Packages] ++ MdePkg/MdePkg.dec ++ ++[LibraryClasses] ++ BaseLib ++ DebugLib ++ UnitTestLib ++ PrintLib ++ SafeIntLib +diff --git a/SecurityPkg/SecurityPkg.ci.yaml b/SecurityPkg/SecurityPkg.ci.yaml +index 2138b0a..1036b18 100644 +--- a/SecurityPkg/SecurityPkg.ci.yaml ++++ b/SecurityPkg/SecurityPkg.ci.yaml +@@ -16,6 +16,7 @@ + ## ] + "ExceptionList": [ + "8005", "gRT", ++ "8001", "DxeTpm2MeasureBootLibUnitTestMain", + ], + ## Both file path and directory path are accepted. + "IgnoreFiles": [ +diff --git a/SecurityPkg/Test/SecurityPkgHostTest.dsc b/SecurityPkg/Test/SecurityPkgHostTest.dsc +index c4df01f..ebf132b 100644 +--- a/SecurityPkg/Test/SecurityPkgHostTest.dsc ++++ b/SecurityPkg/Test/SecurityPkgHostTest.dsc +@@ -25,6 +25,7 @@ + SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiRuntimeServicesTableLib.inf + SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.inf + SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf ++ SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTestHost.inf + + # + # Build SecurityPkg HOST_APPLICATION Tests +-- +2.25.1 + + +From a0eac36176295b0a0eb4102799fbfd0696bc2d3a Mon Sep 17 00:00:00 2001 +From: "Douglas Flick [MSFT]" +Date: Fri, 12 Jan 2024 02:16:02 +0800 +Subject: [PATCH 2/6] SecurityPkg: DxeTpmMeasureBootLib: SECURITY PATCH 4117 - + CVE 2022-36763 + +This commit contains the patch files and tests for DxeTpmMeasureBootLib +CVE 2022-36763. + +Cc: Jiewen Yao + +Signed-off-by: Doug Flick [MSFT] +Reviewed-by: Jiewen Yao +--- + .../DxeTpmMeasureBootLib.c | 40 ++- + .../DxeTpmMeasureBootLib.inf | 4 +- + .../DxeTpmMeasureBootLibSanitization.c | 241 ++++++++++++++++++ + .../DxeTpmMeasureBootLibSanitization.h | 114 +++++++++ + SecurityPkg/SecurityPkg.ci.yaml | 1 + + SecurityPkg/Test/SecurityPkgHostTest.dsc | 1 + + 6 files changed, 387 insertions(+), 14 deletions(-) + create mode 100644 SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c + create mode 100644 SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h + +diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c +index 220393d..669ab19 100644 +--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c ++++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c +@@ -18,6 +18,8 @@ + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + ++Copyright (c) Microsoft Corporation.
++SPDX-License-Identifier: BSD-2-Clause-Patent + **/ + + #include +@@ -40,6 +42,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent + #include + #include + ++#include "DxeTpmMeasureBootLibSanitization.h" ++ + // + // Flag to check GPT partition. It only need be measured once. + // +@@ -136,6 +140,9 @@ TcgMeasureGptTable ( + UINT32 EventSize; + UINT32 EventNumber; + EFI_PHYSICAL_ADDRESS EventLogLastEntry; ++ UINT32 AllocSize; ++ ++ GptData = NULL; + + if (mMeasureGptCount > 0) { + return EFI_SUCCESS; +@@ -166,8 +173,8 @@ TcgMeasureGptTable ( + BlockIo->Media->BlockSize, + (UINT8 *)PrimaryHeader + ); +- if (EFI_ERROR (Status)) { +- DEBUG ((DEBUG_ERROR, "Failed to Read Partition Table Header!\n")); ++ if (EFI_ERROR (Status) || EFI_ERROR (SanitizeEfiPartitionTableHeader (PrimaryHeader, BlockIo))) { ++ DEBUG ((DEBUG_ERROR, "Failed to read Partition Table Header or invalid Partition Table Header!\n")); + FreePool (PrimaryHeader); + return EFI_DEVICE_ERROR; + } +@@ -175,7 +182,13 @@ TcgMeasureGptTable ( + // + // Read the partition entry. + // +- EntryPtr = (UINT8 *)AllocatePool (PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry); ++ Status = SanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSize); ++ if (EFI_ERROR (Status)) { ++ FreePool (PrimaryHeader); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ EntryPtr = (UINT8 *)AllocatePool (AllocSize); + if (EntryPtr == NULL) { + FreePool (PrimaryHeader); + return EFI_OUT_OF_RESOURCES; +@@ -185,7 +198,7 @@ TcgMeasureGptTable ( + DiskIo, + BlockIo->Media->MediaId, + MultU64x32 (PrimaryHeader->PartitionEntryLBA, BlockIo->Media->BlockSize), +- PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry, ++ AllocSize, + EntryPtr + ); + if (EFI_ERROR (Status)) { +@@ -210,9 +223,8 @@ TcgMeasureGptTable ( + // + // Prepare Data for Measurement + // +- EventSize = (UINT32)(sizeof (EFI_GPT_DATA) - sizeof (GptData->Partitions) +- + NumberOfPartition * PrimaryHeader->SizeOfPartitionEntry); +- TcgEvent = (TCG_PCR_EVENT *)AllocateZeroPool (EventSize + sizeof (TCG_PCR_EVENT_HDR)); ++ Status = SanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfPartition, &EventSize); ++ TcgEvent = (TCG_PCR_EVENT *)AllocateZeroPool (EventSize); + if (TcgEvent == NULL) { + FreePool (PrimaryHeader); + FreePool (EntryPtr); +@@ -221,7 +233,7 @@ TcgMeasureGptTable ( + + TcgEvent->PCRIndex = 5; + TcgEvent->EventType = EV_EFI_GPT_EVENT; +- TcgEvent->EventSize = EventSize; ++ TcgEvent->EventSize = EventSize - sizeof (TCG_PCR_EVENT_HDR); + GptData = (EFI_GPT_DATA *)TcgEvent->Event; + + // +@@ -361,11 +373,13 @@ TcgMeasurePeImage ( + TcgEvent->PCRIndex = 2; + break; + default: +- DEBUG (( +- DEBUG_ERROR, +- "TcgMeasurePeImage: Unknown subsystem type %d", +- ImageType +- )); ++ DEBUG ( ++ ( ++ DEBUG_ERROR, ++ "TcgMeasurePeImage: Unknown subsystem type %d", ++ ImageType ++ ) ++ ); + goto Finish; + } + +diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf +index ebab6f7..414c654 100644 +--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf ++++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf +@@ -32,6 +32,8 @@ + + [Sources] + DxeTpmMeasureBootLib.c ++ DxeTpmMeasureBootLibSanitization.c ++ DxeTpmMeasureBootLibSanitization.h + + [Packages] + MdePkg/MdePkg.dec +@@ -41,6 +43,7 @@ + + [LibraryClasses] + BaseMemoryLib ++ SafeIntLib + DebugLib + MemoryAllocationLib + DevicePathLib +@@ -59,4 +62,3 @@ + gEfiFirmwareVolumeBlockProtocolGuid ## SOMETIMES_CONSUMES + gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES + gEfiDiskIoProtocolGuid ## SOMETIMES_CONSUMES +- +diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c +new file mode 100644 +index 0000000..a3fa46f +--- /dev/null ++++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c +@@ -0,0 +1,241 @@ ++/** @file ++ The library instance provides security service of TPM2 measure boot and ++ Confidential Computing (CC) measure boot. ++ ++ Caution: This file requires additional review when modified. ++ This library will have external input - PE/COFF image and GPT partition. ++ This external input must be validated carefully to avoid security issue like ++ buffer overflow, integer overflow. ++ ++ This file will pull out the validation logic from the following functions, in an ++ attempt to validate the untrusted input in the form of unit tests ++ ++ These are those functions: ++ ++ DxeTpmMeasureBootLibImageRead() function will make sure the PE/COFF image content ++ read is within the image buffer. ++ ++ Tcg2MeasureGptTable() function will receive untrusted GPT partition table, and parse ++ partition data carefully. ++ ++ Copyright (c) Microsoft Corporation.
++ SPDX-License-Identifier: BSD-2-Clause-Patent ++**/ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "DxeTpmMeasureBootLibSanitization.h" ++ ++#define GPT_HEADER_REVISION_V1 0x00010000 ++ ++/** ++ This function will validate the EFI_PARTITION_TABLE_HEADER structure is safe to parse ++ However this function will not attempt to verify the validity of the GPT partition ++ It will check the following: ++ - Signature ++ - Revision ++ - AlternateLBA ++ - FirstUsableLBA ++ - LastUsableLBA ++ - PartitionEntryLBA ++ - NumberOfPartitionEntries ++ - SizeOfPartitionEntry ++ - BlockIo ++ ++ @param[in] PrimaryHeader ++ Pointer to the EFI_PARTITION_TABLE_HEADER structure. ++ ++ @param[in] BlockIo ++ Pointer to the EFI_BLOCK_IO_PROTOCOL structure. ++ ++ @retval EFI_SUCCESS ++ The EFI_PARTITION_TABLE_HEADER structure is valid. ++ ++ @retval EFI_INVALID_PARAMETER ++ The EFI_PARTITION_TABLE_HEADER structure is invalid. ++**/ ++EFI_STATUS ++EFIAPI ++SanitizeEfiPartitionTableHeader ( ++ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, ++ IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo ++ ) ++{ ++ // Verify that the input parameters are safe to use ++ if (PrimaryHeader == NULL) { ++ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header!\n")); ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if ((BlockIo == NULL) || (BlockIo->Media == NULL)) { ++ DEBUG ((DEBUG_ERROR, "Invalid BlockIo!\n")); ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // The signature must be EFI_PTAB_HEADER_ID ("EFI PART" in ASCII) ++ if (PrimaryHeader->Header.Signature != EFI_PTAB_HEADER_ID) { ++ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // The version must be GPT_HEADER_REVISION_V1 (0x00010000) ++ if (PrimaryHeader->Header.Revision != GPT_HEADER_REVISION_V1) { ++ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header Revision!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // The HeaderSize must be greater than or equal to 92 and must be less than or equal to the logical block size ++ if ((PrimaryHeader->Header.HeaderSize < sizeof (EFI_PARTITION_TABLE_HEADER)) || (PrimaryHeader->Header.HeaderSize > BlockIo->Media->BlockSize)) { ++ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header HeaderSize!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // check that the PartitionEntryLBA greater than the Max LBA ++ // This will be used later for multiplication ++ if (PrimaryHeader->PartitionEntryLBA > DivU64x32 (MAX_UINT64, BlockIo->Media->BlockSize)) { ++ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header PartitionEntryLBA!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // Check that the number of partition entries is greater than zero ++ if (PrimaryHeader->NumberOfPartitionEntries == 0) { ++ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header NumberOfPartitionEntries!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // SizeOfPartitionEntry must be 128, 256, 512... improper size may lead to accessing uninitialized memory ++ if ((PrimaryHeader->SizeOfPartitionEntry < 128) || ((PrimaryHeader->SizeOfPartitionEntry & (PrimaryHeader->SizeOfPartitionEntry - 1)) != 0)) { ++ DEBUG ((DEBUG_ERROR, "SizeOfPartitionEntry shall be set to a value of 128 x 2^n where n is an integer greater than or equal to zero (e.g., 128, 256, 512, etc.)!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // This check is to prevent overflow when calculating the allocation size for the partition entries ++ // This check will be used later for multiplication ++ if (PrimaryHeader->NumberOfPartitionEntries > DivU64x32 (MAX_UINT64, PrimaryHeader->SizeOfPartitionEntry)) { ++ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header NumberOfPartitionEntries!\n")); ++ return EFI_DEVICE_ERROR; ++ } ++ ++ return EFI_SUCCESS; ++} ++ ++/** ++ This function will validate that the allocation size from the primary header is sane ++ It will check the following: ++ - AllocationSize does not overflow ++ ++ @param[in] PrimaryHeader ++ Pointer to the EFI_PARTITION_TABLE_HEADER structure. ++ ++ @param[out] AllocationSize ++ Pointer to the allocation size. ++ ++ @retval EFI_SUCCESS ++ The allocation size is valid. ++ ++ @retval EFI_OUT_OF_RESOURCES ++ The allocation size is invalid. ++**/ ++EFI_STATUS ++EFIAPI ++SanitizePrimaryHeaderAllocationSize ( ++ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, ++ OUT UINT32 *AllocationSize ++ ) ++{ ++ EFI_STATUS Status; ++ ++ if (PrimaryHeader == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if (AllocationSize == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // Replacing logic: ++ // PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry; ++ Status = SafeUint32Mult (PrimaryHeader->NumberOfPartitionEntries, PrimaryHeader->SizeOfPartitionEntry, AllocationSize); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "Allocation Size would have overflowed!\n")); ++ return EFI_BAD_BUFFER_SIZE; ++ } ++ ++ return EFI_SUCCESS; ++} ++ ++/** ++ This function will validate that the Gpt Event Size calculated from the primary header is sane ++ It will check the following: ++ - EventSize does not overflow ++ ++ Important: This function includes the entire length of the allocated space, including the ++ TCG_PCR_EVENT_HDR. When hashing the buffer allocated with this size, the caller must subtract ++ the size of the TCG_PCR_EVENT_HDR from the size of the buffer before hashing. ++ ++ @param[in] PrimaryHeader - Pointer to the EFI_PARTITION_TABLE_HEADER structure. ++ @param[in] NumberOfPartition - Number of partitions. ++ @param[out] EventSize - Pointer to the event size. ++ ++ @retval EFI_SUCCESS ++ The event size is valid. ++ ++ @retval EFI_OUT_OF_RESOURCES ++ Overflow would have occurred. ++ ++ @retval EFI_INVALID_PARAMETER ++ One of the passed parameters was invalid. ++**/ ++EFI_STATUS ++SanitizePrimaryHeaderGptEventSize ( ++ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, ++ IN UINTN NumberOfPartition, ++ OUT UINT32 *EventSize ++ ) ++{ ++ EFI_STATUS Status; ++ UINT32 SafeNumberOfPartitions; ++ ++ if (PrimaryHeader == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if (EventSize == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // We shouldn't even attempt to perform the multiplication if the number of partitions is greater than the maximum value of UINT32 ++ Status = SafeUintnToUint32 (NumberOfPartition, &SafeNumberOfPartitions); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "NumberOfPartition would have overflowed!\n")); ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // Replacing logic: ++ // (UINT32)(sizeof (EFI_GPT_DATA) - sizeof (GptData->Partitions) + NumberOfPartition * PrimaryHeader.SizeOfPartitionEntry + sizeof (TCG_PCR_EVENT_HDR)); ++ Status = SafeUint32Mult (SafeNumberOfPartitions, PrimaryHeader->SizeOfPartitionEntry, EventSize); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "Event Size would have overflowed!\n")); ++ return EFI_BAD_BUFFER_SIZE; ++ } ++ ++ Status = SafeUint32Add ( ++ sizeof (TCG_PCR_EVENT_HDR) + ++ OFFSET_OF (EFI_GPT_DATA, Partitions), ++ *EventSize, ++ EventSize ++ ); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "Event Size would have overflowed because of GPTData!\n")); ++ return EFI_BAD_BUFFER_SIZE; ++ } ++ ++ return EFI_SUCCESS; ++} +diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h +new file mode 100644 +index 0000000..0d9d00c +--- /dev/null ++++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h +@@ -0,0 +1,114 @@ ++/** @file ++ This file includes the function prototypes for the sanitization functions. ++ ++ These are those functions: ++ ++ DxeTpmMeasureBootLibImageRead() function will make sure the PE/COFF image content ++ read is within the image buffer. ++ ++ TcgMeasurePeImage() function will accept untrusted PE/COFF image and validate its ++ data structure within this image buffer before use. ++ ++ TcgMeasureGptTable() function will receive untrusted GPT partition table, and parse ++ partition data carefully. ++ ++ Copyright (c) Microsoft Corporation.
++ SPDX-License-Identifier: BSD-2-Clause-Patent ++ ++**/ ++ ++#ifndef DXE_TPM_MEASURE_BOOT_LIB_VALIDATION_ ++#define DXE_TPM_MEASURE_BOOT_LIB_VALIDATION_ ++ ++#include ++#include ++#include ++#include ++ ++/** ++ This function will validate the EFI_PARTITION_TABLE_HEADER structure is safe to parse ++ However this function will not attempt to verify the validity of the GPT partition ++ It will check the following: ++ - Signature ++ - Revision ++ - AlternateLBA ++ - FirstUsableLBA ++ - LastUsableLBA ++ - PartitionEntryLBA ++ - NumberOfPartitionEntries ++ - SizeOfPartitionEntry ++ - BlockIo ++ ++ @param[in] PrimaryHeader ++ Pointer to the EFI_PARTITION_TABLE_HEADER structure. ++ ++ @param[in] BlockIo ++ Pointer to the EFI_BLOCK_IO_PROTOCOL structure. ++ ++ @retval EFI_SUCCESS ++ The EFI_PARTITION_TABLE_HEADER structure is valid. ++ ++ @retval EFI_INVALID_PARAMETER ++ The EFI_PARTITION_TABLE_HEADER structure is invalid. ++**/ ++EFI_STATUS ++EFIAPI ++SanitizeEfiPartitionTableHeader ( ++ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, ++ IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo ++ ); ++ ++/** ++ This function will validate that the allocation size from the primary header is sane ++ It will check the following: ++ - AllocationSize does not overflow ++ ++ @param[in] PrimaryHeader ++ Pointer to the EFI_PARTITION_TABLE_HEADER structure. ++ ++ @param[out] AllocationSize ++ Pointer to the allocation size. ++ ++ @retval EFI_SUCCESS ++ The allocation size is valid. ++ ++ @retval EFI_OUT_OF_RESOURCES ++ The allocation size is invalid. ++**/ ++EFI_STATUS ++EFIAPI ++SanitizePrimaryHeaderAllocationSize ( ++ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, ++ OUT UINT32 *AllocationSize ++ ); ++ ++/** ++ This function will validate that the Gpt Event Size calculated from the primary header is sane ++ It will check the following: ++ - EventSize does not overflow ++ ++ Important: This function includes the entire length of the allocated space, including the ++ TCG_PCR_EVENT_HDR. When hashing the buffer allocated with this size, the caller must subtract ++ the size of the TCG_PCR_EVENT_HDR from the size of the buffer before hashing. ++ ++ @param[in] PrimaryHeader - Pointer to the EFI_PARTITION_TABLE_HEADER structure. ++ @param[in] NumberOfPartition - Number of partitions. ++ @param[out] EventSize - Pointer to the event size. ++ ++ @retval EFI_SUCCESS ++ The event size is valid. ++ ++ @retval EFI_OUT_OF_RESOURCES ++ Overflow would have occurred. ++ ++ @retval EFI_INVALID_PARAMETER ++ One of the passed parameters was invalid. ++**/ ++EFI_STATUS ++SanitizePrimaryHeaderGptEventSize ( ++ IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, ++ IN UINTN NumberOfPartition, ++ OUT UINT32 *EventSize ++ ); ++ ++#endif // DXE_TPM_MEASURE_BOOT_LIB_VALIDATION_ +diff --git a/SecurityPkg/SecurityPkg.ci.yaml b/SecurityPkg/SecurityPkg.ci.yaml +index 1036b18..28d9645 100644 +--- a/SecurityPkg/SecurityPkg.ci.yaml ++++ b/SecurityPkg/SecurityPkg.ci.yaml +@@ -17,6 +17,7 @@ + "ExceptionList": [ + "8005", "gRT", + "8001", "DxeTpm2MeasureBootLibUnitTestMain", ++ "8001", "DxeTpmMeasureBootLibUnitTestMain" + ], + ## Both file path and directory path are accepted. + "IgnoreFiles": [ +diff --git a/SecurityPkg/Test/SecurityPkgHostTest.dsc b/SecurityPkg/Test/SecurityPkgHostTest.dsc +index ebf132b..426c9ca 100644 +--- a/SecurityPkg/Test/SecurityPkgHostTest.dsc ++++ b/SecurityPkg/Test/SecurityPkgHostTest.dsc +@@ -26,6 +26,7 @@ + SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.inf + SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf + SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTestHost.inf ++ SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTestHost.inf + + # + # Build SecurityPkg HOST_APPLICATION Tests +-- +2.25.1 + + +From d1ec46e1eb2289ebd2a9a61f18a9e5c1f286278f Mon Sep 17 00:00:00 2001 +From: "Douglas Flick [MSFT]" +Date: Fri, 12 Jan 2024 02:16:03 +0800 +Subject: [PATCH 3/6] SecurityPkg: : Adding CVE 2022-36763 to + SecurityFixes.yaml + +This creates / adds a security file that tracks the security fixes +found in this package and can be used to find the fixes that were +applied. + +Cc: Jiewen Yao + +Signed-off-by: Doug Flick [MSFT] +Reviewed-by: Jiewen Yao +--- + SecurityPkg/SecurityFixes.yaml | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + create mode 100644 SecurityPkg/SecurityFixes.yaml + +diff --git a/SecurityPkg/SecurityFixes.yaml b/SecurityPkg/SecurityFixes.yaml +new file mode 100644 +index 0000000..f9e3e7b +--- /dev/null ++++ b/SecurityPkg/SecurityFixes.yaml +@@ -0,0 +1,22 @@ ++## @file ++# Security Fixes for SecurityPkg ++# ++# Copyright (c) Microsoft Corporation ++# SPDX-License-Identifier: BSD-2-Clause-Patent ++## ++CVE_2022_36763: ++ commit_titles: ++ - "SecurityPkg: DxeTpm2Measurement: SECURITY PATCH 4117 - CVE 2022-36763" ++ - "SecurityPkg: DxeTpmMeasurement: SECURITY PATCH 4117 - CVE 2022-36763" ++ - "SecurityPkg: : Adding CVE 2022-36763 to SecurityFixes.yaml" ++ cve: CVE-2022-36763 ++ date_reported: 2022-10-25 11:31 UTC ++ description: (CVE-2022-36763) - Heap Buffer Overflow in Tcg2MeasureGptTable() ++ note: This patch is related to and supersedes TCBZ2168 ++ files_impacted: ++ - Library\DxeTpm2MeasureBootLib\DxeTpm2MeasureBootLib.c ++ - Library\DxeTpmMeasureBootLib\DxeTpmMeasureBootLib.c ++ links: ++ - https://bugzilla.tianocore.org/show_bug.cgi?id=4117 ++ - https://bugzilla.tianocore.org/show_bug.cgi?id=2168 ++ - https://bugzilla.tianocore.org/show_bug.cgi?id=1990 +-- +2.25.1 + + +From d195161841029615782c08aa25a34041075ff545 Mon Sep 17 00:00:00 2001 +From: "Douglas Flick [MSFT]" +Date: Fri, 12 Jan 2024 02:16:04 +0800 +Subject: [PATCH 4/6] SecurityPkg: DxeTpm2MeasureBootLib: SECURITY PATCH 4118 - + CVE 2022-36764 + +This commit contains the patch files and tests for DxeTpm2MeasureBootLib +CVE 2022-36764. + +Cc: Jiewen Yao + +Signed-off-by: Doug Flick [MSFT] +Reviewed-by: Jiewen Yao +--- + .../DxeTpm2MeasureBootLib.c | 12 ++-- + .../DxeTpm2MeasureBootLibSanitization.c | 46 +++++++++++++- + .../DxeTpm2MeasureBootLibSanitization.h | 28 ++++++++- + .../DxeTpm2MeasureBootLibSanitizationTest.c | 60 ++++++++++++++++--- + 4 files changed, 131 insertions(+), 15 deletions(-) + +diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c +index 0475103..714cc8e 100644 +--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c ++++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c +@@ -378,7 +378,6 @@ Exit: + @retval EFI_OUT_OF_RESOURCES No enough resource to measure image. + @retval EFI_UNSUPPORTED ImageType is unsupported or PE image is mal-format. + @retval other error value +- + **/ + EFI_STATUS + EFIAPI +@@ -405,6 +404,7 @@ Tcg2MeasurePeImage ( + Status = EFI_UNSUPPORTED; + ImageLoad = NULL; + EventPtr = NULL; ++ Tcg2Event = NULL; + + Tcg2Protocol = MeasureBootProtocols->Tcg2Protocol; + CcProtocol = MeasureBootProtocols->CcProtocol; +@@ -420,18 +420,22 @@ Tcg2MeasurePeImage ( + } + + FilePathSize = (UINT32)GetDevicePathSize (FilePath); ++ Status = SanitizePeImageEventSize (FilePathSize, &EventSize); ++ if (EFI_ERROR (Status)) { ++ return EFI_UNSUPPORTED; ++ } + + // + // Determine destination PCR by BootPolicy + // +- EventSize = sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath) + FilePathSize; +- EventPtr = AllocateZeroPool (EventSize + sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event)); ++ // from a malicious GPT disk partition ++ EventPtr = AllocateZeroPool (EventSize); + if (EventPtr == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Tcg2Event = (EFI_TCG2_EVENT *)EventPtr; +- Tcg2Event->Size = EventSize + sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event); ++ Tcg2Event->Size = EventSize; + Tcg2Event->Header.HeaderSize = sizeof (EFI_TCG2_EVENT_HEADER); + Tcg2Event->Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION; + ImageLoad = (EFI_IMAGE_LOAD_EVENT *)Tcg2Event->Event; +diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c +index e230965..2a4d52c 100644 +--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c ++++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c +@@ -151,7 +151,7 @@ SanitizeEfiPartitionTableHeader ( + } + + /** +- This function will validate that the allocation size from the primary header is sane ++ This function will validate that the allocation size from the primary header is sane + It will check the following: + - AllocationSize does not overflow + +@@ -273,3 +273,47 @@ SanitizePrimaryHeaderGptEventSize ( + + return EFI_SUCCESS; + } ++ ++/** ++ This function will validate that the PeImage Event Size from the loaded image is sane ++ It will check the following: ++ - EventSize does not overflow ++ ++ @param[in] FilePathSize - Size of the file path. ++ @param[out] EventSize - Pointer to the event size. ++ ++ @retval EFI_SUCCESS ++ The event size is valid. ++ ++ @retval EFI_OUT_OF_RESOURCES ++ Overflow would have occurred. ++ ++ @retval EFI_INVALID_PARAMETER ++ One of the passed parameters was invalid. ++**/ ++EFI_STATUS ++SanitizePeImageEventSize ( ++ IN UINT32 FilePathSize, ++ OUT UINT32 *EventSize ++ ) ++{ ++ EFI_STATUS Status; ++ ++ // Replacing logic: ++ // sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath) + FilePathSize; ++ Status = SafeUint32Add (OFFSET_OF (EFI_IMAGE_LOAD_EVENT, DevicePath), FilePathSize, EventSize); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "EventSize would overflow!\n")); ++ return EFI_BAD_BUFFER_SIZE; ++ } ++ ++ // Replacing logic: ++ // EventSize + sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event) ++ Status = SafeUint32Add (*EventSize, OFFSET_OF (EFI_TCG2_EVENT, Event), EventSize); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "EventSize would overflow!\n")); ++ return EFI_BAD_BUFFER_SIZE; ++ } ++ ++ return EFI_SUCCESS; ++} +diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h +index 048b738..8f72ba4 100644 +--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h ++++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h +@@ -9,6 +9,9 @@ + Tcg2MeasureGptTable() function will receive untrusted GPT partition table, and parse + partition data carefully. + ++ Tcg2MeasurePeImage() function will accept untrusted PE/COFF image and validate its ++ data structure within this image buffer before use. ++ + Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +@@ -110,4 +113,27 @@ SanitizePrimaryHeaderGptEventSize ( + OUT UINT32 *EventSize + ); + +-#endif // DXE_TPM2_MEASURE_BOOT_LIB_SANITATION_ ++/** ++ This function will validate that the PeImage Event Size from the loaded image is sane ++ It will check the following: ++ - EventSize does not overflow ++ ++ @param[in] FilePathSize - Size of the file path. ++ @param[out] EventSize - Pointer to the event size. ++ ++ @retval EFI_SUCCESS ++ The event size is valid. ++ ++ @retval EFI_OUT_OF_RESOURCES ++ Overflow would have occurred. ++ ++ @retval EFI_INVALID_PARAMETER ++ One of the passed parameters was invalid. ++**/ ++EFI_STATUS ++SanitizePeImageEventSize ( ++ IN UINT32 FilePathSize, ++ OUT UINT32 *EventSize ++ ); ++ ++#endif // DXE_TPM2_MEASURE_BOOT_LIB_VALIDATION_ +diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c +index 3eb9763..820e99a 100644 +--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c ++++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c +@@ -72,10 +72,10 @@ TestSanitizeEfiPartitionTableHeader ( + PrimaryHeader.Header.Revision = DEFAULT_PRIMARY_TABLE_HEADER_REVISION; + PrimaryHeader.Header.HeaderSize = sizeof (EFI_PARTITION_TABLE_HEADER); + PrimaryHeader.MyLBA = 1; +- PrimaryHeader.AlternateLBA = 2; +- PrimaryHeader.FirstUsableLBA = 3; +- PrimaryHeader.LastUsableLBA = 4; +- PrimaryHeader.PartitionEntryLBA = 5; ++ PrimaryHeader.PartitionEntryLBA = 2; ++ PrimaryHeader.AlternateLBA = 3; ++ PrimaryHeader.FirstUsableLBA = 4; ++ PrimaryHeader.LastUsableLBA = 5; + PrimaryHeader.NumberOfPartitionEntries = DEFAULT_PRIMARY_TABLE_HEADER_NUMBER_OF_PARTITION_ENTRIES; + PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; + PrimaryHeader.PartitionEntryArrayCRC32 = 0; // Purposely invalid +@@ -187,11 +187,6 @@ TestSanitizePrimaryHeaderGptEventSize ( + EFI_STATUS Status; + EFI_PARTITION_TABLE_HEADER PrimaryHeader; + UINTN NumberOfPartition; +- EFI_GPT_DATA *GptData; +- EFI_TCG2_EVENT *Tcg2Event; +- +- Tcg2Event = NULL; +- GptData = NULL; + + // Test that a normal PrimaryHeader passes validation + PrimaryHeader.NumberOfPartitionEntries = 5; +@@ -225,6 +220,52 @@ TestSanitizePrimaryHeaderGptEventSize ( + return UNIT_TEST_PASSED; + } + ++/** ++ This function tests the SanitizePeImageEventSize function. ++ It's intent is to test that the untrusted input from a file path when generating a ++ EFI_IMAGE_LOAD_EVENT structure will not cause an overflow when calculating ++ the event size when allocating space ++ ++ @param[in] Context The unit test context. ++ ++ @retval UNIT_TEST_PASSED The test passed. ++ @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. ++**/ ++UNIT_TEST_STATUS ++EFIAPI ++TestSanitizePeImageEventSize ( ++ IN UNIT_TEST_CONTEXT Context ++ ) ++{ ++ UINT32 EventSize; ++ UINTN ExistingLogicEventSize; ++ UINT32 FilePathSize; ++ EFI_STATUS Status; ++ ++ FilePathSize = 255; ++ ++ // Test that a normal PE image passes validation ++ Status = SanitizePeImageEventSize (FilePathSize, &EventSize); ++ UT_ASSERT_EQUAL (Status, EFI_SUCCESS); ++ ++ // Test that the event size is correct compared to the existing logic ++ ExistingLogicEventSize = OFFSET_OF (EFI_IMAGE_LOAD_EVENT, DevicePath) + FilePathSize; ++ ExistingLogicEventSize += OFFSET_OF (EFI_TCG2_EVENT, Event); ++ ++ if (EventSize != ExistingLogicEventSize) { ++ UT_LOG_ERROR ("SanitizePeImageEventSize returned an incorrect event size. Expected %u, got %u\n", ExistingLogicEventSize, EventSize); ++ return UNIT_TEST_ERROR_TEST_FAILED; ++ } ++ ++ // Test that the event size may not overflow ++ Status = SanitizePeImageEventSize (MAX_UINT32, &EventSize); ++ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); ++ ++ DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); ++ ++ return UNIT_TEST_PASSED; ++} ++ + // *--------------------------------------------------------------------* + // * Unit Test Code Main Function + // *--------------------------------------------------------------------* +@@ -267,6 +308,7 @@ UefiTestMain ( + AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Validating EFI Partition Table", "Common.Tcg2MeasureBootLibValidation", TestSanitizeEfiPartitionTableHeader, NULL, NULL, NULL); + AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Primary header gpt event checks for overflow", "Common.Tcg2MeasureBootLibValidation", TestSanitizePrimaryHeaderAllocationSize, NULL, NULL, NULL); + AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Primary header allocation size checks for overflow", "Common.Tcg2MeasureBootLibValidation", TestSanitizePrimaryHeaderGptEventSize, NULL, NULL, NULL); ++ AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests PE Image and FileSize checks for overflow", "Common.Tcg2MeasureBootLibValidation", TestSanitizePeImageEventSize, NULL, NULL, NULL); + + Status = RunAllTestSuites (Framework); + +-- +2.25.1 + + +From 48dc6c3dd3760bca2d916967e7f3ee340368e0d7 Mon Sep 17 00:00:00 2001 +From: "Douglas Flick [MSFT]" +Date: Fri, 12 Jan 2024 02:16:05 +0800 +Subject: [PATCH 5/6] SecurityPkg: DxeTpmMeasureBootLib: SECURITY PATCH 4118 - + CVE 2022-36764 + +This commit contains the patch files and tests for DxeTpmMeasureBootLib +CVE 2022-36764. + +Cc: Jiewen Yao + +Signed-off-by: Doug Flick [MSFT] +Reviewed-by: Jiewen Yao +--- + .../DxeTpmMeasureBootLib.c | 13 ++- + .../DxeTpmMeasureBootLibSanitization.c | 44 +++++++++ + .../DxeTpmMeasureBootLibSanitization.h | 23 +++++ + .../DxeTpmMeasureBootLibSanitizationTest.c | 98 +++++++++++++++++-- + 4 files changed, 168 insertions(+), 10 deletions(-) + +diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c +index 669ab19..a9fc440 100644 +--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c ++++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c +@@ -17,6 +17,7 @@ + + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent ++Copyright (c) Microsoft Corporation.
+ + Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +@@ -345,18 +346,22 @@ TcgMeasurePeImage ( + ImageLoad = NULL; + SectionHeader = NULL; + Sha1Ctx = NULL; ++ TcgEvent = NULL; + FilePathSize = (UINT32)GetDevicePathSize (FilePath); + +- // + // Determine destination PCR by BootPolicy + // +- EventSize = sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath) + FilePathSize; +- TcgEvent = AllocateZeroPool (EventSize + sizeof (TCG_PCR_EVENT)); ++ Status = SanitizePeImageEventSize (FilePathSize, &EventSize); ++ if (EFI_ERROR (Status)) { ++ return EFI_UNSUPPORTED; ++ } ++ ++ TcgEvent = AllocateZeroPool (EventSize); + if (TcgEvent == NULL) { + return EFI_OUT_OF_RESOURCES; + } + +- TcgEvent->EventSize = EventSize; ++ TcgEvent->EventSize = EventSize - sizeof (TCG_PCR_EVENT_HDR); + ImageLoad = (EFI_IMAGE_LOAD_EVENT *)TcgEvent->Event; + + switch (ImageType) { +diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c +index a3fa46f..c989851 100644 +--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c ++++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c +@@ -239,3 +239,47 @@ SanitizePrimaryHeaderGptEventSize ( + + return EFI_SUCCESS; + } ++ ++/** ++ This function will validate that the PeImage Event Size from the loaded image is sane ++ It will check the following: ++ - EventSize does not overflow ++ ++ @param[in] FilePathSize - Size of the file path. ++ @param[out] EventSize - Pointer to the event size. ++ ++ @retval EFI_SUCCESS ++ The event size is valid. ++ ++ @retval EFI_OUT_OF_RESOURCES ++ Overflow would have occurred. ++ ++ @retval EFI_INVALID_PARAMETER ++ One of the passed parameters was invalid. ++**/ ++EFI_STATUS ++SanitizePeImageEventSize ( ++ IN UINT32 FilePathSize, ++ OUT UINT32 *EventSize ++ ) ++{ ++ EFI_STATUS Status; ++ ++ // Replacing logic: ++ // sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath) + FilePathSize; ++ Status = SafeUint32Add (OFFSET_OF (EFI_IMAGE_LOAD_EVENT, DevicePath), FilePathSize, EventSize); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "EventSize would overflow!\n")); ++ return EFI_BAD_BUFFER_SIZE; ++ } ++ ++ // Replacing logic: ++ // EventSize + sizeof (TCG_PCR_EVENT_HDR) ++ Status = SafeUint32Add (*EventSize, sizeof (TCG_PCR_EVENT_HDR), EventSize); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "EventSize would overflow!\n")); ++ return EFI_BAD_BUFFER_SIZE; ++ } ++ ++ return EFI_SUCCESS; ++} +diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h +index 0d9d00c..2248495 100644 +--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h ++++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h +@@ -111,4 +111,27 @@ SanitizePrimaryHeaderGptEventSize ( + OUT UINT32 *EventSize + ); + ++/** ++ This function will validate that the PeImage Event Size from the loaded image is sane ++ It will check the following: ++ - EventSize does not overflow ++ ++ @param[in] FilePathSize - Size of the file path. ++ @param[out] EventSize - Pointer to the event size. ++ ++ @retval EFI_SUCCESS ++ The event size is valid. ++ ++ @retval EFI_OUT_OF_RESOURCES ++ Overflow would have occurred. ++ ++ @retval EFI_INVALID_PARAMETER ++ One of the passed parameters was invalid. ++**/ ++EFI_STATUS ++SanitizePeImageEventSize ( ++ IN UINT32 FilePathSize, ++ OUT UINT32 *EventSize ++ ); ++ + #endif // DXE_TPM_MEASURE_BOOT_LIB_VALIDATION_ +diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c +index eeb928c..c41498b 100644 +--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c ++++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c +@@ -1,8 +1,8 @@ + /** @file +-This file includes the unit test cases for the DxeTpmMeasureBootLibSanitizationTest.c. ++ This file includes the unit test cases for the DxeTpmMeasureBootLibSanitizationTest.c. + +-Copyright (c) Microsoft Corporation.
+-SPDX-License-Identifier: BSD-2-Clause-Patent ++ Copyright (c) Microsoft Corporation.
++ SPDX-License-Identifier: BSD-2-Clause-Patent + **/ + + #include +@@ -186,9 +186,6 @@ TestSanitizePrimaryHeaderGptEventSize ( + EFI_STATUS Status; + EFI_PARTITION_TABLE_HEADER PrimaryHeader; + UINTN NumberOfPartition; +- EFI_GPT_DATA *GptData; +- +- GptData = NULL; + + // Test that a normal PrimaryHeader passes validation + PrimaryHeader.NumberOfPartitionEntries = 5; +@@ -222,6 +219,94 @@ TestSanitizePrimaryHeaderGptEventSize ( + return UNIT_TEST_PASSED; + } + ++/** ++ This function tests the SanitizePeImageEventSize function. ++ It's intent is to test that the untrusted input from a file path for an ++ EFI_IMAGE_LOAD_EVENT structure will not cause an overflow when calculating ++ the event size when allocating space. ++ ++ @param[in] Context The unit test context. ++ ++ @retval UNIT_TEST_PASSED The test passed. ++ @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. ++**/ ++UNIT_TEST_STATUS ++EFIAPI ++TestSanitizePeImageEventSize ( ++ IN UNIT_TEST_CONTEXT Context ++ ) ++{ ++ UINT32 EventSize; ++ UINTN ExistingLogicEventSize; ++ UINT32 FilePathSize; ++ EFI_STATUS Status; ++ EFI_DEVICE_PATH_PROTOCOL DevicePath; ++ EFI_IMAGE_LOAD_EVENT *ImageLoadEvent; ++ UNIT_TEST_STATUS TestStatus; ++ ++ TestStatus = UNIT_TEST_ERROR_TEST_FAILED; ++ ++ // Generate EFI_DEVICE_PATH_PROTOCOL test data ++ DevicePath.Type = 0; ++ DevicePath.SubType = 0; ++ DevicePath.Length[0] = 0; ++ DevicePath.Length[1] = 0; ++ ++ // Generate EFI_IMAGE_LOAD_EVENT test data ++ ImageLoadEvent = AllocateZeroPool (sizeof (EFI_IMAGE_LOAD_EVENT) + sizeof (EFI_DEVICE_PATH_PROTOCOL)); ++ if (ImageLoadEvent == NULL) { ++ DEBUG ((DEBUG_ERROR, "%a: AllocateZeroPool failed\n", __func__)); ++ goto Exit; ++ } ++ ++ // Populate EFI_IMAGE_LOAD_EVENT54 test data ++ ImageLoadEvent->ImageLocationInMemory = (EFI_PHYSICAL_ADDRESS)0x12345678; ++ ImageLoadEvent->ImageLengthInMemory = 0x1000; ++ ImageLoadEvent->ImageLinkTimeAddress = (UINTN)ImageLoadEvent; ++ ImageLoadEvent->LengthOfDevicePath = sizeof (EFI_DEVICE_PATH_PROTOCOL); ++ CopyMem (ImageLoadEvent->DevicePath, &DevicePath, sizeof (EFI_DEVICE_PATH_PROTOCOL)); ++ ++ FilePathSize = 255; ++ ++ // Test that a normal PE image passes validation ++ Status = SanitizePeImageEventSize (FilePathSize, &EventSize); ++ if (EFI_ERROR (Status)) { ++ UT_LOG_ERROR ("SanitizePeImageEventSize failed with %r\n", Status); ++ goto Exit; ++ } ++ ++ // Test that the event size is correct compared to the existing logic ++ ExistingLogicEventSize = OFFSET_OF (EFI_IMAGE_LOAD_EVENT, DevicePath) + FilePathSize; ++ ExistingLogicEventSize += sizeof (TCG_PCR_EVENT_HDR); ++ ++ if (EventSize != ExistingLogicEventSize) { ++ UT_LOG_ERROR ("SanitizePeImageEventSize returned an incorrect event size. Expected %u, got %u\n", ExistingLogicEventSize, EventSize); ++ goto Exit; ++ } ++ ++ // Test that the event size may not overflow ++ Status = SanitizePeImageEventSize (MAX_UINT32, &EventSize); ++ if (Status != EFI_BAD_BUFFER_SIZE) { ++ UT_LOG_ERROR ("SanitizePeImageEventSize succeded when it was supposed to fail with %r\n", Status); ++ goto Exit; ++ } ++ ++ TestStatus = UNIT_TEST_PASSED; ++Exit: ++ ++ if (ImageLoadEvent != NULL) { ++ FreePool (ImageLoadEvent); ++ } ++ ++ if (TestStatus == UNIT_TEST_ERROR_TEST_FAILED) { ++ DEBUG ((DEBUG_ERROR, "%a: Test failed\n", __func__)); ++ } else { ++ DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); ++ } ++ ++ return TestStatus; ++} ++ + // *--------------------------------------------------------------------* + // * Unit Test Code Main Function + // *--------------------------------------------------------------------* +@@ -265,6 +350,7 @@ UefiTestMain ( + AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Validating EFI Partition Table", "Common.TcgMeasureBootLibValidation", TestSanitizeEfiPartitionTableHeader, NULL, NULL, NULL); + AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Primary header gpt event checks for overflow", "Common.TcgMeasureBootLibValidation", TestSanitizePrimaryHeaderAllocationSize, NULL, NULL, NULL); + AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Primary header allocation size checks for overflow", "Common.TcgMeasureBootLibValidation", TestSanitizePrimaryHeaderGptEventSize, NULL, NULL, NULL); ++ AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests PE Image and FileSize checks for overflow", "Common.TcgMeasureBootLibValidation", TestSanitizePeImageEventSize, NULL, NULL, NULL); + + Status = RunAllTestSuites (Framework); + +-- +2.25.1 + + +From c98a06b18c71f94cc65f2f8fee678da23f45c593 Mon Sep 17 00:00:00 2001 +From: "Douglas Flick [MSFT]" +Date: Fri, 12 Jan 2024 02:16:06 +0800 +Subject: [PATCH 6/6] SecurityPkg: : Adding CVE 2022-36764 to + SecurityFixes.yaml + +This creates / adds a security file that tracks the security fixes +found in this package and can be used to find the fixes that were +applied. + +Cc: Jiewen Yao + +Signed-off-by: Doug Flick [MSFT] +Reviewed-by: Jiewen Yao +--- + SecurityPkg/SecurityFixes.yaml | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/SecurityPkg/SecurityFixes.yaml b/SecurityPkg/SecurityFixes.yaml +index f9e3e7b..833fb82 100644 +--- a/SecurityPkg/SecurityFixes.yaml ++++ b/SecurityPkg/SecurityFixes.yaml +@@ -20,3 +20,17 @@ CVE_2022_36763: + - https://bugzilla.tianocore.org/show_bug.cgi?id=4117 + - https://bugzilla.tianocore.org/show_bug.cgi?id=2168 + - https://bugzilla.tianocore.org/show_bug.cgi?id=1990 ++CVE_2022_36764: ++ commit_titles: ++ - "SecurityPkg: DxeTpm2MeasureBootLib: SECURITY PATCH 4118 - CVE 2022-36764" ++ - "SecurityPkg: DxeTpmMeasureBootLib: SECURITY PATCH 4118 - CVE 2022-36764" ++ - "SecurityPkg: : Adding CVE 2022-36764 to SecurityFixes.yaml" ++ cve: CVE-2022-36764 ++ date_reported: 2022-10-25 12:23 UTC ++ description: Heap Buffer Overflow in Tcg2MeasurePeImage() ++ note: ++ files_impacted: ++ - Library\DxeTpm2MeasureBootLib\DxeTpm2MeasureBootLib.c ++ - Library\DxeTpmMeasureBootLib\DxeTpmMeasureBootLib.c ++ links: ++ - https://bugzilla.tianocore.org/show_bug.cgi?id=4118 +-- +2.25.1 + diff --git a/SPECS/edk2/CVE-2022-36764.nopatch b/SPECS/edk2/CVE-2022-36764.nopatch new file mode 100644 index 00000000000..10042e1db43 --- /dev/null +++ b/SPECS/edk2/CVE-2022-36764.nopatch @@ -0,0 +1,2 @@ +CVE already patch in CVE-2022-36763.patch +Ref: https://github.com/tianocore/edk2/pull/5264 \ No newline at end of file diff --git a/SPECS/edk2/CVE-2022-36765.patch b/SPECS/edk2/CVE-2022-36765.patch new file mode 100644 index 00000000000..e2689390d9a --- /dev/null +++ b/SPECS/edk2/CVE-2022-36765.patch @@ -0,0 +1,148 @@ +From aeaee8944f0eaacbf4cdf39279785b9ba4836bb6 Mon Sep 17 00:00:00 2001 +From: Gua Guo +Date: Thu, 11 Jan 2024 13:07:50 +0800 +Subject: [PATCH] EmbeddedPkg/Hob: Integer Overflow in CreateHob() + +REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4166 + +Fix integer overflow in various CreateHob instances. +Fixes: CVE-2022-36765 + +The CreateHob() function aligns the requested size to 8 +performing the following operation: +``` +HobLength = (UINT16)((HobLength + 0x7) & (~0x7)); +``` + +No checks are performed to ensure this value doesn't +overflow, and could lead to CreateHob() returning a smaller +HOB than requested, which could lead to OOB HOB accesses. + +Reported-by: Marc Beatove +Cc: Leif Lindholm +Reviewed-by: Ard Biesheuvel +Cc: Abner Chang +Cc: John Mathew +Authored-by: Gerd Hoffmann +Signed-off-by: Gua Guo +--- + EmbeddedPkg/Library/PrePiHobLib/Hob.c | 43 +++++++++++++++++++++++++++ + 1 file changed, 43 insertions(+) + +diff --git a/EmbeddedPkg/Library/PrePiHobLib/Hob.c b/EmbeddedPkg/Library/PrePiHobLib/Hob.c +index 8eb175aa96f9..cbc35152ccbc 100644 +--- a/EmbeddedPkg/Library/PrePiHobLib/Hob.c ++++ b/EmbeddedPkg/Library/PrePiHobLib/Hob.c +@@ -110,6 +110,13 @@ CreateHob ( + + HandOffHob = GetHobList (); + ++ // ++ // Check Length to avoid data overflow. ++ // ++ if (HobLength > MAX_UINT16 - 0x7) { ++ return NULL; ++ } ++ + HobLength = (UINT16)((HobLength + 0x7) & (~0x7)); + + FreeMemory = HandOffHob->EfiFreeMemoryTop - HandOffHob->EfiFreeMemoryBottom; +@@ -160,6 +167,9 @@ BuildResourceDescriptorHob ( + + Hob = CreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR)); + ASSERT (Hob != NULL); ++ if (Hob == NULL) { ++ return; ++ } + + Hob->ResourceType = ResourceType; + Hob->ResourceAttribute = ResourceAttribute; +@@ -401,6 +411,10 @@ BuildModuleHob ( + ); + + Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE)); ++ ASSERT (Hob != NULL); ++ if (Hob == NULL) { ++ return; ++ } + + CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid); + Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule; +@@ -449,6 +463,11 @@ BuildGuidHob ( + ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE))); + + Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16)(sizeof (EFI_HOB_GUID_TYPE) + DataLength)); ++ ASSERT (Hob != NULL); ++ if (Hob == NULL) { ++ return NULL; ++ } ++ + CopyGuid (&Hob->Name, Guid); + return Hob + 1; + } +@@ -512,6 +531,10 @@ BuildFvHob ( + EFI_HOB_FIRMWARE_VOLUME *Hob; + + Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME)); ++ ASSERT (Hob != NULL); ++ if (Hob == NULL) { ++ return; ++ } + + Hob->BaseAddress = BaseAddress; + Hob->Length = Length; +@@ -543,6 +566,10 @@ BuildFv2Hob ( + EFI_HOB_FIRMWARE_VOLUME2 *Hob; + + Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2)); ++ ASSERT (Hob != NULL); ++ if (Hob == NULL) { ++ return; ++ } + + Hob->BaseAddress = BaseAddress; + Hob->Length = Length; +@@ -584,6 +611,10 @@ BuildFv3Hob ( + EFI_HOB_FIRMWARE_VOLUME3 *Hob; + + Hob = CreateHob (EFI_HOB_TYPE_FV3, sizeof (EFI_HOB_FIRMWARE_VOLUME3)); ++ ASSERT (Hob != NULL); ++ if (Hob == NULL) { ++ return; ++ } + + Hob->BaseAddress = BaseAddress; + Hob->Length = Length; +@@ -639,6 +670,10 @@ BuildCpuHob ( + EFI_HOB_CPU *Hob; + + Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU)); ++ ASSERT (Hob != NULL); ++ if (Hob == NULL) { ++ return; ++ } + + Hob->SizeOfMemorySpace = SizeOfMemorySpace; + Hob->SizeOfIoSpace = SizeOfIoSpace; +@@ -676,6 +711,10 @@ BuildStackHob ( + ); + + Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK)); ++ ASSERT (Hob != NULL); ++ if (Hob == NULL) { ++ return; ++ } + + CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocStackGuid); + Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress; +@@ -756,6 +795,10 @@ BuildMemoryAllocationHob ( + ); + + Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION)); ++ ASSERT (Hob != NULL); ++ if (Hob == NULL) { ++ return; ++ } + + ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID)); + Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress; diff --git a/SPECS/edk2/CVE-2023-45230.patch b/SPECS/edk2/CVE-2023-45230.patch new file mode 100644 index 00000000000..76910d4accd --- /dev/null +++ b/SPECS/edk2/CVE-2023-45230.patch @@ -0,0 +1,1608 @@ +From f31453e8d6542461d92d835e0b79fec8b039174d Mon Sep 17 00:00:00 2001 +From: "Doug Flick via groups.io" +Date: Fri, 26 Jan 2024 05:54:43 +0800 +Subject: [PATCH] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Patch + +REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4535 + +Bug Details: +PixieFail Bug #2 +CVE-2023-45230 +CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H +CWE-119 Improper Restriction of Operations within the Bounds + of a Memory Buffer + +Changes Overview: +> -UINT8 * +> +EFI_STATUS +> Dhcp6AppendOption ( +> - IN OUT UINT8 *Buf, +> - IN UINT16 OptType, +> - IN UINT16 OptLen, +> - IN UINT8 *Data +> + IN OUT EFI_DHCP6_PACKET *Packet, +> + IN OUT UINT8 **PacketCursor, +> + IN UINT16 OptType, +> + IN UINT16 OptLen, +> + IN UINT8 *Data +> ); + +Dhcp6AppendOption() and variants can return errors now. All callsites +are adapted accordingly. + +It gets passed in EFI_DHCP6_PACKET as additional parameter ... + +> + // +> + // Verify the PacketCursor is within the packet +> + // +> + if ( (*PacketCursor < Packet->Dhcp6.Option) +> + || (*PacketCursor >= Packet->Dhcp6.Option + + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) +> + { +> + return EFI_INVALID_PARAMETER; +> + } + +... so it can look at Packet->Size when checking buffer space. +Also to allow Packet->Length updates. + +Lots of checks added. + +Cc: Saloni Kasbekar +Cc: Zachary Clark-williams + +Signed-off-by: Doug Flick [MSFT] +Reviewed-by: Saloni Kasbekar +--- + NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h | 43 +++ + NetworkPkg/Dhcp6Dxe/Dhcp6Io.c | 409 +++++++++++++++++++---------- + NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c | 373 +++++++++++++++++++++----- + NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h | 82 +++--- + 4 files changed, 668 insertions(+), 239 deletions(-) + +diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h +index 0eb9c669b5a1..f2422c2f2827 100644 +--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h ++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h +@@ -45,6 +45,49 @@ typedef struct _DHCP6_INSTANCE DHCP6_INSTANCE; + #define DHCP6_SERVICE_SIGNATURE SIGNATURE_32 ('D', 'H', '6', 'S') + #define DHCP6_INSTANCE_SIGNATURE SIGNATURE_32 ('D', 'H', '6', 'I') + ++// ++// For more information on DHCP options see RFC 8415, Section 21.1 ++// ++// The format of DHCP options is: ++// ++// 0 1 2 3 ++// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ++// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ++// | option-code | option-len | ++// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ++// | option-data | ++// | (option-len octets) | ++// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ++// ++#define DHCP6_SIZE_OF_OPT_CODE (sizeof(UINT16)) ++#define DHCP6_SIZE_OF_OPT_LEN (sizeof(UINT16)) ++ ++// ++// Combined size of Code and Length ++// ++#define DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN (DHCP6_SIZE_OF_OPT_CODE + \ ++ DHCP6_SIZE_OF_OPT_LEN) ++ ++STATIC_ASSERT ( ++ DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN == 4, ++ "Combined size of Code and Length must be 4 per RFC 8415" ++ ); ++ ++// ++// Offset to the length is just past the code ++// ++#define DHCP6_OPT_LEN_OFFSET(a) (a + DHCP6_SIZE_OF_OPT_CODE) ++STATIC_ASSERT ( ++ DHCP6_OPT_LEN_OFFSET (0) == 2, ++ "Offset of length is + 2 past start of option" ++ ); ++ ++#define DHCP6_OPT_DATA_OFFSET(a) (a + DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN) ++STATIC_ASSERT ( ++ DHCP6_OPT_DATA_OFFSET (0) == 4, ++ "Offset to option data should be +4 from start of option" ++ ); ++ + #define DHCP6_PACKET_ALL 0 + #define DHCP6_PACKET_STATEFUL 1 + #define DHCP6_PACKET_STATELESS 2 +diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c +index dcd01e6268b1..bf5aa7a769de 100644 +--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c ++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c +@@ -3,9 +3,9 @@ + + (C) Copyright 2014 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
++ Copyright (c) Microsoft Corporation + + SPDX-License-Identifier: BSD-2-Clause-Patent +- + **/ + + #include "Dhcp6Impl.h" +@@ -930,7 +930,8 @@ Dhcp6SendSolicitMsg ( + // + Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); + if (Packet == NULL) { +- return EFI_OUT_OF_RESOURCES; ++ Status = EFI_OUT_OF_RESOURCES; ++ goto ON_ERROR; + } + + Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen; +@@ -944,54 +945,64 @@ Dhcp6SendSolicitMsg ( + Cursor = Packet->Dhcp6.Option; + + Length = HTONS (ClientId->Length); +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptClientId), + Length, + ClientId->Duid + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendETOption ( +- Cursor, ++ Status = Dhcp6AppendETOption ( ++ Packet, ++ &Cursor, + Instance, + &Elapsed + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendIaOption ( +- Cursor, ++ Status = Dhcp6AppendIaOption ( ++ Packet, ++ &Cursor, + Instance->IaCb.Ia, + Instance->IaCb.T1, + Instance->IaCb.T2, + Packet->Dhcp6.Header.MessageType + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + + // + // Append user-defined when configurate Dhcp6 service. + // + for (Index = 0; Index < Instance->Config->OptionCount; Index++) { + UserOpt = Instance->Config->OptionList[Index]; +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + UserOpt->OpCode, + UserOpt->OpLen, + UserOpt->Data + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + } + +- // +- // Determine the size/length of packet. +- // +- Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option); + ASSERT (Packet->Size > Packet->Length + 8); + + // + // Callback to user with the packet to be sent and check the user's feedback. + // + Status = Dhcp6CallbackUser (Instance, Dhcp6SendSolicit, &Packet); +- + if (EFI_ERROR (Status)) { +- FreePool (Packet); +- return Status; ++ goto ON_ERROR; + } + + // +@@ -1005,10 +1016,8 @@ Dhcp6SendSolicitMsg ( + Instance->StartTime = 0; + + Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); +- + if (EFI_ERROR (Status)) { +- FreePool (Packet); +- return Status; ++ goto ON_ERROR; + } + + // +@@ -1020,6 +1029,14 @@ Dhcp6SendSolicitMsg ( + Elapsed, + Instance->Config->SolicitRetransmission + ); ++ ++ON_ERROR: ++ ++ if (Packet) { ++ FreePool (Packet); ++ } ++ ++ return Status; + } + + /** +@@ -1110,7 +1127,8 @@ Dhcp6SendRequestMsg ( + // + Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); + if (Packet == NULL) { +- return EFI_OUT_OF_RESOURCES; ++ Status = EFI_OUT_OF_RESOURCES; ++ goto ON_ERROR; + } + + Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen; +@@ -1124,51 +1142,67 @@ Dhcp6SendRequestMsg ( + Cursor = Packet->Dhcp6.Option; + + Length = HTONS (ClientId->Length); +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptClientId), + Length, + ClientId->Duid + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendETOption ( +- Cursor, ++ Status = Dhcp6AppendETOption ( ++ Packet, ++ &Cursor, + Instance, + &Elapsed + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptServerId), + ServerId->Length, + ServerId->Duid + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendIaOption ( +- Cursor, ++ Status = Dhcp6AppendIaOption ( ++ Packet, ++ &Cursor, + Instance->IaCb.Ia, + Instance->IaCb.T1, + Instance->IaCb.T2, + Packet->Dhcp6.Header.MessageType + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + + // + // Append user-defined when configurate Dhcp6 service. + // + for (Index = 0; Index < Instance->Config->OptionCount; Index++) { + UserOpt = Instance->Config->OptionList[Index]; +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + UserOpt->OpCode, + UserOpt->OpLen, + UserOpt->Data + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + } + +- // +- // Determine the size/length of packet. +- // +- Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option); + ASSERT (Packet->Size > Packet->Length + 8); + + // +@@ -1177,8 +1211,7 @@ Dhcp6SendRequestMsg ( + Status = Dhcp6CallbackUser (Instance, Dhcp6SendRequest, &Packet); + + if (EFI_ERROR (Status)) { +- FreePool (Packet); +- return Status; ++ goto ON_ERROR; + } + + // +@@ -1194,14 +1227,21 @@ Dhcp6SendRequestMsg ( + Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); + + if (EFI_ERROR (Status)) { +- FreePool (Packet); +- return Status; ++ goto ON_ERROR; + } + + // + // Enqueue the sent packet for the retransmission in case reply timeout. + // + return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); ++ ++ON_ERROR: ++ ++ if (Packet) { ++ FreePool (Packet); ++ } ++ ++ return Status; + } + + /** +@@ -1266,7 +1306,8 @@ Dhcp6SendDeclineMsg ( + // + Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE); + if (Packet == NULL) { +- return EFI_OUT_OF_RESOURCES; ++ Status = EFI_OUT_OF_RESOURCES; ++ goto ON_ERROR; + } + + Packet->Size = DHCP6_BASE_PACKET_SIZE; +@@ -1280,42 +1321,58 @@ Dhcp6SendDeclineMsg ( + Cursor = Packet->Dhcp6.Option; + + Length = HTONS (ClientId->Length); +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptClientId), + Length, + ClientId->Duid + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendETOption ( +- Cursor, ++ Status = Dhcp6AppendETOption ( ++ Packet, ++ &Cursor, + Instance, + &Elapsed + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptServerId), + ServerId->Length, + ServerId->Duid + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendIaOption (Cursor, DecIa, 0, 0, Packet->Dhcp6.Header.MessageType); ++ Status = Dhcp6AppendIaOption ( ++ Packet, ++ &Cursor, ++ DecIa, ++ 0, ++ 0, ++ Packet->Dhcp6.Header.MessageType ++ ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- // +- // Determine the size/length of packet. +- // +- Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option); + ASSERT (Packet->Size > Packet->Length + 8); + + // + // Callback to user with the packet to be sent and check the user's feedback. + // + Status = Dhcp6CallbackUser (Instance, Dhcp6SendDecline, &Packet); +- + if (EFI_ERROR (Status)) { +- FreePool (Packet); +- return Status; ++ goto ON_ERROR; + } + + // +@@ -1329,16 +1386,22 @@ Dhcp6SendDeclineMsg ( + Instance->StartTime = 0; + + Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); +- + if (EFI_ERROR (Status)) { +- FreePool (Packet); +- return Status; ++ goto ON_ERROR; + } + + // + // Enqueue the sent packet for the retransmission in case reply timeout. + // + return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); ++ ++ON_ERROR: ++ ++ if (Packet) { ++ FreePool (Packet); ++ } ++ ++ return Status; + } + + /** +@@ -1399,7 +1462,8 @@ Dhcp6SendReleaseMsg ( + // + Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE); + if (Packet == NULL) { +- return EFI_OUT_OF_RESOURCES; ++ Status = EFI_OUT_OF_RESOURCES; ++ goto ON_ERROR; + } + + Packet->Size = DHCP6_BASE_PACKET_SIZE; +@@ -1413,45 +1477,61 @@ Dhcp6SendReleaseMsg ( + Cursor = Packet->Dhcp6.Option; + + Length = HTONS (ClientId->Length); +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptClientId), + Length, + ClientId->Duid + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + + // + // ServerId is extracted from packet, it's network order. + // +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptServerId), + ServerId->Length, + ServerId->Duid + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendETOption ( +- Cursor, ++ Status = Dhcp6AppendETOption ( ++ Packet, ++ &Cursor, + Instance, + &Elapsed + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendIaOption (Cursor, RelIa, 0, 0, Packet->Dhcp6.Header.MessageType); ++ Status = Dhcp6AppendIaOption ( ++ Packet, ++ &Cursor, ++ RelIa, ++ 0, ++ 0, ++ Packet->Dhcp6.Header.MessageType ++ ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- // +- // Determine the size/length of packet +- // +- Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option); + ASSERT (Packet->Size > Packet->Length + 8); + + // + // Callback to user with the packet to be sent and check the user's feedback. + // + Status = Dhcp6CallbackUser (Instance, Dhcp6SendRelease, &Packet); +- + if (EFI_ERROR (Status)) { +- FreePool (Packet); +- return Status; ++ goto ON_ERROR; + } + + // +@@ -1461,16 +1541,22 @@ Dhcp6SendReleaseMsg ( + Instance->IaCb.Ia->State = Dhcp6Releasing; + + Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); +- + if (EFI_ERROR (Status)) { +- FreePool (Packet); +- return Status; ++ goto ON_ERROR; + } + + // + // Enqueue the sent packet for the retransmission in case reply timeout. + // + return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); ++ ++ON_ERROR: ++ ++ if (Packet) { ++ FreePool (Packet); ++ } ++ ++ return Status; + } + + /** +@@ -1529,7 +1615,8 @@ Dhcp6SendRenewRebindMsg ( + // + Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); + if (Packet == NULL) { +- return EFI_OUT_OF_RESOURCES; ++ Status = EFI_OUT_OF_RESOURCES; ++ goto ON_ERROR; + } + + Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen; +@@ -1543,26 +1630,38 @@ Dhcp6SendRenewRebindMsg ( + Cursor = Packet->Dhcp6.Option; + + Length = HTONS (ClientId->Length); +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptClientId), + Length, + ClientId->Duid + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendETOption ( +- Cursor, ++ Status = Dhcp6AppendETOption ( ++ Packet, ++ &Cursor, + Instance, + &Elapsed + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendIaOption ( +- Cursor, ++ Status = Dhcp6AppendIaOption ( ++ Packet, ++ &Cursor, + Instance->IaCb.Ia, + Instance->IaCb.T1, + Instance->IaCb.T2, + Packet->Dhcp6.Header.MessageType + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + + if (!RebindRequest) { + // +@@ -1578,18 +1677,22 @@ Dhcp6SendRenewRebindMsg ( + Dhcp6OptServerId + ); + if (Option == NULL) { +- FreePool (Packet); +- return EFI_DEVICE_ERROR; ++ Status = EFI_DEVICE_ERROR; ++ goto ON_ERROR; + } + + ServerId = (EFI_DHCP6_DUID *)(Option + 2); + +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptServerId), + ServerId->Length, + ServerId->Duid + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + } + + // +@@ -1597,18 +1700,18 @@ Dhcp6SendRenewRebindMsg ( + // + for (Index = 0; Index < Instance->Config->OptionCount; Index++) { + UserOpt = Instance->Config->OptionList[Index]; +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + UserOpt->OpCode, + UserOpt->OpLen, + UserOpt->Data + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + } + +- // +- // Determine the size/length of packet. +- // +- Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option); + ASSERT (Packet->Size > Packet->Length + 8); + + // +@@ -1618,10 +1721,8 @@ Dhcp6SendRenewRebindMsg ( + Event = (RebindRequest) ? Dhcp6EnterRebinding : Dhcp6EnterRenewing; + + Status = Dhcp6CallbackUser (Instance, Event, &Packet); +- + if (EFI_ERROR (Status)) { +- FreePool (Packet); +- return Status; ++ goto ON_ERROR; + } + + // +@@ -1638,16 +1739,22 @@ Dhcp6SendRenewRebindMsg ( + Instance->StartTime = 0; + + Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); +- + if (EFI_ERROR (Status)) { +- FreePool (Packet); +- return Status; ++ goto ON_ERROR; + } + + // + // Enqueue the sent packet for the retransmission in case reply timeout. + // + return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); ++ ++ON_ERROR: ++ ++ if (Packet) { ++ FreePool (Packet); ++ } ++ ++ return Status; + } + + /** +@@ -1811,7 +1918,8 @@ Dhcp6SendInfoRequestMsg ( + // + Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); + if (Packet == NULL) { +- return EFI_OUT_OF_RESOURCES; ++ Status = EFI_OUT_OF_RESOURCES; ++ goto ON_ERROR; + } + + Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen; +@@ -1828,44 +1936,56 @@ Dhcp6SendInfoRequestMsg ( + + if (SendClientId) { + Length = HTONS (ClientId->Length); +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptClientId), + Length, + ClientId->Duid + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + } + +- Cursor = Dhcp6AppendETOption ( +- Cursor, ++ Status = Dhcp6AppendETOption ( ++ Packet, ++ &Cursor, + Instance, + &Elapsed + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + OptionRequest->OpCode, + OptionRequest->OpLen, + OptionRequest->Data + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + + // + // Append user-defined when configurate Dhcp6 service. + // + for (Index = 0; Index < OptionCount; Index++) { + UserOpt = OptionList[Index]; +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + UserOpt->OpCode, + UserOpt->OpLen, + UserOpt->Data + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + } + +- // +- // Determine the size/length of packet. +- // +- Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option); + ASSERT (Packet->Size > Packet->Length + 8); + + // +@@ -1877,16 +1997,22 @@ Dhcp6SendInfoRequestMsg ( + // Send info-request packet with no state. + // + Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); +- + if (EFI_ERROR (Status)) { +- FreePool (Packet); +- return Status; ++ goto ON_ERROR; + } + + // + // Enqueue the sent packet for the retransmission in case reply timeout. + // + return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, Retransmission); ++ ++ON_ERROR: ++ ++ if (Packet) { ++ FreePool (Packet); ++ } ++ ++ return Status; + } + + /** +@@ -1937,7 +2063,8 @@ Dhcp6SendConfirmMsg ( + // + Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); + if (Packet == NULL) { +- return EFI_OUT_OF_RESOURCES; ++ Status = EFI_OUT_OF_RESOURCES; ++ goto ON_ERROR; + } + + Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen; +@@ -1951,54 +2078,64 @@ Dhcp6SendConfirmMsg ( + Cursor = Packet->Dhcp6.Option; + + Length = HTONS (ClientId->Length); +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + HTONS (Dhcp6OptClientId), + Length, + ClientId->Duid + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendETOption ( +- Cursor, ++ Status = Dhcp6AppendETOption ( ++ Packet, ++ &Cursor, + Instance, + &Elapsed + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + +- Cursor = Dhcp6AppendIaOption ( +- Cursor, ++ Status = Dhcp6AppendIaOption ( ++ Packet, ++ &Cursor, + Instance->IaCb.Ia, + Instance->IaCb.T1, + Instance->IaCb.T2, + Packet->Dhcp6.Header.MessageType + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + + // + // Append user-defined when configurate Dhcp6 service. + // + for (Index = 0; Index < Instance->Config->OptionCount; Index++) { + UserOpt = Instance->Config->OptionList[Index]; +- Cursor = Dhcp6AppendOption ( +- Cursor, ++ Status = Dhcp6AppendOption ( ++ Packet, ++ &Cursor, + UserOpt->OpCode, + UserOpt->OpLen, + UserOpt->Data + ); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } + } + +- // +- // Determine the size/length of packet. +- // +- Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option); + ASSERT (Packet->Size > Packet->Length + 8); + + // + // Callback to user with the packet to be sent and check the user's feedback. + // + Status = Dhcp6CallbackUser (Instance, Dhcp6SendConfirm, &Packet); +- + if (EFI_ERROR (Status)) { +- FreePool (Packet); +- return Status; ++ goto ON_ERROR; + } + + // +@@ -2012,16 +2149,22 @@ Dhcp6SendConfirmMsg ( + Instance->StartTime = 0; + + Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); +- + if (EFI_ERROR (Status)) { +- FreePool (Packet); +- return Status; ++ goto ON_ERROR; + } + + // + // Enqueue the sent packet for the retransmission in case reply timeout. + // + return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); ++ ++ON_ERROR: ++ ++ if (Packet) { ++ FreePool (Packet); ++ } ++ ++ return Status; + } + + /** +diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c +index e6368b5b1c6c..705c665c519d 100644 +--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c ++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c +@@ -577,24 +577,33 @@ Dhcp6OnTransmitted ( + } + + /** +- Append the option to Buf, and move Buf to the end. ++ Append the option to Buf, update the length of packet, and move Buf to the end. + +- @param[in, out] Buf The pointer to the buffer. +- @param[in] OptType The option type. +- @param[in] OptLen The length of option contents. +- @param[in] Data The pointer to the option content. ++ @param[in, out] Packet A pointer to the packet, on success Packet->Length ++ will be updated. ++ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor ++ will be moved to the end of the option. ++ @param[in] OptType The option type. ++ @param[in] OptLen The length of option contents. ++ @param[in] Data The pointer to the option content. + +- @return Buf The position to append the next option. ++ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid ++ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. ++ @retval EFI_SUCCESS The option is appended successfully. + + **/ +-UINT8 * ++EFI_STATUS + Dhcp6AppendOption ( +- IN OUT UINT8 *Buf, +- IN UINT16 OptType, +- IN UINT16 OptLen, +- IN UINT8 *Data ++ IN OUT EFI_DHCP6_PACKET *Packet, ++ IN OUT UINT8 **PacketCursor, ++ IN UINT16 OptType, ++ IN UINT16 OptLen, ++ IN UINT8 *Data + ) + { ++ UINT32 Length; ++ UINT32 BytesNeeded; ++ + // + // The format of Dhcp6 option: + // +@@ -607,35 +616,95 @@ Dhcp6AppendOption ( + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + +- ASSERT (OptLen != 0); ++ // ++ // Verify the arguments are valid ++ // ++ if (Packet == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if ((PacketCursor == NULL) || (*PacketCursor == NULL)) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if (Data == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if (OptLen == 0) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // Verify the PacketCursor is within the packet ++ // ++ if ( (*PacketCursor < Packet->Dhcp6.Option) ++ || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) ++ { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // Calculate the bytes needed for the option ++ // ++ BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN + NTOHS (OptLen); ++ ++ // ++ // Space remaining in the packet ++ // ++ Length = Packet->Size - Packet->Length; ++ if (Length < BytesNeeded) { ++ return EFI_BUFFER_TOO_SMALL; ++ } ++ ++ // ++ // Verify the PacketCursor is within the packet ++ // ++ if ( (*PacketCursor < Packet->Dhcp6.Option) ++ || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) ++ { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ WriteUnaligned16 ((UINT16 *)*PacketCursor, OptType); ++ *PacketCursor += DHCP6_SIZE_OF_OPT_CODE; ++ WriteUnaligned16 ((UINT16 *)*PacketCursor, OptLen); ++ *PacketCursor += DHCP6_SIZE_OF_OPT_LEN; ++ CopyMem (*PacketCursor, Data, NTOHS (OptLen)); ++ *PacketCursor += NTOHS (OptLen); + +- WriteUnaligned16 ((UINT16 *)Buf, OptType); +- Buf += 2; +- WriteUnaligned16 ((UINT16 *)Buf, OptLen); +- Buf += 2; +- CopyMem (Buf, Data, NTOHS (OptLen)); +- Buf += NTOHS (OptLen); ++ // Update the packet length by the length of the option + 4 bytes ++ Packet->Length += BytesNeeded; + +- return Buf; ++ return EFI_SUCCESS; + } + + /** + Append the appointed IA Address option to Buf, and move Buf to the end. + +- @param[in, out] Buf The pointer to the position to append. ++ @param[in, out] Packet A pointer to the packet, on success Packet->Length ++ will be updated. ++ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor ++ will be moved to the end of the option. + @param[in] IaAddr The pointer to the IA Address. + @param[in] MessageType Message type of DHCP6 package. + +- @return Buf The position to append the next option. ++ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid ++ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. ++ @retval EFI_SUCCESS The option is appended successfully. + + **/ +-UINT8 * ++EFI_STATUS + Dhcp6AppendIaAddrOption ( +- IN OUT UINT8 *Buf, ++ IN OUT EFI_DHCP6_PACKET *Packet, ++ IN OUT UINT8 **PacketCursor, + IN EFI_DHCP6_IA_ADDRESS *IaAddr, + IN UINT32 MessageType + ) + { ++ UINT32 BytesNeeded; ++ UINT32 Length; ++ + // The format of the IA Address option is: + // + // 0 1 2 3 +@@ -657,17 +726,60 @@ Dhcp6AppendIaAddrOption ( + // . . + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ++ // ++ // Verify the arguments are valid ++ // ++ if (Packet == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if ((PacketCursor == NULL) || (*PacketCursor == NULL)) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if (IaAddr == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // Verify the PacketCursor is within the packet ++ // ++ if ( (*PacketCursor < Packet->Dhcp6.Option) ++ || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) ++ { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN; ++ BytesNeeded += sizeof (EFI_IPv6_ADDRESS); ++ // ++ // Even if the preferred-lifetime is 0, it still needs to store it. ++ // ++ BytesNeeded += sizeof (IaAddr->PreferredLifetime); ++ // ++ // Even if the valid-lifetime is 0, it still needs to store it. ++ // ++ BytesNeeded += sizeof (IaAddr->ValidLifetime); ++ ++ // ++ // Space remaining in the packet ++ // ++ Length = Packet->Size - Packet->Length; ++ if (Length < BytesNeeded) { ++ return EFI_BUFFER_TOO_SMALL; ++ } ++ + // + // Fill the value of Ia Address option type + // +- WriteUnaligned16 ((UINT16 *)Buf, HTONS (Dhcp6OptIaAddr)); +- Buf += 2; ++ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Dhcp6OptIaAddr)); ++ *PacketCursor += DHCP6_SIZE_OF_OPT_CODE; + +- WriteUnaligned16 ((UINT16 *)Buf, HTONS (sizeof (EFI_DHCP6_IA_ADDRESS))); +- Buf += 2; ++ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (sizeof (EFI_DHCP6_IA_ADDRESS))); ++ *PacketCursor += DHCP6_SIZE_OF_OPT_LEN; + +- CopyMem (Buf, &IaAddr->IpAddress, sizeof (EFI_IPv6_ADDRESS)); +- Buf += sizeof (EFI_IPv6_ADDRESS); ++ CopyMem (*PacketCursor, &IaAddr->IpAddress, sizeof (EFI_IPv6_ADDRESS)); ++ *PacketCursor += sizeof (EFI_IPv6_ADDRESS); + + // + // Fill the value of preferred-lifetime and valid-lifetime. +@@ -675,44 +787,58 @@ Dhcp6AppendIaAddrOption ( + // should set to 0 when initiate a Confirm message. + // + if (MessageType != Dhcp6MsgConfirm) { +- WriteUnaligned32 ((UINT32 *)Buf, HTONL (IaAddr->PreferredLifetime)); ++ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (IaAddr->PreferredLifetime)); + } + +- Buf += 4; ++ *PacketCursor += sizeof (IaAddr->PreferredLifetime); + + if (MessageType != Dhcp6MsgConfirm) { +- WriteUnaligned32 ((UINT32 *)Buf, HTONL (IaAddr->ValidLifetime)); ++ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (IaAddr->ValidLifetime)); + } + +- Buf += 4; ++ *PacketCursor += sizeof (IaAddr->ValidLifetime); ++ ++ // ++ // Update the packet length ++ // ++ Packet->Length += BytesNeeded; + +- return Buf; ++ return EFI_SUCCESS; + } + + /** + Append the appointed Ia option to Buf, and move Buf to the end. + +- @param[in, out] Buf The pointer to the position to append. ++ @param[in, out] Packet A pointer to the packet, on success Packet->Length ++ will be updated. ++ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor ++ will be moved to the end of the option. + @param[in] Ia The pointer to the Ia. + @param[in] T1 The time of T1. + @param[in] T2 The time of T2. + @param[in] MessageType Message type of DHCP6 package. + +- @return Buf The position to append the next Ia option. ++ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid ++ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. ++ @retval EFI_SUCCESS The option is appended successfully. + + **/ +-UINT8 * ++EFI_STATUS + Dhcp6AppendIaOption ( +- IN OUT UINT8 *Buf, +- IN EFI_DHCP6_IA *Ia, +- IN UINT32 T1, +- IN UINT32 T2, +- IN UINT32 MessageType ++ IN OUT EFI_DHCP6_PACKET *Packet, ++ IN OUT UINT8 **PacketCursor, ++ IN EFI_DHCP6_IA *Ia, ++ IN UINT32 T1, ++ IN UINT32 T2, ++ IN UINT32 MessageType + ) + { +- UINT8 *AddrOpt; +- UINT16 *Len; +- UINTN Index; ++ UINT8 *AddrOpt; ++ UINT16 *Len; ++ UINTN Index; ++ UINT32 BytesNeeded; ++ UINT32 Length; ++ EFI_STATUS Status; + + // + // The format of IA_NA and IA_TA option: +@@ -733,32 +859,74 @@ Dhcp6AppendIaOption ( + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + ++ // ++ // Verify the arguments are valid ++ // ++ if (Packet == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if ((PacketCursor == NULL) || (*PacketCursor == NULL)) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if (Ia == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // Verify the PacketCursor is within the packet ++ // ++ if ( (*PacketCursor < Packet->Dhcp6.Option) ++ || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) ++ { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN; ++ BytesNeeded += sizeof (Ia->Descriptor.IaId); ++ // ++ // + N for the IA_NA-options/IA_TA-options ++ // Dhcp6AppendIaAddrOption will need to check the length for each address ++ // ++ if (Ia->Descriptor.Type == Dhcp6OptIana) { ++ BytesNeeded += sizeof (T1) + sizeof (T2); ++ } ++ ++ // ++ // Space remaining in the packet ++ // ++ Length = (UINT16)(Packet->Size - Packet->Length); ++ if (Length < BytesNeeded) { ++ return EFI_BUFFER_TOO_SMALL; ++ } ++ + // + // Fill the value of Ia option type + // +- WriteUnaligned16 ((UINT16 *)Buf, HTONS (Ia->Descriptor.Type)); +- Buf += 2; ++ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Ia->Descriptor.Type)); ++ *PacketCursor += DHCP6_SIZE_OF_OPT_CODE; + + // + // Fill the len of Ia option later, keep the pointer first + // +- Len = (UINT16 *)Buf; +- Buf += 2; ++ Len = (UINT16 *)*PacketCursor; ++ *PacketCursor += DHCP6_SIZE_OF_OPT_LEN; + + // + // Fill the value of iaid + // +- WriteUnaligned32 ((UINT32 *)Buf, HTONL (Ia->Descriptor.IaId)); +- Buf += 4; ++ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (Ia->Descriptor.IaId)); ++ *PacketCursor += sizeof (Ia->Descriptor.IaId); + + // + // Fill the value of t1 and t2 if iana, keep it 0xffffffff if no specified. + // + if (Ia->Descriptor.Type == Dhcp6OptIana) { +- WriteUnaligned32 ((UINT32 *)Buf, HTONL ((T1 != 0) ? T1 : 0xffffffff)); +- Buf += 4; +- WriteUnaligned32 ((UINT32 *)Buf, HTONL ((T2 != 0) ? T2 : 0xffffffff)); +- Buf += 4; ++ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL ((T1 != 0) ? T1 : 0xffffffff)); ++ *PacketCursor += sizeof (T1); ++ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL ((T2 != 0) ? T2 : 0xffffffff)); ++ *PacketCursor += sizeof (T2); + } + + // +@@ -766,35 +934,51 @@ Dhcp6AppendIaOption ( + // + for (Index = 0; Index < Ia->IaAddressCount; Index++) { + AddrOpt = (UINT8 *)Ia->IaAddress + Index * sizeof (EFI_DHCP6_IA_ADDRESS); +- Buf = Dhcp6AppendIaAddrOption (Buf, (EFI_DHCP6_IA_ADDRESS *)AddrOpt, MessageType); ++ Status = Dhcp6AppendIaAddrOption (Packet, PacketCursor, (EFI_DHCP6_IA_ADDRESS *)AddrOpt, MessageType); ++ if (EFI_ERROR (Status)) { ++ return Status; ++ } + } + + // + // Fill the value of Ia option length + // +- *Len = HTONS ((UINT16)(Buf - (UINT8 *)Len - 2)); ++ *Len = HTONS ((UINT16)(*PacketCursor - (UINT8 *)Len - 2)); + +- return Buf; ++ // ++ // Update the packet length ++ // ++ Packet->Length += BytesNeeded; ++ ++ return EFI_SUCCESS; + } + + /** + Append the appointed Elapsed time option to Buf, and move Buf to the end. + +- @param[in, out] Buf The pointer to the position to append. ++ @param[in, out] Packet A pointer to the packet, on success Packet->Length ++ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor ++ will be moved to the end of the option. + @param[in] Instance The pointer to the Dhcp6 instance. + @param[out] Elapsed The pointer to the elapsed time value in +- the generated packet. ++ the generated packet. + +- @return Buf The position to append the next Ia option. ++ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid ++ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. ++ @retval EFI_SUCCESS The option is appended successfully. + + **/ +-UINT8 * ++EFI_STATUS + Dhcp6AppendETOption ( +- IN OUT UINT8 *Buf, +- IN DHCP6_INSTANCE *Instance, +- OUT UINT16 **Elapsed ++ IN OUT EFI_DHCP6_PACKET *Packet, ++ IN OUT UINT8 **PacketCursor, ++ IN DHCP6_INSTANCE *Instance, ++ OUT UINT16 **Elapsed + ) + { ++ UINT32 BytesNeeded; ++ UINT32 Length; ++ + // + // The format of elapsed time option: + // +@@ -806,27 +990,70 @@ Dhcp6AppendETOption ( + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + ++ // ++ // Verify the arguments are valid ++ // ++ if (Packet == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if ((PacketCursor == NULL) || (*PacketCursor == NULL)) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if (Instance == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ if ((Elapsed == NULL)) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // Verify the PacketCursor is within the packet ++ // ++ if ( (*PacketCursor < Packet->Dhcp6.Option) ++ || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) ++ { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN; ++ // ++ // + 2 for elapsed-time ++ // ++ BytesNeeded += sizeof (UINT16); ++ // ++ // Space remaining in the packet ++ // ++ Length = Packet->Size - Packet->Length; ++ if (Length < BytesNeeded) { ++ return EFI_BUFFER_TOO_SMALL; ++ } ++ + // + // Fill the value of elapsed-time option type. + // +- WriteUnaligned16 ((UINT16 *)Buf, HTONS (Dhcp6OptElapsedTime)); +- Buf += 2; ++ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Dhcp6OptElapsedTime)); ++ *PacketCursor += DHCP6_SIZE_OF_OPT_CODE; + + // + // Fill the len of elapsed-time option, which is fixed. + // +- WriteUnaligned16 ((UINT16 *)Buf, HTONS (2)); +- Buf += 2; ++ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (2)); ++ *PacketCursor += DHCP6_SIZE_OF_OPT_LEN; + + // + // Fill in elapsed time value with 0 value for now. The actual value is + // filled in later just before the packet is transmitted. + // +- WriteUnaligned16 ((UINT16 *)Buf, HTONS (0)); +- *Elapsed = (UINT16 *)Buf; +- Buf += 2; ++ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (0)); ++ *Elapsed = (UINT16 *)*PacketCursor; ++ *PacketCursor += sizeof (UINT16); + +- return Buf; ++ Packet->Length += BytesNeeded; ++ ++ return EFI_SUCCESS; + } + + /** +diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h +index 046454ff4ac2..06947f6c1fcf 100644 +--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h ++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h +@@ -160,69 +160,85 @@ Dhcp6OnTransmitted ( + ); + + /** +- Append the appointed option to the buf, and move the buf to the end. +- +- @param[in, out] Buf The pointer to buffer. +- @param[in] OptType The option type. +- @param[in] OptLen The length of option content.s +- @param[in] Data The pointer to the option content. +- +- @return Buf The position to append the next option. +- ++ Append the option to Buf, update the length of packet, and move Buf to the end. ++ ++ @param[in, out] Packet A pointer to the packet, on success Packet->Length ++ will be updated. ++ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor ++ will be moved to the end of the option. ++ @param[in] OptType The option type. ++ @param[in] OptLen The length of option contents. ++ @param[in] Data The pointer to the option content. ++ ++ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid ++ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. ++ @retval EFI_SUCCESS The option is appended successfully. + **/ +-UINT8 * ++EFI_STATUS + Dhcp6AppendOption ( +- IN OUT UINT8 *Buf, +- IN UINT16 OptType, +- IN UINT16 OptLen, +- IN UINT8 *Data ++ IN OUT EFI_DHCP6_PACKET *Packet, ++ IN OUT UINT8 **PacketCursor, ++ IN UINT16 OptType, ++ IN UINT16 OptLen, ++ IN UINT8 *Data + ); + + /** +- Append the Ia option to Buf, and move Buf to the end. +- +- @param[in, out] Buf The pointer to the position to append. ++ Append the appointed Ia option to Buf, update the Ia option length, and move Buf ++ to the end of the option. ++ @param[in, out] Packet A pointer to the packet, on success Packet->Length ++ will be updated. ++ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor ++ will be moved to the end of the option. + @param[in] Ia The pointer to the Ia. + @param[in] T1 The time of T1. + @param[in] T2 The time of T2. + @param[in] MessageType Message type of DHCP6 package. + +- @return Buf The position to append the next Ia option. +- ++ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid ++ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. ++ @retval EFI_SUCCESS The option is appended successfully. + **/ +-UINT8 * ++EFI_STATUS + Dhcp6AppendIaOption ( +- IN OUT UINT8 *Buf, +- IN EFI_DHCP6_IA *Ia, +- IN UINT32 T1, +- IN UINT32 T2, +- IN UINT32 MessageType ++ IN OUT EFI_DHCP6_PACKET *Packet, ++ IN OUT UINT8 **PacketCursor, ++ IN EFI_DHCP6_IA *Ia, ++ IN UINT32 T1, ++ IN UINT32 T2, ++ IN UINT32 MessageType + ); + + /** + Append the appointed Elapsed time option to Buf, and move Buf to the end. + +- @param[in, out] Buf The pointer to the position to append. ++ @param[in, out] Packet A pointer to the packet, on success Packet->Length ++ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor ++ will be moved to the end of the option. + @param[in] Instance The pointer to the Dhcp6 instance. + @param[out] Elapsed The pointer to the elapsed time value in + the generated packet. + +- @return Buf The position to append the next Ia option. ++ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid ++ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. ++ @retval EFI_SUCCESS The option is appended successfully. + + **/ +-UINT8 * ++EFI_STATUS + Dhcp6AppendETOption ( +- IN OUT UINT8 *Buf, +- IN DHCP6_INSTANCE *Instance, +- OUT UINT16 **Elapsed ++ IN OUT EFI_DHCP6_PACKET *Packet, ++ IN OUT UINT8 **PacketCursor, ++ IN DHCP6_INSTANCE *Instance, ++ OUT UINT16 **Elapsed + ); + + /** + Set the elapsed time based on the given instance and the pointer to the + elapsed time option. + +- @param[in] Elapsed The pointer to the position to append. +- @param[in] Instance The pointer to the Dhcp6 instance. ++ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid ++ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. ++ @retval EFI_SUCCESS The option is appended successfully. + **/ + VOID + SetElapsedTime ( diff --git a/SPECS/edk2/CVE-2023-45232.patch b/SPECS/edk2/CVE-2023-45232.patch new file mode 100644 index 00000000000..b68cacc1d3c --- /dev/null +++ b/SPECS/edk2/CVE-2023-45232.patch @@ -0,0 +1,351 @@ +From 4df0229ef992d4f2721a8508787ebf9dc81fbd6e Mon Sep 17 00:00:00 2001 +From: Doug Flick +Date: Fri, 26 Jan 2024 05:54:50 +0800 +Subject: [PATCH] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45232 Patch + +REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4537 +REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4538 + +Bug Details: +PixieFail Bug #4 +CVE-2023-45232 +CVSS 7.5 : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H +CWE-835 Loop with Unreachable Exit Condition ('Infinite Loop') + +Infinite loop when parsing unknown options in the Destination Options +header + +PixieFail Bug #5 +CVE-2023-45233 +CVSS 7.5 : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H +CWE-835 Loop with Unreachable Exit Condition ('Infinite Loop') + +Infinite loop when parsing a PadN option in the Destination Options +header + +Change Overview: + +Most importantly this change corrects the following incorrect math +and cleans up the code. + +> // It is a PadN option +> // +> - Offset = (UINT8)(Offset + *(Option + Offset + 1) + 2); +> + OptDataLen = ((EFI_IP6_OPTION *)(Option + Offset))->Length; +> + Offset = IP6_NEXT_OPTION_OFFSET (Offset, OptDataLen); + +> case Ip6OptionSkip: +> - Offset = (UINT8)(Offset + *(Option + Offset + 1)); +> OptDataLen = ((EFI_IP6_OPTION *)(Option + Offset))->Length; +> Offset = IP6_NEXT_OPTION_OFFSET (Offset, OptDataLen); + +Additionally, this change also corrects incorrect math where the calling +function was calculating the HDR EXT optionLen as a uint8 instead of a +uint16 + +> - OptionLen = (UINT8)((*Option + 1) * 8 - 2); +> + OptionLen = IP6_HDR_EXT_LEN (*Option) - +IP6_COMBINED_SIZE_OF_NEXT_HDR_AND_LEN; + +Additionally this check adds additional logic to santize the incoming +data + +Cc: Saloni Kasbekar +Cc: Zachary Clark-williams + +Signed-off-by: Doug Flick [MSFT] +Reviewed-by: Saloni Kasbekar +--- + NetworkPkg/Ip6Dxe/Ip6Nd.h | 35 ++++++++++++++++ + NetworkPkg/Ip6Dxe/Ip6Option.c | 76 ++++++++++++++++++++++++++++++----- + NetworkPkg/Ip6Dxe/Ip6Option.h | 71 ++++++++++++++++++++++++++++++++ + 3 files changed, 171 insertions(+), 11 deletions(-) + +diff --git a/NetworkPkg/Ip6Dxe/Ip6Nd.h b/NetworkPkg/Ip6Dxe/Ip6Nd.h +index 860934a167eb..bf64e9114e13 100644 +--- a/NetworkPkg/Ip6Dxe/Ip6Nd.h ++++ b/NetworkPkg/Ip6Dxe/Ip6Nd.h +@@ -56,13 +56,48 @@ VOID + VOID *Context + ); + ++// ++// Per RFC8200 Section 4.2 ++// ++// Two of the currently-defined extension headers -- the Hop-by-Hop ++// Options header and the Destination Options header -- carry a variable ++// number of type-length-value (TLV) encoded "options", of the following ++// format: ++// ++// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - - ++// | Option Type | Opt Data Len | Option Data ++// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - - ++// ++// Option Type 8-bit identifier of the type of option. ++// ++// Opt Data Len 8-bit unsigned integer. Length of the Option ++// Data field of this option, in octets. ++// ++// Option Data Variable-length field. Option-Type-specific ++// data. ++// + typedef struct _IP6_OPTION_HEADER { ++ /// ++ /// identifier of the type of option. ++ /// + UINT8 Type; ++ /// ++ /// Length of the Option Data field of this option, in octets. ++ /// + UINT8 Length; ++ /// ++ /// Option-Type-specific data. ++ /// + } IP6_OPTION_HEADER; + + STATIC_ASSERT (sizeof (IP6_OPTION_HEADER) == 2, "IP6_OPTION_HEADER is expected to be exactly 2 bytes long."); + ++#define IP6_NEXT_OPTION_OFFSET(offset, length) (offset + sizeof(IP6_OPTION_HEADER) + length) ++STATIC_ASSERT ( ++ IP6_NEXT_OPTION_OFFSET (0, 0) == 2, ++ "The next option is minimally the combined size of the option tag and length" ++ ); ++ + typedef struct _IP6_ETHE_ADDR_OPTION { + UINT8 Type; + UINT8 Length; +diff --git a/NetworkPkg/Ip6Dxe/Ip6Option.c b/NetworkPkg/Ip6Dxe/Ip6Option.c +index 8718d5d8756a..fd97ce116f98 100644 +--- a/NetworkPkg/Ip6Dxe/Ip6Option.c ++++ b/NetworkPkg/Ip6Dxe/Ip6Option.c +@@ -17,7 +17,8 @@ + @param[in] IpSb The IP6 service data. + @param[in] Packet The to be validated packet. + @param[in] Option The first byte of the option. +- @param[in] OptionLen The length of the whole option. ++ @param[in] OptionLen The length of all options, expressed in byte length of octets. ++ Maximum length is 2046 bytes or ((n + 1) * 8) - 2 where n is 255. + @param[in] Pointer Identifies the octet offset within + the invoking packet where the error was detected. + +@@ -31,12 +32,33 @@ Ip6IsOptionValid ( + IN IP6_SERVICE *IpSb, + IN NET_BUF *Packet, + IN UINT8 *Option, +- IN UINT8 OptionLen, ++ IN UINT16 OptionLen, + IN UINT32 Pointer + ) + { +- UINT8 Offset; +- UINT8 OptionType; ++ UINT16 Offset; ++ UINT8 OptionType; ++ UINT8 OptDataLen; ++ ++ if (Option == NULL) { ++ ASSERT (Option != NULL); ++ return FALSE; ++ } ++ ++ if ((OptionLen <= 0) || (OptionLen > IP6_MAX_EXT_DATA_LENGTH)) { ++ ASSERT (OptionLen > 0 && OptionLen <= IP6_MAX_EXT_DATA_LENGTH); ++ return FALSE; ++ } ++ ++ if (Packet == NULL) { ++ ASSERT (Packet != NULL); ++ return FALSE; ++ } ++ ++ if (IpSb == NULL) { ++ ASSERT (IpSb != NULL); ++ return FALSE; ++ } + + Offset = 0; + +@@ -54,7 +76,8 @@ Ip6IsOptionValid ( + // + // It is a PadN option + // +- Offset = (UINT8)(Offset + *(Option + Offset + 1) + 2); ++ OptDataLen = ((IP6_OPTION_HEADER *)(Option + Offset))->Length; ++ Offset = IP6_NEXT_OPTION_OFFSET (Offset, OptDataLen); + break; + case Ip6OptionRouterAlert: + // +@@ -69,7 +92,8 @@ Ip6IsOptionValid ( + // + switch (OptionType & Ip6OptionMask) { + case Ip6OptionSkip: +- Offset = (UINT8)(Offset + *(Option + Offset + 1)); ++ OptDataLen = ((IP6_OPTION_HEADER *)(Option + Offset))->Length; ++ Offset = IP6_NEXT_OPTION_OFFSET (Offset, OptDataLen); + break; + case Ip6OptionDiscard: + return FALSE; +@@ -308,7 +332,7 @@ Ip6IsExtsValid ( + UINT32 Pointer; + UINT32 Offset; + UINT8 *Option; +- UINT8 OptionLen; ++ UINT16 OptionLen; + BOOLEAN Flag; + UINT8 CountD; + UINT8 CountA; +@@ -385,6 +409,36 @@ Ip6IsExtsValid ( + // Fall through + // + case IP6_DESTINATION: ++ // ++ // See https://www.rfc-editor.org/rfc/rfc2460#section-4.2 page 23 ++ // ++ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ++ // | Next Header | Hdr Ext Len | | ++ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ++ // | | ++ // . . ++ // . Options . ++ // . . ++ // | | ++ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ++ // ++ // ++ // Next Header 8-bit selector. Identifies the type of header ++ // immediately following the Destination Options ++ // header. Uses the same values as the IPv4 ++ // Protocol field [RFC-1700 et seq.]. ++ // ++ // Hdr Ext Len 8-bit unsigned integer. Length of the ++ // Destination Options header in 8-octet units, not ++ // including the first 8 octets. ++ // ++ // Options Variable-length field, of length such that the ++ // complete Destination Options header is an ++ // integer multiple of 8 octets long. Contains one ++ // or more TLV-encoded options, as described in ++ // section 4.2. ++ // ++ + if (*NextHeader == IP6_DESTINATION) { + CountD++; + } +@@ -398,7 +452,7 @@ Ip6IsExtsValid ( + + Offset++; + Option = ExtHdrs + Offset; +- OptionLen = (UINT8)((*Option + 1) * 8 - 2); ++ OptionLen = IP6_HDR_EXT_LEN (*Option) - sizeof (IP6_EXT_HDR); + Option++; + Offset++; + +@@ -430,7 +484,7 @@ Ip6IsExtsValid ( + // + // Ignore the routing header and proceed to process the next header. + // +- Offset = Offset + (RoutingHead->HeaderLen + 1) * 8; ++ Offset = Offset + IP6_HDR_EXT_LEN (RoutingHead->HeaderLen); + + if (UnFragmentLen != NULL) { + *UnFragmentLen = Offset; +@@ -441,7 +495,7 @@ Ip6IsExtsValid ( + // to the packet's source address, pointing to the unrecognized routing + // type. + // +- Pointer = Offset + 2 + sizeof (EFI_IP6_HEADER); ++ Pointer = Offset + sizeof (IP6_EXT_HDR) + sizeof (EFI_IP6_HEADER); + if ((IpSb != NULL) && (Packet != NULL) && + !IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress)) + { +@@ -527,7 +581,7 @@ Ip6IsExtsValid ( + // + // RFC2402, Payload length is specified in 32-bit words, minus "2". + // +- OptionLen = (UINT8)((*Option + 2) * 4); ++ OptionLen = ((UINT16)(*Option + 2) * 4); + Offset = Offset + OptionLen; + break; + +diff --git a/NetworkPkg/Ip6Dxe/Ip6Option.h b/NetworkPkg/Ip6Dxe/Ip6Option.h +index bd8e223c8a67..fb07c28f5ad7 100644 +--- a/NetworkPkg/Ip6Dxe/Ip6Option.h ++++ b/NetworkPkg/Ip6Dxe/Ip6Option.h +@@ -12,6 +12,77 @@ + + #define IP6_FRAGMENT_OFFSET_MASK (~0x3) + ++// ++// For more information see RFC 8200, Section 4.3, 4.4, and 4.6 ++// ++// This example format is from section 4.6 ++// This does not apply to fragment headers ++// ++// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ++// | Next Header | Hdr Ext Len | | ++// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ++// | | ++// . . ++// . Header-Specific Data . ++// . . ++// | | ++// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ++// ++// Next Header 8-bit selector. Identifies the type of ++// header immediately following the extension ++// header. Uses the same values as the IPv4 ++// Protocol field [IANA-PN]. ++// ++// Hdr Ext Len 8-bit unsigned integer. Length of the ++// Destination Options header in 8-octet units, ++// not including the first 8 octets. ++ ++// ++// These defines apply to the following: ++// 1. Hop by Hop ++// 2. Routing ++// 3. Destination ++// ++typedef struct _IP6_EXT_HDR { ++ /// ++ /// The Next Header field identifies the type of header immediately ++ /// ++ UINT8 NextHeader; ++ /// ++ /// The Hdr Ext Len field specifies the length of the Hop-by-Hop Options ++ /// ++ UINT8 HdrExtLen; ++ /// ++ /// Header-Specific Data ++ /// ++} IP6_EXT_HDR; ++ ++STATIC_ASSERT ( ++ sizeof (IP6_EXT_HDR) == 2, ++ "The combined size of Next Header and Len is two 8 bit fields" ++ ); ++ ++// ++// IPv6 extension headers contain an 8-bit length field which describes the size of ++// the header. However, the length field only includes the size of the extension ++// header options, not the size of the first 8 bytes of the header. Therefore, in ++// order to calculate the full size of the extension header, we add 1 (to account ++// for the first 8 bytes omitted by the length field reporting) and then multiply ++// by 8 (since the size is represented in 8-byte units). ++// ++// a is the length field of the extension header (UINT8) ++// The result may be up to 2046 octets (UINT16) ++// ++#define IP6_HDR_EXT_LEN(a) (((UINT16)((UINT8)(a)) + 1) * 8) ++ ++// This is the maxmimum length permissible by a extension header ++// Length is UINT8 of 8 octets not including the first 8 octets ++#define IP6_MAX_EXT_DATA_LENGTH (IP6_HDR_EXT_LEN (MAX_UINT8) - sizeof(IP6_EXT_HDR)) ++STATIC_ASSERT ( ++ IP6_MAX_EXT_DATA_LENGTH == 2046, ++ "Maximum data length is ((MAX_UINT8 + 1) * 8) - 2" ++ ); ++ + typedef struct _IP6_FRAGMENT_HEADER { + UINT8 NextHeader; + UINT8 Reserved; diff --git a/SPECS/edk2/CVE-2023-45233.nopatch b/SPECS/edk2/CVE-2023-45233.nopatch new file mode 100644 index 00000000000..49e1720e9c2 --- /dev/null +++ b/SPECS/edk2/CVE-2023-45233.nopatch @@ -0,0 +1,2 @@ +CVE already patch in CVE-2023-45232.patch +Ref: https://github.com/tianocore/edk2/commit/4df0229ef992d4f2721a8508787ebf9dc81fbd6e \ No newline at end of file diff --git a/SPECS/edk2/CVE-2023-45234.patch b/SPECS/edk2/CVE-2023-45234.patch new file mode 100644 index 00000000000..6f09437f6de --- /dev/null +++ b/SPECS/edk2/CVE-2023-45234.patch @@ -0,0 +1,145 @@ +From 1b53515d53d303166b2bbd31e2cc7f16fd0aecd7 Mon Sep 17 00:00:00 2001 +From: Doug Flick +Date: Fri, 26 Jan 2024 05:54:52 +0800 +Subject: [PATCH] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45234 Patch + +REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4539 + +Bug Details: +PixieFail Bug #6 +CVE-2023-45234 +CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H +CWE-119 Improper Restriction of Operations within the Bounds of + a Memory Buffer + +Buffer overflow when processing DNS Servers option in a DHCPv6 +Advertise message + +Change Overview: + +Introduces a function to cache the Dns Server and perform sanitizing +on the incoming DnsServerLen to ensure that the length is valid + +> + EFI_STATUS +> + PxeBcCacheDnsServerAddresses ( +> + IN PXEBC_PRIVATE_DATA *Private, +> + IN PXEBC_DHCP6_PACKET_CACHE *Cache6 +> + ) + +Additional code cleanup + +Cc: Saloni Kasbekar +Cc: Zachary Clark-williams + +Signed-off-by: Doug Flick [MSFT] +Reviewed-by: Saloni Kasbekar +--- + NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c | 71 +++++++++++++++++++++++++--- + 1 file changed, 65 insertions(+), 6 deletions(-) + +diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c +index 425e0cf8061d..2b2d372889a3 100644 +--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c ++++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c +@@ -3,6 +3,7 @@ + + (C) Copyright 2014 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
++ Copyright (c) Microsoft Corporation + + SPDX-License-Identifier: BSD-2-Clause-Patent + +@@ -1312,6 +1313,65 @@ PxeBcSelectDhcp6Offer ( + } + } + ++/** ++ Cache the DHCPv6 DNS Server addresses ++ ++ @param[in] Private The pointer to PXEBC_PRIVATE_DATA. ++ @param[in] Cache6 The pointer to PXEBC_DHCP6_PACKET_CACHE. ++ ++ @retval EFI_SUCCESS Cache the DHCPv6 DNS Server address successfully. ++ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. ++ @retval EFI_DEVICE_ERROR The DNS Server Address Length provided by a untrusted ++ option is not a multiple of 16 bytes (sizeof (EFI_IPv6_ADDRESS)). ++**/ ++EFI_STATUS ++PxeBcCacheDnsServerAddresses ( ++ IN PXEBC_PRIVATE_DATA *Private, ++ IN PXEBC_DHCP6_PACKET_CACHE *Cache6 ++ ) ++{ ++ UINT16 DnsServerLen; ++ ++ DnsServerLen = NTOHS (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen); ++ // ++ // Make sure that the number is nonzero ++ // ++ if (DnsServerLen == 0) { ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // ++ // Make sure the DnsServerlen is a multiple of EFI_IPv6_ADDRESS (16) ++ // ++ if (DnsServerLen % sizeof (EFI_IPv6_ADDRESS) != 0) { ++ return EFI_DEVICE_ERROR; ++ } ++ ++ // ++ // This code is currently written to only support a single DNS Server instead ++ // of multiple such as is spec defined (RFC3646, Section 3). The proper behavior ++ // would be to allocate the full space requested, CopyMem all of the data, ++ // and then add a DnsServerCount field to Private and update additional code ++ // that depends on this. ++ // ++ // To support multiple DNS servers the `AllocationSize` would need to be changed to DnsServerLen ++ // ++ // This is tracked in https://bugzilla.tianocore.org/show_bug.cgi?id=1886 ++ // ++ Private->DnsServer = AllocateZeroPool (sizeof (EFI_IPv6_ADDRESS)); ++ if (Private->DnsServer == NULL) { ++ return EFI_OUT_OF_RESOURCES; ++ } ++ ++ // ++ // Intentionally only copy over the first server address. ++ // To support multiple DNS servers, the `Length` would need to be changed to DnsServerLen ++ // ++ CopyMem (Private->DnsServer, Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->Data, sizeof (EFI_IPv6_ADDRESS)); ++ ++ return EFI_SUCCESS; ++} ++ + /** + Handle the DHCPv6 offer packet. + +@@ -1335,6 +1395,7 @@ PxeBcHandleDhcp6Offer ( + UINT32 SelectIndex; + UINT32 Index; + ++ ASSERT (Private != NULL); + ASSERT (Private->SelectIndex > 0); + SelectIndex = (UINT32)(Private->SelectIndex - 1); + ASSERT (SelectIndex < PXEBC_OFFER_MAX_NUM); +@@ -1342,15 +1403,13 @@ PxeBcHandleDhcp6Offer ( + Status = EFI_SUCCESS; + + // +- // First try to cache DNS server address if DHCP6 offer provides. ++ // First try to cache DNS server addresses if DHCP6 offer provides. + // + if (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] != NULL) { +- Private->DnsServer = AllocateZeroPool (NTOHS (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen)); +- if (Private->DnsServer == NULL) { +- return EFI_OUT_OF_RESOURCES; ++ Status = PxeBcCacheDnsServerAddresses (Private, Cache6); ++ if (EFI_ERROR (Status)) { ++ return Status; + } +- +- CopyMem (Private->DnsServer, Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->Data, sizeof (EFI_IPv6_ADDRESS)); + } + + if (Cache6->OfferType == PxeOfferTypeDhcpBinl) { diff --git a/SPECS/edk2/CVE-2023-45235.patch b/SPECS/edk2/CVE-2023-45235.patch new file mode 100644 index 00000000000..16a33eb1b17 --- /dev/null +++ b/SPECS/edk2/CVE-2023-45235.patch @@ -0,0 +1,234 @@ +From fac297724e6cc343430cd0104e55cd7a96d1151e Mon Sep 17 00:00:00 2001 +From: Doug Flick +Date: Fri, 26 Jan 2024 05:54:55 +0800 +Subject: [PATCH] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45235 Patch + +REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4540 + +Bug Details: +PixieFail Bug #7 +CVE-2023-45235 +CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H +CWE-119 Improper Restriction of Operations within the Bounds of + a Memory Buffer + +Buffer overflow when handling Server ID option from a DHCPv6 proxy +Advertise message + +Change Overview: + +Performs two checks + +1. Checks that the length of the duid is accurate +> + // +> + // Check that the minimum and maximum requirements are met +> + // +> + if ((OpLen < PXEBC_MIN_SIZE_OF_DUID) || +(OpLen > PXEBC_MAX_SIZE_OF_DUID)) { +> + Status = EFI_INVALID_PARAMETER; +> + goto ON_ERROR; +> + } + +2. Ensures that the amount of data written to the buffer is tracked and +never exceeds that +> + // +> + // Check that the option length is valid. +> + // +> + if ((DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN) + > DiscoverLenNeeded) { +> + Status = EFI_OUT_OF_RESOURCES; +> + goto ON_ERROR; +> + } + +Additional code clean up and fix for memory leak in case Option was NULL + +Cc: Saloni Kasbekar +Cc: Zachary Clark-williams + +Signed-off-by: Doug Flick [MSFT] +Reviewed-by: Saloni Kasbekar +--- + NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c | 77 ++++++++++++++++++++++------ + NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h | 17 ++++++ + 2 files changed, 78 insertions(+), 16 deletions(-) + +diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c +index 2b2d372889a3..7fd1281c1184 100644 +--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c ++++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c +@@ -887,6 +887,7 @@ PxeBcRequestBootService ( + EFI_STATUS Status; + EFI_DHCP6_PACKET *IndexOffer; + UINT8 *Option; ++ UINTN DiscoverLenNeeded; + + PxeBc = &Private->PxeBc; + Request = Private->Dhcp6Request; +@@ -899,7 +900,8 @@ PxeBcRequestBootService ( + return EFI_DEVICE_ERROR; + } + +- Discover = AllocateZeroPool (sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET)); ++ DiscoverLenNeeded = sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET); ++ Discover = AllocateZeroPool (DiscoverLenNeeded); + if (Discover == NULL) { + return EFI_OUT_OF_RESOURCES; + } +@@ -924,16 +926,34 @@ PxeBcRequestBootService ( + DHCP6_OPT_SERVER_ID + ); + if (Option == NULL) { +- return EFI_NOT_FOUND; ++ Status = EFI_NOT_FOUND; ++ goto ON_ERROR; + } + + // + // Add Server ID Option. + // + OpLen = NTOHS (((EFI_DHCP6_PACKET_OPTION *)Option)->OpLen); +- CopyMem (DiscoverOpt, Option, OpLen + 4); +- DiscoverOpt += (OpLen + 4); +- DiscoverLen += (OpLen + 4); ++ ++ // ++ // Check that the minimum and maximum requirements are met ++ // ++ if ((OpLen < PXEBC_MIN_SIZE_OF_DUID) || (OpLen > PXEBC_MAX_SIZE_OF_DUID)) { ++ Status = EFI_INVALID_PARAMETER; ++ goto ON_ERROR; ++ } ++ ++ // ++ // Check that the option length is valid. ++ // ++ if ((DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN) > DiscoverLenNeeded) { ++ Status = EFI_OUT_OF_RESOURCES; ++ goto ON_ERROR; ++ } ++ ++ CopyMem (DiscoverOpt, Option, OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); ++ DiscoverOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); ++ DiscoverLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); + } + + while (RequestLen < Request->Length) { +@@ -944,16 +964,24 @@ PxeBcRequestBootService ( + (OpCode != DHCP6_OPT_SERVER_ID) + ) + { ++ // ++ // Check that the option length is valid. ++ // ++ if (DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN > DiscoverLenNeeded) { ++ Status = EFI_OUT_OF_RESOURCES; ++ goto ON_ERROR; ++ } ++ + // + // Copy all the options except IA option and Server ID + // +- CopyMem (DiscoverOpt, RequestOpt, OpLen + 4); +- DiscoverOpt += (OpLen + 4); +- DiscoverLen += (OpLen + 4); ++ CopyMem (DiscoverOpt, RequestOpt, OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); ++ DiscoverOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); ++ DiscoverLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); + } + +- RequestOpt += (OpLen + 4); +- RequestLen += (OpLen + 4); ++ RequestOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); ++ RequestLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); + } + + // +@@ -2154,6 +2182,7 @@ PxeBcDhcp6Discover ( + UINT16 OpLen; + UINT32 Xid; + EFI_STATUS Status; ++ UINTN DiscoverLenNeeded; + + PxeBc = &Private->PxeBc; + Mode = PxeBc->Mode; +@@ -2169,7 +2198,8 @@ PxeBcDhcp6Discover ( + return EFI_DEVICE_ERROR; + } + +- Discover = AllocateZeroPool (sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET)); ++ DiscoverLenNeeded = sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET); ++ Discover = AllocateZeroPool (DiscoverLenNeeded); + if (Discover == NULL) { + return EFI_OUT_OF_RESOURCES; + } +@@ -2185,22 +2215,37 @@ PxeBcDhcp6Discover ( + DiscoverLen = sizeof (EFI_DHCP6_HEADER); + RequestLen = DiscoverLen; + ++ // ++ // The request packet is generated by the UEFI network stack. In the DHCP4 DORA and DHCP6 SARR sequence, ++ // the first (discover in DHCP4 and solicit in DHCP6) and third (request in both DHCP4 and DHCP6) are ++ // generated by the DHCP client (the UEFI network stack in this case). By the time this function executes, ++ // the DHCP sequence already has been executed once (see UEFI Specification Figures 24.2 and 24.3), with ++ // Private->Dhcp6Request being a cached copy of the DHCP6 request packet that UEFI network stack previously ++ // generated and sent. ++ // ++ // Therefore while this code looks like it could overflow, in practice it's not possible. ++ // + while (RequestLen < Request->Length) { + OpCode = NTOHS (((EFI_DHCP6_PACKET_OPTION *)RequestOpt)->OpCode); + OpLen = NTOHS (((EFI_DHCP6_PACKET_OPTION *)RequestOpt)->OpLen); + if ((OpCode != EFI_DHCP6_IA_TYPE_NA) && + (OpCode != EFI_DHCP6_IA_TYPE_TA)) + { ++ if (DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN > DiscoverLenNeeded) { ++ Status = EFI_OUT_OF_RESOURCES; ++ goto ON_ERROR; ++ } ++ + // + // Copy all the options except IA option. + // +- CopyMem (DiscoverOpt, RequestOpt, OpLen + 4); +- DiscoverOpt += (OpLen + 4); +- DiscoverLen += (OpLen + 4); ++ CopyMem (DiscoverOpt, RequestOpt, OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); ++ DiscoverOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); ++ DiscoverLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); + } + +- RequestOpt += (OpLen + 4); +- RequestLen += (OpLen + 4); ++ RequestOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); ++ RequestLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); + } + + Status = PxeBc->UdpWrite ( +diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h +index c86f6d391b80..6357d27faefd 100644 +--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h ++++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h +@@ -34,6 +34,23 @@ + #define PXEBC_ADDR_START_DELIMITER '[' + #define PXEBC_ADDR_END_DELIMITER ']' + ++// ++// A DUID consists of a 2-octet type code represented in network byte ++// order, followed by a variable number of octets that make up the ++// actual identifier. The length of the DUID (not including the type ++// code) is at least 1 octet and at most 128 octets. ++// ++#define PXEBC_MIN_SIZE_OF_DUID (sizeof(UINT16) + 1) ++#define PXEBC_MAX_SIZE_OF_DUID (sizeof(UINT16) + 128) ++ ++// ++// This define represents the combineds code and length field from ++// https://datatracker.ietf.org/doc/html/rfc3315#section-22.1 ++// ++#define PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN \ ++ (sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->OpCode) + \ ++ sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->OpLen)) ++ + #define GET_NEXT_DHCP6_OPTION(Opt) \ + (EFI_DHCP6_PACKET_OPTION *) ((UINT8 *) (Opt) + \ + sizeof (EFI_DHCP6_PACKET_OPTION) + (NTOHS ((Opt)->OpLen)) - 1) diff --git a/SPECS/edk2/CVE-2023-45236.patch b/SPECS/edk2/CVE-2023-45236.patch new file mode 100644 index 00000000000..de27a20cf1a --- /dev/null +++ b/SPECS/edk2/CVE-2023-45236.patch @@ -0,0 +1,823 @@ +From 147c87ac780ea20d2ce5e9b56980eb509a06cd17 Mon Sep 17 00:00:00 2001 +From: Doug Flick +Date: Wed, 8 May 2024 22:56:29 -0700 +Subject: [PATCH] NetworkPkg TcpDxe: SECURITY PATCH CVE-2023-45236 + +REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4541 +REF: https://www.rfc-editor.org/rfc/rfc1948.txt +REF: https://www.rfc-editor.org/rfc/rfc6528.txt +REF: https://www.rfc-editor.org/rfc/rfc9293.txt + +Bug Overview: +PixieFail Bug #8 +CVE-2023-45236 +CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:N/A:N +CWE-200 Exposure of Sensitive Information to an Unauthorized Actor + +Updates TCP ISN generation to use a cryptographic hash of the +connection's identifying parameters and a secret key. +This prevents an attacker from guessing the ISN used for some other +connection. + +This is follows the guidance in RFC 1948, RFC 6528, and RFC 9293. + +RFC: 9293 Section 3.4.1. Initial Sequence Number Selection + + A TCP implementation MUST use the above type of "clock" for clock- + driven selection of initial sequence numbers (MUST-8), and SHOULD + generate its initial sequence numbers with the expression: + + ISN = M + F(localip, localport, remoteip, remoteport, secretkey) + + where M is the 4 microsecond timer, and F() is a pseudorandom + function (PRF) of the connection's identifying parameters ("localip, + localport, remoteip, remoteport") and a secret key ("secretkey") + (SHLD-1). F() MUST NOT be computable from the outside (MUST-9), or + an attacker could still guess at sequence numbers from the ISN used + for some other connection. The PRF could be implemented as a + cryptographic hash of the concatenation of the TCP connection + parameters and some secret data. For discussion of the selection of + a specific hash algorithm and management of the secret key data, + please see Section 3 of [42]. + + For each connection there is a send sequence number and a receive + sequence number. The initial send sequence number (ISS) is chosen by + the data sending TCP peer, and the initial receive sequence number + (IRS) is learned during the connection-establishing procedure. + + For a connection to be established or initialized, the two TCP peers + must synchronize on each other's initial sequence numbers. This is + done in an exchange of connection-establishing segments carrying a + control bit called "SYN" (for synchronize) and the initial sequence + numbers. As a shorthand, segments carrying the SYN bit are also + called "SYNs". Hence, the solution requires a suitable mechanism for + picking an initial sequence number and a slightly involved handshake + to exchange the ISNs. + +Cc: Saloni Kasbekar +Cc: Zachary Clark-williams + +Signed-off-by: Doug Flick [MSFT] +Reviewed-by: Saloni Kasbekar +--- + NetworkPkg/TcpDxe/TcpDriver.c | 92 ++++++++++++- + NetworkPkg/TcpDxe/TcpDxe.inf | 8 +- + NetworkPkg/TcpDxe/TcpFunc.h | 23 ++-- + NetworkPkg/TcpDxe/TcpInput.c | 13 +- + NetworkPkg/TcpDxe/TcpMain.h | 59 ++++++-- + NetworkPkg/TcpDxe/TcpMisc.c | 244 +++++++++++++++++++++++++++++++-- + NetworkPkg/TcpDxe/TcpTimer.c | 3 +- + SecurityPkg/SecurityFixes.yaml | 22 +++ + 8 files changed, 415 insertions(+), 49 deletions(-) + +diff --git a/NetworkPkg/TcpDxe/TcpDriver.c b/NetworkPkg/TcpDxe/TcpDriver.c +index 8fe6bad..40bba40 100644 +--- a/NetworkPkg/TcpDxe/TcpDriver.c ++++ b/NetworkPkg/TcpDxe/TcpDriver.c +@@ -83,6 +83,12 @@ EFI_SERVICE_BINDING_PROTOCOL gTcpServiceBinding = { + TcpServiceBindingDestroyChild + }; + ++// ++// This is the handle for the Hash2ServiceBinding Protocol instance this driver produces ++// if the platform does not provide one. ++// ++EFI_HANDLE mHash2ServiceHandle = NULL; ++ + /** + Create and start the heartbeat timer for the TCP driver. + +@@ -165,6 +171,23 @@ TcpDriverEntryPoint ( + EFI_STATUS Status; + UINT32 Random; + ++ // ++ // Initialize the Secret used for hashing TCP sequence numbers ++ // ++ // Normally this should be regenerated periodically, but since ++ // this is only used for UEFI networking and not a general purpose ++ // operating system, it is not necessary to regenerate it. ++ // ++ Status = PseudoRandomU32 (&mTcpGlobalSecret); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status)); ++ return Status; ++ } ++ ++ // ++ // Get a random number used to generate a random port number ++ // Intentionally not linking this to mTcpGlobalSecret to avoid leaking information about the secret ++ // + Status = PseudoRandomU32 (&Random); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a Failed to generate random number: %r\n", __func__, Status)); +@@ -207,9 +230,8 @@ TcpDriverEntryPoint ( + } + + // +- // Initialize ISS and random port. ++ // Initialize the random port. + // +- mTcpGlobalIss = Random % mTcpGlobalIss; + mTcp4RandomPort = (UINT16)(TCP_PORT_KNOWN + (Random % TCP_PORT_KNOWN)); + mTcp6RandomPort = mTcp4RandomPort; + +@@ -224,6 +246,8 @@ TcpDriverEntryPoint ( + @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6. + + @retval EFI_OUT_OF_RESOURCES Failed to allocate some resources. ++ @retval EFI_UNSUPPORTED Service Binding Protocols are unavailable. ++ @retval EFI_ALREADY_STARTED The TCP driver is already started on the controller. + @retval EFI_SUCCESS A new IP6 service binding private was created. + + **/ +@@ -234,11 +258,13 @@ TcpCreateService ( + IN UINT8 IpVersion + ) + { +- EFI_STATUS Status; +- EFI_GUID *IpServiceBindingGuid; +- EFI_GUID *TcpServiceBindingGuid; +- TCP_SERVICE_DATA *TcpServiceData; +- IP_IO_OPEN_DATA OpenData; ++ EFI_STATUS Status; ++ EFI_GUID *IpServiceBindingGuid; ++ EFI_GUID *TcpServiceBindingGuid; ++ TCP_SERVICE_DATA *TcpServiceData; ++ IP_IO_OPEN_DATA OpenData; ++ EFI_SERVICE_BINDING_PROTOCOL *Hash2ServiceBinding; ++ EFI_HASH2_PROTOCOL *Hash2Protocol; + + if (IpVersion == IP_VERSION_4) { + IpServiceBindingGuid = &gEfiIp4ServiceBindingProtocolGuid; +@@ -272,6 +298,33 @@ TcpCreateService ( + return EFI_UNSUPPORTED; + } + ++ Status = gBS->LocateProtocol (&gEfiHash2ProtocolGuid, NULL, (VOID **)&Hash2Protocol); ++ if (EFI_ERROR (Status)) { ++ // ++ // If we can't find the Hashing protocol, then we need to create one. ++ // ++ ++ // ++ // Platform is expected to publish the hash service binding protocol to support TCP. ++ // ++ Status = gBS->LocateProtocol ( ++ &gEfiHash2ServiceBindingProtocolGuid, ++ NULL, ++ (VOID **)&Hash2ServiceBinding ++ ); ++ if (EFI_ERROR (Status) || (Hash2ServiceBinding == NULL) || (Hash2ServiceBinding->CreateChild == NULL)) { ++ return EFI_UNSUPPORTED; ++ } ++ ++ // ++ // Create an instance of the hash protocol for this controller. ++ // ++ Status = Hash2ServiceBinding->CreateChild (Hash2ServiceBinding, &mHash2ServiceHandle); ++ if (EFI_ERROR (Status)) { ++ return EFI_UNSUPPORTED; ++ } ++ } ++ + // + // Create the TCP service data. + // +@@ -423,6 +476,7 @@ TcpDestroyService ( + EFI_STATUS Status; + LIST_ENTRY *List; + TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context; ++ EFI_SERVICE_BINDING_PROTOCOL *Hash2ServiceBinding; + + ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6)); + +@@ -439,6 +493,30 @@ TcpDestroyService ( + return EFI_SUCCESS; + } + ++ // ++ // Destroy the Hash2ServiceBinding instance if it is created by Tcp driver. ++ // ++ if (mHash2ServiceHandle != NULL) { ++ Status = gBS->LocateProtocol ( ++ &gEfiHash2ServiceBindingProtocolGuid, ++ NULL, ++ (VOID **)&Hash2ServiceBinding ++ ); ++ if (EFI_ERROR (Status) || (Hash2ServiceBinding == NULL) || (Hash2ServiceBinding->DestroyChild == NULL)) { ++ return EFI_UNSUPPORTED; ++ } ++ ++ // ++ // Destroy the instance of the hashing protocol for this controller. ++ // ++ Status = Hash2ServiceBinding->DestroyChild (Hash2ServiceBinding, &mHash2ServiceHandle); ++ if (EFI_ERROR (Status)) { ++ return EFI_UNSUPPORTED; ++ } ++ ++ mHash2ServiceHandle = NULL; ++ } ++ + Status = gBS->OpenProtocol ( + NicHandle, + ServiceBindingGuid, +diff --git a/NetworkPkg/TcpDxe/TcpDxe.inf b/NetworkPkg/TcpDxe/TcpDxe.inf +index cf5423f..76de4cf 100644 +--- a/NetworkPkg/TcpDxe/TcpDxe.inf ++++ b/NetworkPkg/TcpDxe/TcpDxe.inf +@@ -6,6 +6,7 @@ + # stack has been loaded in system. This driver supports both IPv4 and IPv6 network stack. + # + # Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
++# Copyright (c) Microsoft Corporation + # + # SPDX-License-Identifier: BSD-2-Clause-Patent + # +@@ -68,7 +69,6 @@ + NetLib + IpIoLib + +- + [Protocols] + ## SOMETIMES_CONSUMES + ## SOMETIMES_PRODUCES +@@ -81,6 +81,12 @@ + gEfiIp6ServiceBindingProtocolGuid ## TO_START + gEfiTcp6ProtocolGuid ## BY_START + gEfiTcp6ServiceBindingProtocolGuid ## BY_START ++ gEfiHash2ProtocolGuid ## BY_START ++ gEfiHash2ServiceBindingProtocolGuid ## BY_START ++ ++[Guids] ++ gEfiHashAlgorithmMD5Guid ## CONSUMES ++ gEfiHashAlgorithmSha256Guid ## CONSUMES + + [Depex] + gEfiHash2ServiceBindingProtocolGuid +diff --git a/NetworkPkg/TcpDxe/TcpFunc.h b/NetworkPkg/TcpDxe/TcpFunc.h +index a7af01f..c707bee 100644 +--- a/NetworkPkg/TcpDxe/TcpFunc.h ++++ b/NetworkPkg/TcpDxe/TcpFunc.h +@@ -2,7 +2,7 @@ + Declaration of external functions shared in TCP driver. + + Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.
+- ++ Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + + **/ +@@ -36,8 +36,11 @@ VOID + + @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. + ++ @retval EFI_SUCCESS The operation completed successfully ++ @retval others The underlying functions failed and could not complete the operation ++ + **/ +-VOID ++EFI_STATUS + TcpInitTcbLocal ( + IN OUT TCP_CB *Tcb + ); +@@ -128,17 +131,6 @@ TcpCloneTcb ( + IN TCP_CB *Tcb + ); + +-/** +- Compute an ISS to be used by a new connection. +- +- @return The result ISS. +- +-**/ +-TCP_SEQNO +-TcpGetIss ( +- VOID +- ); +- + /** + Get the local mss. + +@@ -202,8 +194,11 @@ TcpFormatNetbuf ( + @param[in, out] Tcb Pointer to the TCP_CB that wants to initiate a + connection. + ++ @retval EFI_SUCCESS The operation completed successfully ++ @retval others The underlying functions failed and could not complete the operation ++ + **/ +-VOID ++EFI_STATUS + TcpOnAppConnect ( + IN OUT TCP_CB *Tcb + ); +diff --git a/NetworkPkg/TcpDxe/TcpInput.c b/NetworkPkg/TcpDxe/TcpInput.c +index fb1aa82..0477a15 100644 +--- a/NetworkPkg/TcpDxe/TcpInput.c ++++ b/NetworkPkg/TcpDxe/TcpInput.c +@@ -724,6 +724,7 @@ TcpInput ( + TCP_SEQNO Urg; + UINT16 Checksum; + INT32 Usable; ++ EFI_STATUS Status; + + ASSERT ((Version == IP_VERSION_4) || (Version == IP_VERSION_6)); + +@@ -872,7 +873,17 @@ TcpInput ( + Tcb->LocalEnd.Port = Head->DstPort; + Tcb->RemoteEnd.Port = Head->SrcPort; + +- TcpInitTcbLocal (Tcb); ++ Status = TcpInitTcbLocal (Tcb); ++ if (EFI_ERROR (Status)) { ++ DEBUG ( ++ (DEBUG_ERROR, ++ "TcpInput: discard a segment because failed to init local end for TCB %p\n", ++ Tcb) ++ ); ++ ++ goto DISCARD; ++ } ++ + TcpInitTcbPeer (Tcb, Seg, &Option); + + TcpSetState (Tcb, TCP_SYN_RCVD); +diff --git a/NetworkPkg/TcpDxe/TcpMain.h b/NetworkPkg/TcpDxe/TcpMain.h +index c0c9b7f..4d5566a 100644 +--- a/NetworkPkg/TcpDxe/TcpMain.h ++++ b/NetworkPkg/TcpDxe/TcpMain.h +@@ -3,7 +3,7 @@ + It is the common head file for all Tcp*.c in TCP driver. + + Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
+- ++ Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + + **/ +@@ -13,6 +13,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -31,7 +32,7 @@ extern EFI_UNICODE_STRING_TABLE *gTcpControllerNameTable; + + extern LIST_ENTRY mTcpRunQue; + extern LIST_ENTRY mTcpListenQue; +-extern TCP_SEQNO mTcpGlobalIss; ++extern TCP_SEQNO mTcpGlobalSecret; + extern UINT32 mTcpTick; + + /// +@@ -45,14 +46,6 @@ extern UINT32 mTcpTick; + + #define TCP_EXPIRE_TIME 65535 + +-/// +-/// The implementation selects the initial send sequence number and the unit to +-/// be added when it is increased. +-/// +-#define TCP_BASE_ISS 0x4d7e980b +-#define TCP_ISS_INCREMENT_1 2048 +-#define TCP_ISS_INCREMENT_2 100 +- + typedef union { + EFI_TCP4_CONFIG_DATA Tcp4CfgData; + EFI_TCP6_CONFIG_DATA Tcp6CfgData; +@@ -774,4 +767,50 @@ Tcp6Poll ( + IN EFI_TCP6_PROTOCOL *This + ); + ++/** ++ Retrieves the Initial Sequence Number (ISN) for a TCP connection identified by local ++ and remote IP addresses and ports. ++ ++ This method is based on https://datatracker.ietf.org/doc/html/rfc9293#section-3.4.1 ++ Where the ISN is computed as follows: ++ ISN = TimeStamp + MD5(LocalIP, LocalPort, RemoteIP, RemotePort, Secret) ++ ++ Otherwise: ++ ISN = M + F(localip, localport, remoteip, remoteport, secretkey) ++ ++ "Here M is the 4 microsecond timer, and F() is a pseudorandom function (PRF) of the ++ connection's identifying parameters ("localip, localport, remoteip, remoteport") ++ and a secret key ("secretkey") (SHLD-1). F() MUST NOT be computable from the ++ outside (MUST-9), or an attacker could still guess at sequence numbers from the ++ ISN used for some other connection. The PRF could be implemented as a ++ cryptographic hash of the concatenation of the TCP connection parameters and some ++ secret data. For discussion of the selection of a specific hash algorithm and ++ management of the secret key data." ++ ++ @param[in] LocalIp A pointer to the local IP address of the TCP connection. ++ @param[in] LocalIpSize The size, in bytes, of the LocalIp buffer. ++ @param[in] LocalPort The local port number of the TCP connection. ++ @param[in] RemoteIp A pointer to the remote IP address of the TCP connection. ++ @param[in] RemoteIpSize The size, in bytes, of the RemoteIp buffer. ++ @param[in] RemotePort The remote port number of the TCP connection. ++ @param[out] Isn A pointer to the variable that will receive the Initial ++ Sequence Number (ISN). ++ ++ @retval EFI_SUCCESS The operation completed successfully, and the ISN was ++ retrieved. ++ @retval EFI_INVALID_PARAMETER One or more of the input parameters are invalid. ++ @retval EFI_UNSUPPORTED The operation is not supported. ++ ++**/ ++EFI_STATUS ++TcpGetIsn ( ++ IN UINT8 *LocalIp, ++ IN UINTN LocalIpSize, ++ IN UINT16 LocalPort, ++ IN UINT8 *RemoteIp, ++ IN UINTN RemoteIpSize, ++ IN UINT16 RemotePort, ++ OUT TCP_SEQNO *Isn ++ ); ++ + #endif +diff --git a/NetworkPkg/TcpDxe/TcpMisc.c b/NetworkPkg/TcpDxe/TcpMisc.c +index c93212d..3310306 100644 +--- a/NetworkPkg/TcpDxe/TcpMisc.c ++++ b/NetworkPkg/TcpDxe/TcpMisc.c +@@ -3,7 +3,7 @@ + + (C) Copyright 2014 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.
+- ++ Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + + **/ +@@ -20,7 +20,34 @@ LIST_ENTRY mTcpListenQue = { + &mTcpListenQue + }; + +-TCP_SEQNO mTcpGlobalIss = TCP_BASE_ISS; ++// ++// The Session secret ++// This must be initialized to a random value at boot time ++// ++TCP_SEQNO mTcpGlobalSecret; ++ ++// ++// Union to hold either an IPv4 or IPv6 address ++// This is used to simplify the ISN hash computation ++// ++typedef union { ++ UINT8 IPv4[4]; ++ UINT8 IPv6[16]; ++} NETWORK_ADDRESS; ++ ++// ++// The ISN is computed by hashing this structure ++// It is initialized with the local and remote IP addresses and ports ++// and the secret ++// ++// ++typedef struct { ++ UINT16 LocalPort; ++ UINT16 RemotePort; ++ NETWORK_ADDRESS LocalAddress; ++ NETWORK_ADDRESS RemoteAddress; ++ TCP_SEQNO Secret; ++} ISN_HASH_CTX; + + CHAR16 *mTcpStateName[] = { + L"TCP_CLOSED", +@@ -41,12 +68,18 @@ CHAR16 *mTcpStateName[] = { + + @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. + ++ @retval EFI_SUCCESS The operation completed successfully ++ @retval others The underlying functions failed and could not complete the operation ++ + **/ +-VOID ++EFI_STATUS + TcpInitTcbLocal ( + IN OUT TCP_CB *Tcb + ) + { ++ TCP_SEQNO Isn; ++ EFI_STATUS Status; ++ + // + // Compute the checksum of the fixed parts of pseudo header + // +@@ -57,6 +90,16 @@ TcpInitTcbLocal ( + 0x06, + 0 + ); ++ ++ Status = TcpGetIsn ( ++ Tcb->LocalEnd.Ip.v4.Addr, ++ sizeof (IPv4_ADDRESS), ++ Tcb->LocalEnd.Port, ++ Tcb->RemoteEnd.Ip.v4.Addr, ++ sizeof (IPv4_ADDRESS), ++ Tcb->RemoteEnd.Port, ++ &Isn ++ ); + } else { + Tcb->HeadSum = NetIp6PseudoHeadChecksum ( + &Tcb->LocalEnd.Ip.v6, +@@ -64,9 +107,25 @@ TcpInitTcbLocal ( + 0x06, + 0 + ); ++ ++ Status = TcpGetIsn ( ++ Tcb->LocalEnd.Ip.v6.Addr, ++ sizeof (IPv6_ADDRESS), ++ Tcb->LocalEnd.Port, ++ Tcb->RemoteEnd.Ip.v6.Addr, ++ sizeof (IPv6_ADDRESS), ++ Tcb->RemoteEnd.Port, ++ &Isn ++ ); ++ } ++ ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "TcpInitTcbLocal: failed to get isn\n")); ++ ASSERT (FALSE); ++ return Status; + } + +- Tcb->Iss = TcpGetIss (); ++ Tcb->Iss = Isn; + Tcb->SndUna = Tcb->Iss; + Tcb->SndNxt = Tcb->Iss; + +@@ -82,6 +141,8 @@ TcpInitTcbLocal ( + Tcb->RetxmitSeqMax = 0; + + Tcb->ProbeTimerOn = FALSE; ++ ++ return EFI_SUCCESS; + } + + /** +@@ -506,18 +567,162 @@ TcpCloneTcb ( + } + + /** +- Compute an ISS to be used by a new connection. +- +- @return The resulting ISS. ++ Retrieves the Initial Sequence Number (ISN) for a TCP connection identified by local ++ and remote IP addresses and ports. ++ ++ This method is based on https://datatracker.ietf.org/doc/html/rfc9293#section-3.4.1 ++ Where the ISN is computed as follows: ++ ISN = TimeStamp + MD5(LocalIP, LocalPort, RemoteIP, RemotePort, Secret) ++ ++ Otherwise: ++ ISN = M + F(localip, localport, remoteip, remoteport, secretkey) ++ ++ "Here M is the 4 microsecond timer, and F() is a pseudorandom function (PRF) of the ++ connection's identifying parameters ("localip, localport, remoteip, remoteport") ++ and a secret key ("secretkey") (SHLD-1). F() MUST NOT be computable from the ++ outside (MUST-9), or an attacker could still guess at sequence numbers from the ++ ISN used for some other connection. The PRF could be implemented as a ++ cryptographic hash of the concatenation of the TCP connection parameters and some ++ secret data. For discussion of the selection of a specific hash algorithm and ++ management of the secret key data." ++ ++ @param[in] LocalIp A pointer to the local IP address of the TCP connection. ++ @param[in] LocalIpSize The size, in bytes, of the LocalIp buffer. ++ @param[in] LocalPort The local port number of the TCP connection. ++ @param[in] RemoteIp A pointer to the remote IP address of the TCP connection. ++ @param[in] RemoteIpSize The size, in bytes, of the RemoteIp buffer. ++ @param[in] RemotePort The remote port number of the TCP connection. ++ @param[out] Isn A pointer to the variable that will receive the Initial ++ Sequence Number (ISN). ++ ++ @retval EFI_SUCCESS The operation completed successfully, and the ISN was ++ retrieved. ++ @retval EFI_INVALID_PARAMETER One or more of the input parameters are invalid. ++ @retval EFI_UNSUPPORTED The operation is not supported. + + **/ +-TCP_SEQNO +-TcpGetIss ( +- VOID ++EFI_STATUS ++TcpGetIsn ( ++ IN UINT8 *LocalIp, ++ IN UINTN LocalIpSize, ++ IN UINT16 LocalPort, ++ IN UINT8 *RemoteIp, ++ IN UINTN RemoteIpSize, ++ IN UINT16 RemotePort, ++ OUT TCP_SEQNO *Isn + ) + { +- mTcpGlobalIss += TCP_ISS_INCREMENT_1; +- return mTcpGlobalIss; ++ EFI_STATUS Status; ++ EFI_HASH2_PROTOCOL *Hash2Protocol; ++ EFI_HASH2_OUTPUT HashResult; ++ ISN_HASH_CTX IsnHashCtx; ++ EFI_TIME TimeStamp; ++ ++ // ++ // Check that the ISN pointer is valid ++ // ++ if (Isn == NULL) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // The local ip may be a v4 or v6 address and may not be NULL ++ // ++ if ((LocalIp == NULL) || (LocalIpSize == 0) || (RemoteIp == NULL) || (RemoteIpSize == 0)) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // the local ip may be a v4 or v6 address ++ // ++ if ((LocalIpSize != sizeof (EFI_IPv4_ADDRESS)) && (LocalIpSize != sizeof (EFI_IPv6_ADDRESS))) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ // ++ // Locate the Hash Protocol ++ // ++ Status = gBS->LocateProtocol (&gEfiHash2ProtocolGuid, NULL, (VOID **)&Hash2Protocol); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_NET, "Failed to locate Hash Protocol: %r\n", Status)); ++ ++ // ++ // TcpCreateService(..) is expected to be called prior to this function ++ // ++ ASSERT_EFI_ERROR (Status); ++ return Status; ++ } ++ ++ // ++ // Initialize the hash algorithm ++ // ++ Status = Hash2Protocol->HashInit (Hash2Protocol, &gEfiHashAlgorithmSha256Guid); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_NET, "Failed to initialize sha256 hash algorithm: %r\n", Status)); ++ return Status; ++ } ++ ++ IsnHashCtx.LocalPort = LocalPort; ++ IsnHashCtx.RemotePort = RemotePort; ++ IsnHashCtx.Secret = mTcpGlobalSecret; ++ ++ // ++ // Check the IP address family and copy accordingly ++ // ++ if (LocalIpSize == sizeof (EFI_IPv4_ADDRESS)) { ++ CopyMem (&IsnHashCtx.LocalAddress.IPv4, LocalIp, LocalIpSize); ++ } else if (LocalIpSize == sizeof (EFI_IPv6_ADDRESS)) { ++ CopyMem (&IsnHashCtx.LocalAddress.IPv6, LocalIp, LocalIpSize); ++ } else { ++ return EFI_INVALID_PARAMETER; // Unsupported address size ++ } ++ ++ // ++ // Repeat the process for the remote IP address ++ // ++ if (RemoteIpSize == sizeof (EFI_IPv4_ADDRESS)) { ++ CopyMem (&IsnHashCtx.RemoteAddress.IPv4, RemoteIp, RemoteIpSize); ++ } else if (RemoteIpSize == sizeof (EFI_IPv6_ADDRESS)) { ++ CopyMem (&IsnHashCtx.RemoteAddress.IPv6, RemoteIp, RemoteIpSize); ++ } else { ++ return EFI_INVALID_PARAMETER; // Unsupported address size ++ } ++ ++ // ++ // Compute the hash ++ // Update the hash with the data ++ // ++ Status = Hash2Protocol->HashUpdate (Hash2Protocol, (UINT8 *)&IsnHashCtx, sizeof (IsnHashCtx)); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_NET, "Failed to update hash: %r\n", Status)); ++ return Status; ++ } ++ ++ // ++ // Finalize the hash and retrieve the result ++ // ++ Status = Hash2Protocol->HashFinal (Hash2Protocol, &HashResult); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_NET, "Failed to finalize hash: %r\n", Status)); ++ return Status; ++ } ++ ++ Status = gRT->GetTime (&TimeStamp, NULL); ++ if (EFI_ERROR (Status)) { ++ return Status; ++ } ++ ++ // ++ // copy the first 4 bytes of the hash result into the ISN ++ // ++ CopyMem (Isn, HashResult.Md5Hash, sizeof (*Isn)); ++ ++ // ++ // now add the timestamp to the ISN as 4 microseconds units (1000 / 4 = 250) ++ // ++ *Isn += (TCP_SEQNO)TimeStamp.Nanosecond * 250; ++ ++ return Status; + } + + /** +@@ -721,17 +926,28 @@ TcpFormatNetbuf ( + @param[in, out] Tcb Pointer to the TCP_CB that wants to initiate a + connection. + ++ @retval EFI_SUCCESS The operation completed successfully ++ @retval others The underlying functions failed and could not complete the operation ++ + **/ +-VOID ++EFI_STATUS + TcpOnAppConnect ( + IN OUT TCP_CB *Tcb + ) + { +- TcpInitTcbLocal (Tcb); ++ EFI_STATUS Status; ++ ++ Status = TcpInitTcbLocal (Tcb); ++ if (EFI_ERROR (Status)) { ++ return Status; ++ } ++ + TcpSetState (Tcb, TCP_SYN_SENT); + + TcpSetTimer (Tcb, TCP_TIMER_CONNECT, Tcb->ConnectTimeout); + TcpToSendData (Tcb, 1); ++ ++ return EFI_SUCCESS; + } + + /** +diff --git a/NetworkPkg/TcpDxe/TcpTimer.c b/NetworkPkg/TcpDxe/TcpTimer.c +index 5d2e124..065b1bd 100644 +--- a/NetworkPkg/TcpDxe/TcpTimer.c ++++ b/NetworkPkg/TcpDxe/TcpTimer.c +@@ -2,7 +2,7 @@ + TCP timer related functions. + + Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+- ++ Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + + **/ +@@ -483,7 +483,6 @@ TcpTickingDpc ( + INT16 Index; + + mTcpTick++; +- mTcpGlobalIss += TCP_ISS_INCREMENT_2; + + // + // Don't use LIST_FOR_EACH, which isn't delete safe. +diff --git a/SecurityPkg/SecurityFixes.yaml b/SecurityPkg/SecurityFixes.yaml +index 04aa6a3..1efb542 100644 +--- a/SecurityPkg/SecurityFixes.yaml ++++ b/SecurityPkg/SecurityFixes.yaml +@@ -40,6 +40,28 @@ CVE_2022_36764: + - Library\DxeTpmMeasureBootLib\DxeTpmMeasureBootLib.c + links: + - https://bugzilla.tianocore.org/show_bug.cgi?id=4118 ++CVE_2023_45236: ++ commit_titles: ++ - "NetworkPkg: TcpDxe: SECURITY PATCH CVE-2023-45236 Patch" ++ cve: CVE-2023-45236 ++ date_reported: 2023-08-28 13:56 UTC ++ description: "Bug 08 - edk2/NetworkPkg: Predictable TCP Initial Sequence Numbers" ++ note: ++ files_impacted: ++ - NetworkPkg/Include/Library/NetLib.h ++ - NetworkPkg/TcpDxe/TcpDriver.c ++ - NetworkPkg/TcpDxe/TcpDxe.inf ++ - NetworkPkg/TcpDxe/TcpFunc.h ++ - NetworkPkg/TcpDxe/TcpInput.c ++ - NetworkPkg/TcpDxe/TcpMain.h ++ - NetworkPkg/TcpDxe/TcpMisc.c ++ - NetworkPkg/TcpDxe/TcpTimer.c ++ links: ++ - https://bugzilla.tianocore.org/show_bug.cgi?id=4541 ++ - https://nvd.nist.gov/vuln/detail/CVE-2023-45236 ++ - http://www.openwall.com/lists/oss-security/2024/01/16/2 ++ - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html ++ - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html + CVE_2023_45237: + commit_titles: + - "NetworkPkg:: SECURITY PATCH CVE 2023-45237" +-- +2.25.1 + diff --git a/SPECS/edk2/CVE-2023-45237.patch b/SPECS/edk2/CVE-2023-45237.patch new file mode 100644 index 00000000000..f08619896a3 --- /dev/null +++ b/SPECS/edk2/CVE-2023-45237.patch @@ -0,0 +1,1308 @@ +From e21878df8c03edfd4950e079319477a05357dccd Mon Sep 17 00:00:00 2001 +From: Doug Flick +Date: Wed, 8 May 2024 22:56:28 -0700 +Subject: [PATCH 1/2] NetworkPkg: SECURITY PATCH CVE-2023-45237 + +REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4542 + +Bug Overview: +PixieFail Bug #9 +CVE-2023-45237 +CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N +CWE-338 Use of Cryptographically Weak Pseudo-Random Number Generator (PRNG) + +Use of a Weak PseudoRandom Number Generator + +Change Overview: + +Updates all Instances of NET_RANDOM (NetRandomInitSeed ()) to either + +> +> EFI_STATUS +> EFIAPI +> PseudoRandomU32 ( +> OUT UINT32 *Output +> ); +> + +or (depending on the use case) + +> +> EFI_STATUS +> EFIAPI +> PseudoRandom ( +> OUT VOID *Output, +> IN UINTN OutputLength +> ); +> + +This is because the use of + +Example: + +The following code snippet PseudoRandomU32 () function is used: + +> +> UINT32 Random; +> +> Status = PseudoRandomU32 (&Random); +> if (EFI_ERROR (Status)) { +> DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", +__func__, Status)); +> return Status; +> } +> + +This also introduces a new PCD to enable/disable the use of the +secure implementation of algorithms for PseudoRandom () and +instead depend on the default implementation. This may be required for +some platforms where the UEFI Spec defined algorithms are not available. + +> +> PcdEnforceSecureRngAlgorithms +> + +If the platform does not have any one of the UEFI defined +secure RNG algorithms then the driver will assert. + +Cc: Saloni Kasbekar +Cc: Zachary Clark-williams + +Signed-off-by: Doug Flick [MSFT] +Reviewed-by: Saloni Kasbekar +--- + NetworkPkg/Dhcp4Dxe/Dhcp4Driver.c | 10 +- + NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c | 11 +- + NetworkPkg/DnsDxe/DnsDhcp.c | 10 +- + NetworkPkg/DnsDxe/DnsImpl.c | 11 +- + NetworkPkg/HttpBootDxe/HttpBootDhcp6.c | 10 +- + NetworkPkg/IScsiDxe/IScsiCHAP.c | 19 ++- + NetworkPkg/IScsiDxe/IScsiMisc.c | 14 +-- + NetworkPkg/IScsiDxe/IScsiMisc.h | 6 +- + NetworkPkg/Include/Library/NetLib.h | 40 +++++-- + NetworkPkg/Ip4Dxe/Ip4Driver.c | 10 +- + NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c | 9 +- + NetworkPkg/Ip6Dxe/Ip6Driver.c | 17 ++- + NetworkPkg/Ip6Dxe/Ip6If.c | 12 +- + NetworkPkg/Ip6Dxe/Ip6Mld.c | 12 +- + NetworkPkg/Ip6Dxe/Ip6Nd.c | 33 +++++- + NetworkPkg/Ip6Dxe/Ip6Nd.h | 8 +- + NetworkPkg/Library/DxeNetLib/DxeNetLib.c | 130 ++++++++++++++++++--- + NetworkPkg/Library/DxeNetLib/DxeNetLib.inf | 14 ++- + NetworkPkg/NetworkPkg.dec | 7 ++ + NetworkPkg/TcpDxe/TcpDriver.c | 15 ++- + NetworkPkg/TcpDxe/TcpDxe.inf | 3 + + NetworkPkg/Udp4Dxe/Udp4Driver.c | 10 +- + NetworkPkg/Udp6Dxe/Udp6Driver.c | 11 +- + NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c | 9 +- + NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c | 11 +- + NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c | 12 +- + SecurityPkg/SecurityFixes.yaml | 39 +++++++ + 27 files changed, 410 insertions(+), 83 deletions(-) + +diff --git a/NetworkPkg/Dhcp4Dxe/Dhcp4Driver.c b/NetworkPkg/Dhcp4Dxe/Dhcp4Driver.c +index 8c37e93..892caee 100644 +--- a/NetworkPkg/Dhcp4Dxe/Dhcp4Driver.c ++++ b/NetworkPkg/Dhcp4Dxe/Dhcp4Driver.c +@@ -1,6 +1,7 @@ + /** @file + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
++Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + + **/ +@@ -189,6 +190,13 @@ Dhcp4CreateService ( + { + DHCP_SERVICE *DhcpSb; + EFI_STATUS Status; ++ UINT32 Random; ++ ++ Status = PseudoRandomU32 (&Random); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status)); ++ return Status; ++ } + + *Service = NULL; + DhcpSb = AllocateZeroPool (sizeof (DHCP_SERVICE)); +@@ -203,7 +211,7 @@ Dhcp4CreateService ( + DhcpSb->Image = ImageHandle; + InitializeListHead (&DhcpSb->Children); + DhcpSb->DhcpState = Dhcp4Stopped; +- DhcpSb->Xid = NET_RANDOM (NetRandomInitSeed ()); ++ DhcpSb->Xid = Random; + CopyMem ( + &DhcpSb->ServiceBinding, + &mDhcp4ServiceBindingTemplate, +diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c +index b591a46..e7f2787 100644 +--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c ++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c +@@ -3,7 +3,7 @@ + implementation for Dhcp6 Driver. + + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+- ++ Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + + **/ +@@ -123,6 +123,13 @@ Dhcp6CreateService ( + { + DHCP6_SERVICE *Dhcp6Srv; + EFI_STATUS Status; ++ UINT32 Random; ++ ++ Status = PseudoRandomU32 (&Random); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status)); ++ return Status; ++ } + + *Service = NULL; + Dhcp6Srv = AllocateZeroPool (sizeof (DHCP6_SERVICE)); +@@ -147,7 +154,7 @@ Dhcp6CreateService ( + Dhcp6Srv->Signature = DHCP6_SERVICE_SIGNATURE; + Dhcp6Srv->Controller = Controller; + Dhcp6Srv->Image = ImageHandle; +- Dhcp6Srv->Xid = (0xffffff & NET_RANDOM (NetRandomInitSeed ())); ++ Dhcp6Srv->Xid = (0xffffff & Random); + + CopyMem ( + &Dhcp6Srv->ServiceBinding, +diff --git a/NetworkPkg/DnsDxe/DnsDhcp.c b/NetworkPkg/DnsDxe/DnsDhcp.c +index 933565a..9eb3c1d 100644 +--- a/NetworkPkg/DnsDxe/DnsDhcp.c ++++ b/NetworkPkg/DnsDxe/DnsDhcp.c +@@ -2,6 +2,7 @@ + Functions implementation related with DHCPv4/v6 for DNS driver. + + Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
++Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + + **/ +@@ -277,6 +278,7 @@ GetDns4ServerFromDhcp4 ( + EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN Token; + BOOLEAN IsDone; + UINTN Index; ++ UINT32 Random; + + Image = Instance->Service->ImageHandle; + Controller = Instance->Service->ControllerHandle; +@@ -292,6 +294,12 @@ GetDns4ServerFromDhcp4 ( + Data = NULL; + InterfaceInfo = NULL; + ++ Status = PseudoRandomU32 (&Random); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status)); ++ return Status; ++ } ++ + ZeroMem ((UINT8 *)ParaList, sizeof (ParaList)); + + ZeroMem (&MnpConfigData, sizeof (EFI_MANAGED_NETWORK_CONFIG_DATA)); +@@ -467,7 +475,7 @@ GetDns4ServerFromDhcp4 ( + + Status = Dhcp4->Build (Dhcp4, &SeedPacket, 0, NULL, 2, ParaList, &Token.Packet); + +- Token.Packet->Dhcp4.Header.Xid = HTONL (NET_RANDOM (NetRandomInitSeed ())); ++ Token.Packet->Dhcp4.Header.Xid = Random; + + Token.Packet->Dhcp4.Header.Reserved = HTONS ((UINT16)0x8000); + +diff --git a/NetworkPkg/DnsDxe/DnsImpl.c b/NetworkPkg/DnsDxe/DnsImpl.c +index d311812..c2629bb 100644 +--- a/NetworkPkg/DnsDxe/DnsImpl.c ++++ b/NetworkPkg/DnsDxe/DnsImpl.c +@@ -2,6 +2,7 @@ + DnsDxe support functions implementation. + + Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.
++Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + + **/ +@@ -1963,6 +1964,14 @@ ConstructDNSQuery ( + NET_FRAGMENT Frag; + DNS_HEADER *DnsHeader; + DNS_QUERY_SECTION *DnsQuery; ++ EFI_STATUS Status; ++ UINT32 Random; ++ ++ Status = PseudoRandomU32 (&Random); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status)); ++ return Status; ++ } + + // + // Messages carried by UDP are restricted to 512 bytes (not counting the IP +@@ -1977,7 +1986,7 @@ ConstructDNSQuery ( + // Fill header + // + DnsHeader = (DNS_HEADER *)Frag.Bulk; +- DnsHeader->Identification = (UINT16)NET_RANDOM (NetRandomInitSeed ()); ++ DnsHeader->Identification = (UINT16)Random; + DnsHeader->Flags.Uint16 = 0x0000; + DnsHeader->Flags.Bits.RD = 1; + DnsHeader->Flags.Bits.OpCode = DNS_FLAGS_OPCODE_STANDARD; +diff --git a/NetworkPkg/HttpBootDxe/HttpBootDhcp6.c b/NetworkPkg/HttpBootDxe/HttpBootDhcp6.c +index b22cef4..f964515 100644 +--- a/NetworkPkg/HttpBootDxe/HttpBootDhcp6.c ++++ b/NetworkPkg/HttpBootDxe/HttpBootDhcp6.c +@@ -2,6 +2,7 @@ + Functions implementation related with DHCPv6 for HTTP boot driver. + + Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
++Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + + **/ +@@ -951,6 +952,7 @@ HttpBootDhcp6Sarr ( + UINT32 OptCount; + UINT8 Buffer[HTTP_BOOT_DHCP6_OPTION_MAX_SIZE]; + EFI_STATUS Status; ++ UINT32 Random; + + Dhcp6 = Private->Dhcp6; + ASSERT (Dhcp6 != NULL); +@@ -961,6 +963,12 @@ HttpBootDhcp6Sarr ( + OptCount = HttpBootBuildDhcp6Options (Private, OptList, Buffer); + ASSERT (OptCount > 0); + ++ Status = PseudoRandomU32 (&Random); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status)); ++ return Status; ++ } ++ + Retransmit = AllocateZeroPool (sizeof (EFI_DHCP6_RETRANSMISSION)); + if (Retransmit == NULL) { + return EFI_OUT_OF_RESOURCES; +@@ -976,7 +984,7 @@ HttpBootDhcp6Sarr ( + Config.IaInfoEvent = NULL; + Config.RapidCommit = FALSE; + Config.ReconfigureAccept = FALSE; +- Config.IaDescriptor.IaId = NET_RANDOM (NetRandomInitSeed ()); ++ Config.IaDescriptor.IaId = Random; + Config.IaDescriptor.Type = EFI_DHCP6_IA_TYPE_NA; + Config.SolicitRetransmission = Retransmit; + Retransmit->Irt = 4; +diff --git a/NetworkPkg/IScsiDxe/IScsiCHAP.c b/NetworkPkg/IScsiDxe/IScsiCHAP.c +index b507f11..bebb1ac 100644 +--- a/NetworkPkg/IScsiDxe/IScsiCHAP.c ++++ b/NetworkPkg/IScsiDxe/IScsiCHAP.c +@@ -3,6 +3,7 @@ + Configuration. + + Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
++Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + + **/ +@@ -576,16 +577,24 @@ IScsiCHAPToSendReq ( + // + // CHAP_I= + // +- IScsiGenRandom ((UINT8 *)&AuthData->OutIdentifier, 1); ++ Status = IScsiGenRandom ((UINT8 *)&AuthData->OutIdentifier, 1); ++ if (EFI_ERROR (Status)) { ++ break; ++ } ++ + AsciiSPrint (ValueStr, sizeof (ValueStr), "%d", AuthData->OutIdentifier); + IScsiAddKeyValuePair (Pdu, ISCSI_KEY_CHAP_IDENTIFIER, ValueStr); + // + // CHAP_C= + // +- IScsiGenRandom ( +- (UINT8 *)AuthData->OutChallenge, +- AuthData->Hash->DigestSize +- ); ++ Status = IScsiGenRandom ( ++ (UINT8 *)AuthData->OutChallenge, ++ AuthData->Hash->DigestSize ++ ); ++ if (EFI_ERROR (Status)) { ++ break; ++ } ++ + BinToHexStatus = IScsiBinToHex ( + (UINT8 *)AuthData->OutChallenge, + AuthData->Hash->DigestSize, +diff --git a/NetworkPkg/IScsiDxe/IScsiMisc.c b/NetworkPkg/IScsiDxe/IScsiMisc.c +index b3ea901..cd77f1a 100644 +--- a/NetworkPkg/IScsiDxe/IScsiMisc.c ++++ b/NetworkPkg/IScsiDxe/IScsiMisc.c +@@ -2,6 +2,7 @@ + Miscellaneous routines for iSCSI driver. + + Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
++Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + + **/ +@@ -474,20 +475,17 @@ IScsiNetNtoi ( + @param[in, out] Rand The buffer to contain random numbers. + @param[in] RandLength The length of the Rand buffer. + ++ @retval EFI_SUCCESS on success ++ @retval others on error ++ + **/ +-VOID ++EFI_STATUS + IScsiGenRandom ( + IN OUT UINT8 *Rand, + IN UINTN RandLength + ) + { +- UINT32 Random; +- +- while (RandLength > 0) { +- Random = NET_RANDOM (NetRandomInitSeed ()); +- *Rand++ = (UINT8)(Random); +- RandLength--; +- } ++ return PseudoRandom (Rand, RandLength); + } + + /** +diff --git a/NetworkPkg/IScsiDxe/IScsiMisc.h b/NetworkPkg/IScsiDxe/IScsiMisc.h +index a951eee..91b2cd2 100644 +--- a/NetworkPkg/IScsiDxe/IScsiMisc.h ++++ b/NetworkPkg/IScsiDxe/IScsiMisc.h +@@ -2,6 +2,7 @@ + Miscellaneous definitions for iSCSI driver. + + Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
++Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + + **/ +@@ -202,8 +203,11 @@ IScsiNetNtoi ( + @param[in, out] Rand The buffer to contain random numbers. + @param[in] RandLength The length of the Rand buffer. + ++ @retval EFI_SUCCESS on success ++ @retval others on error ++ + **/ +-VOID ++EFI_STATUS + IScsiGenRandom ( + IN OUT UINT8 *Rand, + IN UINTN RandLength +diff --git a/NetworkPkg/Include/Library/NetLib.h b/NetworkPkg/Include/Library/NetLib.h +index 8c0e62b..e8108b7 100644 +--- a/NetworkPkg/Include/Library/NetLib.h ++++ b/NetworkPkg/Include/Library/NetLib.h +@@ -3,6 +3,7 @@ + It provides basic functions for the UEFI network stack. + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.
++Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + + **/ +@@ -539,8 +540,6 @@ extern EFI_IPv4_ADDRESS mZeroIp4Addr; + #define TICKS_PER_MS 10000U + #define TICKS_PER_SECOND 10000000U + +-#define NET_RANDOM(Seed) ((UINT32) ((UINT32) (Seed) * 1103515245UL + 12345) % 4294967295UL) +- + /** + Extract a UINT32 from a byte stream. + +@@ -580,19 +579,40 @@ NetPutUint32 ( + ); + + /** +- Initialize a random seed using current time and monotonic count. ++ Generate a Random output data given a length. + +- Get current time and monotonic count first. Then initialize a random seed +- based on some basic mathematics operation on the hour, day, minute, second, +- nanosecond and year of the current time and the monotonic count value. ++ @param[out] Output - The buffer to store the generated random data. ++ @param[in] OutputLength - The length of the output buffer. + +- @return The random seed initialized with current time. ++ @retval EFI_SUCCESS On Success ++ @retval EFI_INVALID_PARAMETER Pointer is null or size is zero ++ @retval EFI_NOT_FOUND RNG protocol not found ++ @retval Others Error from RngProtocol->GetRNG() + ++ @return Status code + **/ +-UINT32 ++EFI_STATUS + EFIAPI +-NetRandomInitSeed ( +- VOID ++PseudoRandom ( ++ OUT VOID *Output, ++ IN UINTN OutputLength ++ ); ++ ++/** ++ Generate a 32-bit pseudo-random number. ++ ++ @param[out] Output - The buffer to store the generated random number. ++ ++ @retval EFI_SUCCESS On Success ++ @retval EFI_NOT_FOUND RNG protocol not found ++ @retval Others Error from RngProtocol->GetRNG() ++ ++ @return Status code ++**/ ++EFI_STATUS ++EFIAPI ++PseudoRandomU32 ( ++ OUT UINT32 *Output + ); + + #define NET_LIST_USER_STRUCT(Entry, Type, Field) \ +diff --git a/NetworkPkg/Ip4Dxe/Ip4Driver.c b/NetworkPkg/Ip4Dxe/Ip4Driver.c +index ec483ff..683423f 100644 +--- a/NetworkPkg/Ip4Dxe/Ip4Driver.c ++++ b/NetworkPkg/Ip4Dxe/Ip4Driver.c +@@ -2,6 +2,7 @@ + The driver binding and service binding protocol for IP4 driver. + + Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.
++Copyright (c) Microsoft Corporation + (C) Copyright 2015 Hewlett-Packard Development Company, L.P.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +@@ -549,11 +550,18 @@ Ip4DriverBindingStart ( + EFI_IP4_CONFIG2_PROTOCOL *Ip4Cfg2; + UINTN Index; + IP4_CONFIG2_DATA_ITEM *DataItem; ++ UINT32 Random; + + IpSb = NULL; + Ip4Cfg2 = NULL; + DataItem = NULL; + ++ Status = PseudoRandomU32 (&Random); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status)); ++ return Status; ++ } ++ + // + // Test for the Ip4 service binding protocol + // +@@ -653,7 +661,7 @@ Ip4DriverBindingStart ( + // + // Initialize the IP4 ID + // +- mIp4Id = (UINT16)NET_RANDOM (NetRandomInitSeed ()); ++ mIp4Id = (UINT16)Random; + + return Status; + +diff --git a/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c b/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c +index 70e232c..4c1354d 100644 +--- a/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c ++++ b/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c +@@ -2276,6 +2276,13 @@ Ip6ConfigInitInstance ( + UINTN Index; + UINT16 IfIndex; + IP6_CONFIG_DATA_ITEM *DataItem; ++ UINT32 Random; ++ ++ Status = PseudoRandomU32 (&Random); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status)); ++ return Status; ++ } + + IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance); + +@@ -2381,7 +2388,7 @@ Ip6ConfigInitInstance ( + // The NV variable is not set, so generate a random IAID, and write down the + // fresh new configuration as the NV variable now. + // +- Instance->IaId = NET_RANDOM (NetRandomInitSeed ()); ++ Instance->IaId = Random; + + for (Index = 0; Index < IpSb->SnpMode.HwAddressSize; Index++) { + Instance->IaId |= (IpSb->SnpMode.CurrentAddress.Addr[Index] << ((Index << 3) & 31)); +diff --git a/NetworkPkg/Ip6Dxe/Ip6Driver.c b/NetworkPkg/Ip6Dxe/Ip6Driver.c +index b483a7d..cbe011d 100644 +--- a/NetworkPkg/Ip6Dxe/Ip6Driver.c ++++ b/NetworkPkg/Ip6Dxe/Ip6Driver.c +@@ -3,7 +3,7 @@ + + Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2015 Hewlett-Packard Development Company, L.P.
+- ++ Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + + **/ +@@ -316,7 +316,11 @@ Ip6CreateService ( + IpSb->CurHopLimit = IP6_HOP_LIMIT; + IpSb->LinkMTU = IP6_MIN_LINK_MTU; + IpSb->BaseReachableTime = IP6_REACHABLE_TIME; +- Ip6UpdateReachableTime (IpSb); ++ Status = Ip6UpdateReachableTime (IpSb); ++ if (EFI_ERROR (Status)) { ++ goto ON_ERROR; ++ } ++ + // + // RFC4861 RETRANS_TIMER: 1,000 milliseconds + // +@@ -516,11 +520,18 @@ Ip6DriverBindingStart ( + EFI_STATUS Status; + EFI_IP6_CONFIG_PROTOCOL *Ip6Cfg; + IP6_CONFIG_DATA_ITEM *DataItem; ++ UINT32 Random; + + IpSb = NULL; + Ip6Cfg = NULL; + DataItem = NULL; + ++ Status = PseudoRandomU32 (&Random); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status)); ++ return Status; ++ } ++ + // + // Test for the Ip6 service binding protocol + // +@@ -656,7 +667,7 @@ Ip6DriverBindingStart ( + // + // Initialize the IP6 ID + // +- mIp6Id = NET_RANDOM (NetRandomInitSeed ()); ++ mIp6Id = Random; + + return EFI_SUCCESS; + +diff --git a/NetworkPkg/Ip6Dxe/Ip6If.c b/NetworkPkg/Ip6Dxe/Ip6If.c +index 4629c05..f3d11c4 100644 +--- a/NetworkPkg/Ip6Dxe/Ip6If.c ++++ b/NetworkPkg/Ip6Dxe/Ip6If.c +@@ -2,7 +2,7 @@ + Implement IP6 pseudo interface. + + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+- ++ Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + + **/ +@@ -89,6 +89,14 @@ Ip6SetAddress ( + IP6_PREFIX_LIST_ENTRY *PrefixEntry; + UINT64 Delay; + IP6_DELAY_JOIN_LIST *DelayNode; ++ EFI_STATUS Status; ++ UINT32 Random; ++ ++ Status = PseudoRandomU32 (&Random); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status)); ++ return Status; ++ } + + NET_CHECK_SIGNATURE (Interface, IP6_INTERFACE_SIGNATURE); + +@@ -164,7 +172,7 @@ Ip6SetAddress ( + // Thus queue the address to be processed in Duplicate Address Detection module + // after the delay time (in milliseconds). + // +- Delay = (UINT64)NET_RANDOM (NetRandomInitSeed ()); ++ Delay = (UINT64)Random; + Delay = MultU64x32 (Delay, IP6_ONE_SECOND_IN_MS); + Delay = RShiftU64 (Delay, 32); + +diff --git a/NetworkPkg/Ip6Dxe/Ip6Mld.c b/NetworkPkg/Ip6Dxe/Ip6Mld.c +index e6b2b65..498a118 100644 +--- a/NetworkPkg/Ip6Dxe/Ip6Mld.c ++++ b/NetworkPkg/Ip6Dxe/Ip6Mld.c +@@ -696,7 +696,15 @@ Ip6UpdateDelayTimer ( + IN OUT IP6_MLD_GROUP *Group + ) + { +- UINT32 Delay; ++ UINT32 Delay; ++ EFI_STATUS Status; ++ UINT32 Random; ++ ++ Status = PseudoRandomU32 (&Random); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status)); ++ return Status; ++ } + + // + // If the Query packet specifies a Maximum Response Delay of zero, perform timer +@@ -715,7 +723,7 @@ Ip6UpdateDelayTimer ( + // is less than the remaining value of the running timer. + // + if ((Group->DelayTimer == 0) || (Delay < Group->DelayTimer)) { +- Group->DelayTimer = Delay / 4294967295UL * NET_RANDOM (NetRandomInitSeed ()); ++ Group->DelayTimer = Delay / 4294967295UL * Random; + } + + return EFI_SUCCESS; +diff --git a/NetworkPkg/Ip6Dxe/Ip6Nd.c b/NetworkPkg/Ip6Dxe/Ip6Nd.c +index c10c701..72aa45c 100644 +--- a/NetworkPkg/Ip6Dxe/Ip6Nd.c ++++ b/NetworkPkg/Ip6Dxe/Ip6Nd.c +@@ -2,7 +2,7 @@ + Implementation of Neighbor Discovery support routines. + + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+- ++ Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + + **/ +@@ -16,17 +16,28 @@ EFI_MAC_ADDRESS mZeroMacAddress; + + @param[in, out] IpSb Points to the IP6_SERVICE. + ++ @retval EFI_SUCCESS ReachableTime Updated ++ @retval others Failed to update ReachableTime + **/ +-VOID ++EFI_STATUS + Ip6UpdateReachableTime ( + IN OUT IP6_SERVICE *IpSb + ) + { +- UINT32 Random; ++ UINT32 Random; ++ EFI_STATUS Status; + +- Random = (NetRandomInitSeed () / 4294967295UL) * IP6_RANDOM_FACTOR_SCALE; ++ Status = PseudoRandomU32 (&Random); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status)); ++ return Status; ++ } ++ ++ Random = (Random / 4294967295UL) * IP6_RANDOM_FACTOR_SCALE; + Random = Random + IP6_MIN_RANDOM_FACTOR_SCALED; + IpSb->ReachableTime = (IpSb->BaseReachableTime * Random) / IP6_RANDOM_FACTOR_SCALE; ++ ++ return EFI_SUCCESS; + } + + /** +@@ -972,10 +983,17 @@ Ip6InitDADProcess ( + IP6_SERVICE *IpSb; + EFI_STATUS Status; + UINT32 MaxDelayTick; ++ UINT32 Random; + + NET_CHECK_SIGNATURE (IpIf, IP6_INTERFACE_SIGNATURE); + ASSERT (AddressInfo != NULL); + ++ Status = PseudoRandomU32 (&Random); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status)); ++ return Status; ++ } ++ + // + // Do nothing if we have already started DAD on the address. + // +@@ -1014,7 +1032,7 @@ Ip6InitDADProcess ( + Entry->Transmit = 0; + Entry->Receive = 0; + MaxDelayTick = IP6_MAX_RTR_SOLICITATION_DELAY / IP6_TIMER_INTERVAL_IN_MS; +- Entry->RetransTick = (MaxDelayTick * ((NET_RANDOM (NetRandomInitSeed ()) % 5) + 1)) / 5; ++ Entry->RetransTick = (MaxDelayTick * ((Random % 5) + 1)) / 5; + Entry->AddressInfo = AddressInfo; + Entry->Callback = Callback; + Entry->Context = Context; +@@ -2078,7 +2096,10 @@ Ip6ProcessRouterAdvertise ( + // in BaseReachableTime and recompute a ReachableTime. + // + IpSb->BaseReachableTime = ReachableTime; +- Ip6UpdateReachableTime (IpSb); ++ Status = Ip6UpdateReachableTime (IpSb); ++ if (EFI_ERROR (Status)) { ++ goto Exit; ++ } + } + + if (RetransTimer != 0) { +diff --git a/NetworkPkg/Ip6Dxe/Ip6Nd.h b/NetworkPkg/Ip6Dxe/Ip6Nd.h +index bf64e91..5795e23 100644 +--- a/NetworkPkg/Ip6Dxe/Ip6Nd.h ++++ b/NetworkPkg/Ip6Dxe/Ip6Nd.h +@@ -2,7 +2,7 @@ + Definition of Neighbor Discovery support routines. + + Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
+- ++ Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + + **/ +@@ -780,10 +780,10 @@ Ip6OnArpResolved ( + /** + Update the ReachableTime in IP6 service binding instance data, in milliseconds. + +- @param[in, out] IpSb Points to the IP6_SERVICE. +- ++ @retval EFI_SUCCESS ReachableTime Updated ++ @retval others Failed to update ReachableTime + **/ +-VOID ++EFI_STATUS + Ip6UpdateReachableTime ( + IN OUT IP6_SERVICE *IpSb + ); +diff --git a/NetworkPkg/Library/DxeNetLib/DxeNetLib.c b/NetworkPkg/Library/DxeNetLib/DxeNetLib.c +index fd4a9e1..01c13c0 100644 +--- a/NetworkPkg/Library/DxeNetLib/DxeNetLib.c ++++ b/NetworkPkg/Library/DxeNetLib/DxeNetLib.c +@@ -3,6 +3,7 @@ + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.
+ (C) Copyright 2015 Hewlett Packard Enterprise Development LP
++Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + **/ + +@@ -31,6 +32,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent + #include + #include + #include ++#include + + #define NIC_ITEM_CONFIG_SIZE (sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * MAX_IP4_CONFIG_IN_VARIABLE) + #define DEFAULT_ZERO_START ((UINTN) ~0) +@@ -127,6 +129,25 @@ GLOBAL_REMOVE_IF_UNREFERENCED VLAN_DEVICE_PATH mNetVlanDevicePathTemplate = { + 0 + }; + ++// ++// These represent UEFI SPEC defined algorithms that should be supported by ++// the RNG protocol and are generally considered secure. ++// ++// The order of the algorithms in this array is important. This order is the order ++// in which the algorithms will be tried by the RNG protocol. ++// If your platform needs to use a specific algorithm for the random number generator, ++// then you should place that algorithm first in the array. ++// ++GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID *mSecureHashAlgorithms[] = { ++ &gEfiRngAlgorithmSp80090Ctr256Guid, // SP800-90A DRBG CTR using AES-256 ++ &gEfiRngAlgorithmSp80090Hmac256Guid, // SP800-90A DRBG HMAC using SHA-256 ++ &gEfiRngAlgorithmSp80090Hash256Guid, // SP800-90A DRBG Hash using SHA-256 ++ &gEfiRngAlgorithmArmRndr, // unspecified SP800-90A DRBG via ARM RNDR register ++ &gEfiRngAlgorithmRaw, // Raw data from NRBG (or TRNG) ++}; ++ ++#define SECURE_HASH_ALGORITHMS_SIZE (sizeof (mSecureHashAlgorithms) / sizeof (EFI_GUID *)) ++ + /** + Locate the handles that support SNP, then open one of them + to send the syslog packets. The caller isn't required to close +@@ -884,34 +905,107 @@ Ip6Swap128 ( + } + + /** +- Initialize a random seed using current time and monotonic count. ++ Generate a Random output data given a length. + +- Get current time and monotonic count first. Then initialize a random seed +- based on some basic mathematics operation on the hour, day, minute, second, +- nanosecond and year of the current time and the monotonic count value. ++ @param[out] Output - The buffer to store the generated random data. ++ @param[in] OutputLength - The length of the output buffer. + +- @return The random seed initialized with current time. ++ @retval EFI_SUCCESS On Success ++ @retval EFI_INVALID_PARAMETER Pointer is null or size is zero ++ @retval EFI_NOT_FOUND RNG protocol not found ++ @retval Others Error from RngProtocol->GetRNG() + ++ @return Status code + **/ +-UINT32 ++EFI_STATUS + EFIAPI +-NetRandomInitSeed ( +- VOID ++PseudoRandom ( ++ OUT VOID *Output, ++ IN UINTN OutputLength + ) + { +- EFI_TIME Time; +- UINT32 Seed; +- UINT64 MonotonicCount; ++ EFI_RNG_PROTOCOL *RngProtocol; ++ EFI_STATUS Status; ++ UINTN AlgorithmIndex; ++ ++ if ((Output == NULL) || (OutputLength == 0)) { ++ return EFI_INVALID_PARAMETER; ++ } ++ ++ Status = gBS->LocateProtocol (&gEfiRngProtocolGuid, NULL, (VOID **)&RngProtocol); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "Failed to locate EFI_RNG_PROTOCOL: %r\n", Status)); ++ ASSERT_EFI_ERROR (Status); ++ return Status; ++ } ++ ++ if (PcdGetBool (PcdEnforceSecureRngAlgorithms)) { ++ for (AlgorithmIndex = 0; AlgorithmIndex < SECURE_HASH_ALGORITHMS_SIZE; AlgorithmIndex++) { ++ Status = RngProtocol->GetRNG (RngProtocol, mSecureHashAlgorithms[AlgorithmIndex], OutputLength, (UINT8 *)Output); ++ if (!EFI_ERROR (Status)) { ++ // ++ // Secure Algorithm was supported on this platform ++ // ++ return EFI_SUCCESS; ++ } else if (Status == EFI_UNSUPPORTED) { ++ // ++ // Secure Algorithm was not supported on this platform ++ // ++ DEBUG ((DEBUG_ERROR, "Failed to generate random data using secure algorithm %d: %r\n", AlgorithmIndex, Status)); ++ ++ // ++ // Try the next secure algorithm ++ // ++ continue; ++ } else { ++ // ++ // Some other error occurred ++ // ++ DEBUG ((DEBUG_ERROR, "Failed to generate random data using secure algorithm %d: %r\n", AlgorithmIndex, Status)); ++ ASSERT_EFI_ERROR (Status); ++ return Status; ++ } ++ } ++ ++ // ++ // If we get here, we failed to generate random data using any secure algorithm ++ // Platform owner should ensure that at least one secure algorithm is supported ++ // ++ ASSERT_EFI_ERROR (Status); ++ return Status; ++ } ++ ++ // ++ // Lets try using the default algorithm (which may not be secure) ++ // ++ Status = RngProtocol->GetRNG (RngProtocol, NULL, OutputLength, (UINT8 *)Output); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%a failed to generate random data: %r\n", __func__, Status)); ++ ASSERT_EFI_ERROR (Status); ++ return Status; ++ } + +- gRT->GetTime (&Time, NULL); +- Seed = (Time.Hour << 24 | Time.Day << 16 | Time.Minute << 8 | Time.Second); +- Seed ^= Time.Nanosecond; +- Seed ^= Time.Year << 7; ++ return EFI_SUCCESS; ++} ++ ++/** ++ Generate a 32-bit pseudo-random number. + +- gBS->GetNextMonotonicCount (&MonotonicCount); +- Seed += (UINT32)MonotonicCount; ++ @param[out] Output - The buffer to store the generated random number. + +- return Seed; ++ @retval EFI_SUCCESS On Success ++ @retval EFI_NOT_FOUND RNG protocol not found ++ @retval Others Error from RngProtocol->GetRNG() ++ ++ @return Status code ++**/ ++EFI_STATUS ++EFIAPI ++PseudoRandomU32 ( ++ OUT UINT32 *Output ++ ) ++{ ++ return PseudoRandom (Output, sizeof (*Output)); + } + + /** +diff --git a/NetworkPkg/Library/DxeNetLib/DxeNetLib.inf b/NetworkPkg/Library/DxeNetLib/DxeNetLib.inf +index 8145d25..a8f534a 100644 +--- a/NetworkPkg/Library/DxeNetLib/DxeNetLib.inf ++++ b/NetworkPkg/Library/DxeNetLib/DxeNetLib.inf +@@ -3,6 +3,7 @@ + # + # Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+ # (C) Copyright 2015 Hewlett Packard Enterprise Development LP
++# Copyright (c) Microsoft Corporation + # SPDX-License-Identifier: BSD-2-Clause-Patent + # + ## +@@ -49,7 +50,11 @@ + gEfiSmbiosTableGuid ## SOMETIMES_CONSUMES ## SystemTable + gEfiSmbios3TableGuid ## SOMETIMES_CONSUMES ## SystemTable + gEfiAdapterInfoMediaStateGuid ## SOMETIMES_CONSUMES +- ++ gEfiRngAlgorithmRaw ## CONSUMES ++ gEfiRngAlgorithmSp80090Ctr256Guid ## CONSUMES ++ gEfiRngAlgorithmSp80090Hmac256Guid ## CONSUMES ++ gEfiRngAlgorithmSp80090Hash256Guid ## CONSUMES ++ gEfiRngAlgorithmArmRndr ## CONSUMES + + [Protocols] + gEfiSimpleNetworkProtocolGuid ## SOMETIMES_CONSUMES +@@ -59,3 +64,10 @@ + gEfiComponentNameProtocolGuid ## SOMETIMES_CONSUMES + gEfiComponentName2ProtocolGuid ## SOMETIMES_CONSUMES + gEfiAdapterInformationProtocolGuid ## SOMETIMES_CONSUMES ++ gEfiRngProtocolGuid ## CONSUMES ++ ++[FixedPcd] ++ gEfiNetworkPkgTokenSpaceGuid.PcdEnforceSecureRngAlgorithms ## CONSUMES ++ ++[Depex] ++ gEfiRngProtocolGuid +diff --git a/NetworkPkg/NetworkPkg.dec b/NetworkPkg/NetworkPkg.dec +index e06f35e..7c4289b 100644 +--- a/NetworkPkg/NetworkPkg.dec ++++ b/NetworkPkg/NetworkPkg.dec +@@ -5,6 +5,7 @@ + # + # Copyright (c) 2009 - 2021, Intel Corporation. All rights reserved.
+ # (C) Copyright 2015-2020 Hewlett Packard Enterprise Development LP
++# Copyright (c) Microsoft Corporation + # + # SPDX-License-Identifier: BSD-2-Clause-Patent + # +@@ -130,6 +131,12 @@ + # @Prompt Indicates whether SnpDxe creates event for ExitBootServices() call. + gEfiNetworkPkgTokenSpaceGuid.PcdSnpCreateExitBootServicesEvent|TRUE|BOOLEAN|0x1000000C + ++ ## Enforces the use of Secure UEFI spec defined RNG algorithms for all network connections. ++ # TRUE - Enforce the use of Secure UEFI spec defined RNG algorithms. ++ # FALSE - Do not enforce and depend on the default implementation of RNG algorithm from the provider. ++ # @Prompt Enforce the use of Secure UEFI spec defined RNG algorithms. ++ gEfiNetworkPkgTokenSpaceGuid.PcdEnforceSecureRngAlgorithms|TRUE|BOOLEAN|0x1000000D ++ + [PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx] + ## IPv6 DHCP Unique Identifier (DUID) Type configuration (From RFCs 3315 and 6355). + # 01 = DUID Based on Link-layer Address Plus Time [DUID-LLT] +diff --git a/NetworkPkg/TcpDxe/TcpDriver.c b/NetworkPkg/TcpDxe/TcpDriver.c +index 98a90e0..8fe6bad 100644 +--- a/NetworkPkg/TcpDxe/TcpDriver.c ++++ b/NetworkPkg/TcpDxe/TcpDriver.c +@@ -2,7 +2,7 @@ + The driver binding and service binding protocol for the TCP driver. + + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+- ++ Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + + **/ +@@ -163,7 +163,13 @@ TcpDriverEntryPoint ( + ) + { + EFI_STATUS Status; +- UINT32 Seed; ++ UINT32 Random; ++ ++ Status = PseudoRandomU32 (&Random); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%a Failed to generate random number: %r\n", __func__, Status)); ++ return Status; ++ } + + // + // Install the TCP Driver Binding Protocol +@@ -203,9 +209,8 @@ TcpDriverEntryPoint ( + // + // Initialize ISS and random port. + // +- Seed = NetRandomInitSeed (); +- mTcpGlobalIss = NET_RANDOM (Seed) % mTcpGlobalIss; +- mTcp4RandomPort = (UINT16)(TCP_PORT_KNOWN + (NET_RANDOM (Seed) % TCP_PORT_KNOWN)); ++ mTcpGlobalIss = Random % mTcpGlobalIss; ++ mTcp4RandomPort = (UINT16)(TCP_PORT_KNOWN + (Random % TCP_PORT_KNOWN)); + mTcp6RandomPort = mTcp4RandomPort; + + return EFI_SUCCESS; +diff --git a/NetworkPkg/TcpDxe/TcpDxe.inf b/NetworkPkg/TcpDxe/TcpDxe.inf +index c0acbdc..cf5423f 100644 +--- a/NetworkPkg/TcpDxe/TcpDxe.inf ++++ b/NetworkPkg/TcpDxe/TcpDxe.inf +@@ -82,5 +82,8 @@ + gEfiTcp6ProtocolGuid ## BY_START + gEfiTcp6ServiceBindingProtocolGuid ## BY_START + ++[Depex] ++ gEfiHash2ServiceBindingProtocolGuid ++ + [UserExtensions.TianoCore."ExtraFiles"] + TcpDxeExtra.uni +diff --git a/NetworkPkg/Udp4Dxe/Udp4Driver.c b/NetworkPkg/Udp4Dxe/Udp4Driver.c +index cb917fc..c7ea16f 100644 +--- a/NetworkPkg/Udp4Dxe/Udp4Driver.c ++++ b/NetworkPkg/Udp4Dxe/Udp4Driver.c +@@ -1,6 +1,7 @@ + /** @file + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
++Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + + **/ +@@ -555,6 +556,13 @@ Udp4DriverEntryPoint ( + ) + { + EFI_STATUS Status; ++ UINT32 Random; ++ ++ Status = PseudoRandomU32 (&Random); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status)); ++ return Status; ++ } + + // + // Install the Udp4DriverBinding and Udp4ComponentName protocols. +@@ -571,7 +579,7 @@ Udp4DriverEntryPoint ( + // + // Initialize the UDP random port. + // +- mUdp4RandomPort = (UINT16)(((UINT16)NetRandomInitSeed ()) % UDP4_PORT_KNOWN + UDP4_PORT_KNOWN); ++ mUdp4RandomPort = (UINT16)(((UINT16)Random) % UDP4_PORT_KNOWN + UDP4_PORT_KNOWN); + } + + return Status; +diff --git a/NetworkPkg/Udp6Dxe/Udp6Driver.c b/NetworkPkg/Udp6Dxe/Udp6Driver.c +index ae96fb9..edb758d 100644 +--- a/NetworkPkg/Udp6Dxe/Udp6Driver.c ++++ b/NetworkPkg/Udp6Dxe/Udp6Driver.c +@@ -2,7 +2,7 @@ + Driver Binding functions and Service Binding functions for the Network driver module. + + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+- ++ Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + + **/ +@@ -596,6 +596,13 @@ Udp6DriverEntryPoint ( + ) + { + EFI_STATUS Status; ++ UINT32 Random; ++ ++ Status = PseudoRandomU32 (&Random); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status)); ++ return Status; ++ } + + // + // Install the Udp6DriverBinding and Udp6ComponentName protocols. +@@ -614,7 +621,7 @@ Udp6DriverEntryPoint ( + // Initialize the UDP random port. + // + mUdp6RandomPort = (UINT16)( +- ((UINT16)NetRandomInitSeed ()) % ++ ((UINT16)Random) % + UDP6_PORT_KNOWN + + UDP6_PORT_KNOWN + ); +diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c +index 91146b7..452038c 100644 +--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c ++++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c +@@ -2,7 +2,7 @@ + Functions implementation related with DHCPv4 for UefiPxeBc Driver. + + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+- ++ Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + + **/ +@@ -1381,6 +1381,12 @@ PxeBcDhcp4Discover ( + UINT8 VendorOptLen; + UINT32 Xid; + ++ Status = PseudoRandomU32 (&Xid); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status)); ++ return Status; ++ } ++ + Mode = Private->PxeBc.Mode; + Dhcp4 = Private->Dhcp4; + Status = EFI_SUCCESS; +@@ -1471,7 +1477,6 @@ PxeBcDhcp4Discover ( + // + // Set fields of the token for the request packet. + // +- Xid = NET_RANDOM (NetRandomInitSeed ()); + Token.Packet->Dhcp4.Header.Xid = HTONL (Xid); + Token.Packet->Dhcp4.Header.Reserved = HTONS ((UINT16)((IsBCast) ? 0x8000 : 0x0)); + CopyMem (&Token.Packet->Dhcp4.Header.ClientAddr, &Private->StationIp, sizeof (EFI_IPv4_ADDRESS)); +diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c +index 7fd1281..bcabbd2 100644 +--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c ++++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c +@@ -2180,7 +2180,7 @@ PxeBcDhcp6Discover ( + UINTN ReadSize; + UINT16 OpCode; + UINT16 OpLen; +- UINT32 Xid; ++ UINT32 Random; + EFI_STATUS Status; + UINTN DiscoverLenNeeded; + +@@ -2198,6 +2198,12 @@ PxeBcDhcp6Discover ( + return EFI_DEVICE_ERROR; + } + ++ Status = PseudoRandomU32 (&Random); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status)); ++ return Status; ++ } ++ + DiscoverLenNeeded = sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET); + Discover = AllocateZeroPool (DiscoverLenNeeded); + if (Discover == NULL) { +@@ -2207,8 +2213,7 @@ PxeBcDhcp6Discover ( + // + // Build the discover packet by the cached request packet before. + // +- Xid = NET_RANDOM (NetRandomInitSeed ()); +- Discover->TransactionId = HTONL (Xid); ++ Discover->TransactionId = HTONL (Random); + Discover->MessageType = Request->Dhcp6.Header.MessageType; + RequestOpt = Request->Dhcp6.Option; + DiscoverOpt = Discover->DhcpOptions; +diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c +index d84aca7..4cd915b 100644 +--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c ++++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c +@@ -3,6 +3,7 @@ + + (C) Copyright 2014 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.
++ Copyright (c) Microsoft Corporation + + SPDX-License-Identifier: BSD-2-Clause-Patent + +@@ -892,6 +893,13 @@ PxeBcCreateIp6Children ( + PXEBC_PRIVATE_PROTOCOL *Id; + EFI_SIMPLE_NETWORK_PROTOCOL *Snp; + UINTN Index; ++ UINT32 Random; ++ ++ Status = PseudoRandomU32 (&Random); ++ if (EFI_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "Failed to generate random number using EFI_RNG_PROTOCOL: %r\n", Status)); ++ return Status; ++ } + + if (Private->Ip6Nic != NULL) { + // +@@ -935,9 +943,9 @@ PxeBcCreateIp6Children ( + } + + // +- // Generate a random IAID for the Dhcp6 assigned address. ++ // Set a random IAID for the Dhcp6 assigned address. + // +- Private->IaId = NET_RANDOM (NetRandomInitSeed ()); ++ Private->IaId = Random; + if (Private->Snp != NULL) { + for (Index = 0; Index < Private->Snp->Mode->HwAddressSize; Index++) { + Private->IaId |= (Private->Snp->Mode->CurrentAddress.Addr[Index] << ((Index << 3) & 31)); +diff --git a/SecurityPkg/SecurityFixes.yaml b/SecurityPkg/SecurityFixes.yaml +index b4006b4..04aa6a3 100644 +--- a/SecurityPkg/SecurityFixes.yaml ++++ b/SecurityPkg/SecurityFixes.yaml +@@ -40,3 +40,42 @@ CVE_2022_36764: + - Library\DxeTpmMeasureBootLib\DxeTpmMeasureBootLib.c + links: + - https://bugzilla.tianocore.org/show_bug.cgi?id=4118 ++CVE_2023_45237: ++ commit_titles: ++ - "NetworkPkg:: SECURITY PATCH CVE 2023-45237" ++ cve: CVE-2023-45237 ++ date_reported: 2023-08-28 13:56 UTC ++ description: "Bug 09 - Use of a Weak PseudoRandom Number Generator" ++ note: ++ files_impacted: ++ - NetworkPkg/Dhcp4Dxe/Dhcp4Driver.c ++ - NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c ++ - NetworkPkg/DnsDxe/DnsDhcp.c ++ - NetworkPkg/DnsDxe/DnsImpl.c ++ - NetworkPkg/HttpBootDxe/HttpBootDhcp6.c ++ - NetworkPkg/IScsiDxe/IScsiCHAP.c ++ - NetworkPkg/IScsiDxe/IScsiMisc.c ++ - NetworkPkg/IScsiDxe/IScsiMisc.h ++ - NetworkPkg/Include/Library/NetLib.h ++ - NetworkPkg/Ip4Dxe/Ip4Driver.c ++ - NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c ++ - NetworkPkg/Ip6Dxe/Ip6Driver.c ++ - NetworkPkg/Ip6Dxe/Ip6If.c ++ - NetworkPkg/Ip6Dxe/Ip6Mld.c ++ - NetworkPkg/Ip6Dxe/Ip6Nd.c ++ - NetworkPkg/Ip6Dxe/Ip6Nd.h ++ - NetworkPkg/Library/DxeNetLib/DxeNetLib.c ++ - NetworkPkg/Library/DxeNetLib/DxeNetLib.inf ++ - NetworkPkg/NetworkPkg.dec ++ - NetworkPkg/TcpDxe/TcpDriver.c ++ - NetworkPkg/Udp4Dxe/Udp4Driver.c ++ - NetworkPkg/Udp6Dxe/Udp6Driver.c ++ - NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c ++ - NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c ++ - NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c ++ links: ++ - https://bugzilla.tianocore.org/show_bug.cgi?id=4542 ++ - https://nvd.nist.gov/vuln/detail/CVE-2023-45237 ++ - http://www.openwall.com/lists/oss-security/2024/01/16/2 ++ - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html ++ - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html +\ No newline at end of file +-- +2.25.1 + + +From 95d3dee98112460c0940ff390e36101c4528331d Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Thu, 19 Sep 2024 19:20:54 -0700 +Subject: [PATCH 2/2] add changes for CVE-2023-45237 + +--- + MdePkg/MdePkg.dec | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec +index 80b6559..9cfd89a 100644 +--- a/MdePkg/MdePkg.dec ++++ b/MdePkg/MdePkg.dec +@@ -624,6 +624,7 @@ + gEfiRngAlgorithmX9313DesGuid = { 0x63c4785a, 0xca34, 0x4012, {0xa3, 0xc8, 0x0b, 0x6a, 0x32, 0x4f, 0x55, 0x46 }} + gEfiRngAlgorithmX931AesGuid = { 0xacd03321, 0x777e, 0x4d3d, {0xb1, 0xc8, 0x20, 0xcf, 0xd8, 0x88, 0x20, 0xc9 }} + gEfiRngAlgorithmRaw = { 0xe43176d7, 0xb6e8, 0x4827, {0xb7, 0x84, 0x7f, 0xfd, 0xc4, 0xb6, 0x85, 0x61 }} ++ gEfiRngAlgorithmArmRndr = { 0x43d2fde3, 0x9d4e, 0x4d79, {0x02, 0x96, 0xa8, 0x9b, 0xca, 0x78, 0x08, 0x41 }} + + ## Include/Protocol/AdapterInformation.h + gEfiAdapterInfoMediaStateGuid = { 0xD7C74207, 0xA831, 0x4A26, {0xB1, 0xF5, 0xD1, 0x93, 0x06, 0x5C, 0xE8, 0xB6 }} +-- +2.25.1 + diff --git a/SPECS/edk2/edk2.spec b/SPECS/edk2/edk2.spec index 64546561091..9430867be69 100644 --- a/SPECS/edk2/edk2.spec +++ b/SPECS/edk2/edk2.spec @@ -45,7 +45,7 @@ ExclusiveArch: x86_64 Name: edk2 Version: %{GITDATE}git%{GITCOMMIT} -Release: 39%{?dist} +Release: 40%{?dist} Summary: UEFI firmware for 64-bit virtual machines License: BSD-2-Clause-Patent and OpenSSL and MIT URL: http://www.tianocore.org @@ -109,6 +109,17 @@ Patch0015: 0015-SecurityPkg-add-TIS-sanity-check-tpm12.patch Patch0016: 0016-OvmfPkg-Clarify-invariants-for-NestedInterruptTplLib.patch Patch0017: 0017-OvmfPkg-Relax-assertion-that-interrupts-do-not-occur.patch Patch0018: CVE-2024-1298.patch +Patch0019: CVE-2022-36763.patch +# This patch is need for CVE-2022-36763 to resolve the tpm1 and tpm2 build conflicts +# See https://edk2.groups.io/g/devel/topic/patch_0_6_security_patches/103675434 +Patch0020: fix-tpm-build-issue-from-CVE-2022-36763.patch +Patch0021: CVE-2022-36765.patch +Patch0022: CVE-2023-45230.patch +Patch0023: CVE-2023-45232.patch +Patch0024: CVE-2023-45234.patch +Patch0025: CVE-2023-45235.patch +Patch0026: CVE-2023-45237.patch +Patch0027: CVE-2023-45236.patch Patch1000: CVE-2023-0464.patch Patch1001: CVE-2023-3817.patch @@ -700,6 +711,11 @@ $tests_ok %changelog +* Mon Sep 16 2024 Minghe Ren - 20230301gitf80f052277c8-40 +- Add CVE-2022-36763, CVE-2022-36765, CVE-2023-45230, CVE-2023-45232, CVE-2023-45234, CVE-2023-45235, CVE-2023-45236, CVE-2023-45237 patch +- Add fix-tpm-build-issue-from-CVE-2022-36763.patch +- Add nopatch for CVE-2022-36764, CVE-2023-45233 + * Thu Jun 06 2024 Archana Choudhary - 20230301gitf80f052277c8-39 - Apply CVE-2024-1298 patch @@ -709,7 +725,7 @@ $tests_ok * Tue Oct 17 2023 Francisco Huelsz Prince - 20230301gitf80f052277c8-37 - Patch CVE-2023-0465 and CVE-2023-2650 in bundled OpenSSL. -* Tue Oct 13 2023 Sindhu Karri - 20230301gitf80f052277c8-36 +* Fri Oct 13 2023 Sindhu Karri - 20230301gitf80f052277c8-36 - Patch CVE-2023-3817 in bundled OpenSSL * Tue Sep 26 2023 Pawel Winogrodzki - 20230301gitf80f052277c8-35 diff --git a/SPECS/edk2/fix-tpm-build-issue-from-CVE-2022-36763.patch b/SPECS/edk2/fix-tpm-build-issue-from-CVE-2022-36763.patch new file mode 100644 index 00000000000..18d371afc33 --- /dev/null +++ b/SPECS/edk2/fix-tpm-build-issue-from-CVE-2022-36763.patch @@ -0,0 +1,593 @@ +From 1f24cdf5ba0950e9f92e29b0fd041e4c2441ad56 Mon Sep 17 00:00:00 2001 +From: Doug Flick +Date: Wed, 17 Jan 2024 14:47:20 -0800 +Subject: [PATCH 1/3] SecurityPkg: DxeTpm2MeasureBootLib: SECURITY PATCH + 4117/4118 symbol rename + +Updates the sanitation function names to be lib unique names + +Cc: Jiewen Yao +Cc: Rahul Kumar + +Signed-off-by: Doug Flick [MSFT] +Message-Id: <7b18434c8a8b561654efd40ced3becb8b378c8f1.1705529990.git.doug.edk2@gmail.com> +Reviewed-by: Jiewen Yao +--- + .../DxeTpm2MeasureBootLib.c | 8 +++--- + .../DxeTpm2MeasureBootLibSanitization.c | 8 +++--- + .../DxeTpm2MeasureBootLibSanitization.h | 8 +++--- + .../DxeTpm2MeasureBootLibSanitizationTest.c | 26 +++++++++---------- + 4 files changed, 25 insertions(+), 25 deletions(-) + +This patch is need for CVE-2022-36763 to resolve the tpm1 and tpm2 build conflicts. +See details: +https://edk2.groups.io/g/devel/topic/patch_0_6_security_patches/103675434 +https://edk2.groups.io/g/devel/topic/103797461#msg113966 + +diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c +index 714cc8e..73719f3 100644 +--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c ++++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c +@@ -200,7 +200,7 @@ Tcg2MeasureGptTable ( + BlockIo->Media->BlockSize, + (UINT8 *)PrimaryHeader + ); +- if (EFI_ERROR (Status) || EFI_ERROR (SanitizeEfiPartitionTableHeader (PrimaryHeader, BlockIo))) { ++ if (EFI_ERROR (Status) || EFI_ERROR (Tpm2SanitizeEfiPartitionTableHeader (PrimaryHeader, BlockIo))) { + DEBUG ((DEBUG_ERROR, "Failed to read Partition Table Header or invalid Partition Table Header!\n")); + FreePool (PrimaryHeader); + return EFI_DEVICE_ERROR; +@@ -209,7 +209,7 @@ Tcg2MeasureGptTable ( + // + // Read the partition entry. + // +- Status = SanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSize); ++ Status = Tpm2SanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSize); + if (EFI_ERROR (Status)) { + FreePool (PrimaryHeader); + return EFI_BAD_BUFFER_SIZE; +@@ -250,7 +250,7 @@ Tcg2MeasureGptTable ( + // + // Prepare Data for Measurement (CcProtocol and Tcg2Protocol) + // +- Status = SanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfPartition, &TcgEventSize); ++ Status = Tpm2SanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfPartition, &TcgEventSize); + if (EFI_ERROR (Status)) { + FreePool (PrimaryHeader); + FreePool (EntryPtr); +@@ -420,7 +420,7 @@ Tcg2MeasurePeImage ( + } + + FilePathSize = (UINT32)GetDevicePathSize (FilePath); +- Status = SanitizePeImageEventSize (FilePathSize, &EventSize); ++ Status = Tpm2SanitizePeImageEventSize (FilePathSize, &EventSize); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } +diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c +index 2a4d52c..809a3bf 100644 +--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c ++++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c +@@ -63,7 +63,7 @@ + **/ + EFI_STATUS + EFIAPI +-SanitizeEfiPartitionTableHeader ( ++Tpm2SanitizeEfiPartitionTableHeader ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo + ) +@@ -169,7 +169,7 @@ SanitizeEfiPartitionTableHeader ( + **/ + EFI_STATUS + EFIAPI +-SanitizePrimaryHeaderAllocationSize ( ++Tpm2SanitizePrimaryHeaderAllocationSize ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + OUT UINT32 *AllocationSize + ) +@@ -221,7 +221,7 @@ SanitizePrimaryHeaderAllocationSize ( + One of the passed parameters was invalid. + **/ + EFI_STATUS +-SanitizePrimaryHeaderGptEventSize ( ++Tpm2SanitizePrimaryHeaderGptEventSize ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + IN UINTN NumberOfPartition, + OUT UINT32 *EventSize +@@ -292,7 +292,7 @@ SanitizePrimaryHeaderGptEventSize ( + One of the passed parameters was invalid. + **/ + EFI_STATUS +-SanitizePeImageEventSize ( ++Tpm2SanitizePeImageEventSize ( + IN UINT32 FilePathSize, + OUT UINT32 *EventSize + ) +diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h +index 8f72ba4..8526bc7 100644 +--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h ++++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h +@@ -54,7 +54,7 @@ + **/ + EFI_STATUS + EFIAPI +-SanitizeEfiPartitionTableHeader ( ++Tpm2SanitizeEfiPartitionTableHeader ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo + ); +@@ -78,7 +78,7 @@ SanitizeEfiPartitionTableHeader ( + **/ + EFI_STATUS + EFIAPI +-SanitizePrimaryHeaderAllocationSize ( ++Tpm2SanitizePrimaryHeaderAllocationSize ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + OUT UINT32 *AllocationSize + ); +@@ -107,7 +107,7 @@ SanitizePrimaryHeaderAllocationSize ( + One of the passed parameters was invalid. + **/ + EFI_STATUS +-SanitizePrimaryHeaderGptEventSize ( ++Tpm2SanitizePrimaryHeaderGptEventSize ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + IN UINTN NumberOfPartition, + OUT UINT32 *EventSize +@@ -131,7 +131,7 @@ SanitizePrimaryHeaderGptEventSize ( + One of the passed parameters was invalid. + **/ + EFI_STATUS +-SanitizePeImageEventSize ( ++Tpm2SanitizePeImageEventSize ( + IN UINT32 FilePathSize, + OUT UINT32 *EventSize + ); +diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c +index 820e99a..50a68e1 100644 +--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c ++++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c +@@ -84,27 +84,27 @@ TestSanitizeEfiPartitionTableHeader ( + PrimaryHeader.Header.CRC32 = CalculateCrc32 ((UINT8 *)&PrimaryHeader, PrimaryHeader.Header.HeaderSize); + + // Test that a normal PrimaryHeader passes validation +- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ Status = Tpm2SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // Test that when number of partition entries is 0, the function returns EFI_DEVICE_ERROR + // Should print "Invalid Partition Table Header NumberOfPartitionEntries!"" + PrimaryHeader.NumberOfPartitionEntries = 0; +- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ Status = Tpm2SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); + UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); + PrimaryHeader.NumberOfPartitionEntries = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; + + // Test that when the header size is too small, the function returns EFI_DEVICE_ERROR + // Should print "Invalid Partition Table Header Size!" + PrimaryHeader.Header.HeaderSize = 0; +- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ Status = Tpm2SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); + UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); + PrimaryHeader.Header.HeaderSize = sizeof (EFI_PARTITION_TABLE_HEADER); + + // Test that when the SizeOfPartitionEntry is too small, the function returns EFI_DEVICE_ERROR + // should print: "SizeOfPartitionEntry shall be set to a value of 128 x 2^n where n is an integer greater than or equal to zero (e.g., 128, 256, 512, etc.)!" + PrimaryHeader.SizeOfPartitionEntry = 1; +- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ Status = Tpm2SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); + UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); + + DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); +@@ -137,7 +137,7 @@ TestSanitizePrimaryHeaderAllocationSize ( + PrimaryHeader.NumberOfPartitionEntries = 5; + PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; + +- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ Status = Tpm2SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // Test that the allocation size is correct compared to the existing logic +@@ -146,19 +146,19 @@ TestSanitizePrimaryHeaderAllocationSize ( + // Test that an overflow is detected + PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32; + PrimaryHeader.SizeOfPartitionEntry = 5; +- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ Status = Tpm2SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + // Test the inverse + PrimaryHeader.NumberOfPartitionEntries = 5; + PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; +- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ Status = Tpm2SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + // Test the worst case scenario + PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32; + PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; +- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ Status = Tpm2SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); +@@ -196,7 +196,7 @@ TestSanitizePrimaryHeaderGptEventSize ( + NumberOfPartition = 13; + + // that the primary event size is correct +- Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); ++ Status = Tpm2SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // Calculate the existing logic event size +@@ -207,12 +207,12 @@ TestSanitizePrimaryHeaderGptEventSize ( + UT_ASSERT_EQUAL (EventSize, ExistingLogicEventSize); + + // Tests that the primary event size may not overflow +- Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, MAX_UINT32, &EventSize); ++ Status = Tpm2SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, MAX_UINT32, &EventSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + // Test that the size of partition entries may not overflow + PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; +- Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); ++ Status = Tpm2SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); +@@ -245,7 +245,7 @@ TestSanitizePeImageEventSize ( + FilePathSize = 255; + + // Test that a normal PE image passes validation +- Status = SanitizePeImageEventSize (FilePathSize, &EventSize); ++ Status = Tpm2SanitizePeImageEventSize (FilePathSize, &EventSize); + UT_ASSERT_EQUAL (Status, EFI_SUCCESS); + + // Test that the event size is correct compared to the existing logic +@@ -258,7 +258,7 @@ TestSanitizePeImageEventSize ( + } + + // Test that the event size may not overflow +- Status = SanitizePeImageEventSize (MAX_UINT32, &EventSize); ++ Status = Tpm2SanitizePeImageEventSize (MAX_UINT32, &EventSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); +-- +2.25.1 + + +From e00ef8ed668d2e658e45a9b8b530ccec263c7e20 Mon Sep 17 00:00:00 2001 +From: Doug Flick +Date: Wed, 17 Jan 2024 14:47:21 -0800 +Subject: [PATCH 2/3] SecurityPkg: DxeTpmMeasureBootLib: SECURITY PATCH + 4117/4118 symbol rename + +Updates the sanitation function names to be lib unique names + +Cc: Jiewen Yao +Cc: Rahul Kumar + +Signed-off-by: Doug Flick [MSFT] +Message-Id: <355aa846a99ca6ac0f7574cf5982661da0d9fea6.1705529990.git.doug.edk2@gmail.com> +Reviewed-by: Jiewen Yao +--- + .../DxeTpmMeasureBootLib.c | 8 +++--- + .../DxeTpmMeasureBootLibSanitization.c | 10 +++---- + .../DxeTpmMeasureBootLibSanitization.h | 8 +++--- + .../DxeTpmMeasureBootLibSanitizationTest.c | 26 +++++++++---------- + 4 files changed, 26 insertions(+), 26 deletions(-) + +diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c +index a9fc440..ac855b8 100644 +--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c ++++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c +@@ -174,7 +174,7 @@ TcgMeasureGptTable ( + BlockIo->Media->BlockSize, + (UINT8 *)PrimaryHeader + ); +- if (EFI_ERROR (Status) || EFI_ERROR (SanitizeEfiPartitionTableHeader (PrimaryHeader, BlockIo))) { ++ if (EFI_ERROR (Status) || EFI_ERROR (TpmSanitizeEfiPartitionTableHeader (PrimaryHeader, BlockIo))) { + DEBUG ((DEBUG_ERROR, "Failed to read Partition Table Header or invalid Partition Table Header!\n")); + FreePool (PrimaryHeader); + return EFI_DEVICE_ERROR; +@@ -183,7 +183,7 @@ TcgMeasureGptTable ( + // + // Read the partition entry. + // +- Status = SanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSize); ++ Status = TpmSanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSize); + if (EFI_ERROR (Status)) { + FreePool (PrimaryHeader); + return EFI_DEVICE_ERROR; +@@ -224,7 +224,7 @@ TcgMeasureGptTable ( + // + // Prepare Data for Measurement + // +- Status = SanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfPartition, &EventSize); ++ Status = TpmSanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfPartition, &EventSize); + TcgEvent = (TCG_PCR_EVENT *)AllocateZeroPool (EventSize); + if (TcgEvent == NULL) { + FreePool (PrimaryHeader); +@@ -351,7 +351,7 @@ TcgMeasurePeImage ( + + // Determine destination PCR by BootPolicy + // +- Status = SanitizePeImageEventSize (FilePathSize, &EventSize); ++ Status = TpmSanitizePeImageEventSize (FilePathSize, &EventSize); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } +diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c +index c989851..070e4a2 100644 +--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c ++++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c +@@ -1,5 +1,5 @@ + /** @file +- The library instance provides security service of TPM2 measure boot and ++ The library instance provides security service of TPM measure boot and + Confidential Computing (CC) measure boot. + + Caution: This file requires additional review when modified. +@@ -63,7 +63,7 @@ + **/ + EFI_STATUS + EFIAPI +-SanitizeEfiPartitionTableHeader ( ++TpmSanitizeEfiPartitionTableHeader ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo + ) +@@ -145,7 +145,7 @@ SanitizeEfiPartitionTableHeader ( + **/ + EFI_STATUS + EFIAPI +-SanitizePrimaryHeaderAllocationSize ( ++TpmSanitizePrimaryHeaderAllocationSize ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + OUT UINT32 *AllocationSize + ) +@@ -194,7 +194,7 @@ SanitizePrimaryHeaderAllocationSize ( + One of the passed parameters was invalid. + **/ + EFI_STATUS +-SanitizePrimaryHeaderGptEventSize ( ++TpmSanitizePrimaryHeaderGptEventSize ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + IN UINTN NumberOfPartition, + OUT UINT32 *EventSize +@@ -258,7 +258,7 @@ SanitizePrimaryHeaderGptEventSize ( + One of the passed parameters was invalid. + **/ + EFI_STATUS +-SanitizePeImageEventSize ( ++TpmSanitizePeImageEventSize ( + IN UINT32 FilePathSize, + OUT UINT32 *EventSize + ) +diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h +index 2248495..db6e9c3 100644 +--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h ++++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h +@@ -53,7 +53,7 @@ + **/ + EFI_STATUS + EFIAPI +-SanitizeEfiPartitionTableHeader ( ++TpmSanitizeEfiPartitionTableHeader ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo + ); +@@ -77,7 +77,7 @@ SanitizeEfiPartitionTableHeader ( + **/ + EFI_STATUS + EFIAPI +-SanitizePrimaryHeaderAllocationSize ( ++TpmSanitizePrimaryHeaderAllocationSize ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + OUT UINT32 *AllocationSize + ); +@@ -105,7 +105,7 @@ SanitizePrimaryHeaderAllocationSize ( + One of the passed parameters was invalid. + **/ + EFI_STATUS +-SanitizePrimaryHeaderGptEventSize ( ++TpmSanitizePrimaryHeaderGptEventSize ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + IN UINTN NumberOfPartition, + OUT UINT32 *EventSize +@@ -129,7 +129,7 @@ SanitizePrimaryHeaderGptEventSize ( + One of the passed parameters was invalid. + **/ + EFI_STATUS +-SanitizePeImageEventSize ( ++TpmSanitizePeImageEventSize ( + IN UINT32 FilePathSize, + OUT UINT32 *EventSize + ); +diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c +index c41498b..de1740a 100644 +--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c ++++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c +@@ -83,27 +83,27 @@ TestSanitizeEfiPartitionTableHeader ( + PrimaryHeader.Header.CRC32 = CalculateCrc32 ((UINT8 *)&PrimaryHeader, PrimaryHeader.Header.HeaderSize); + + // Test that a normal PrimaryHeader passes validation +- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ Status = TpmSanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // Test that when number of partition entries is 0, the function returns EFI_DEVICE_ERROR + // Should print "Invalid Partition Table Header NumberOfPartitionEntries!"" + PrimaryHeader.NumberOfPartitionEntries = 0; +- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ Status = TpmSanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); + UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); + PrimaryHeader.NumberOfPartitionEntries = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; + + // Test that when the header size is too small, the function returns EFI_DEVICE_ERROR + // Should print "Invalid Partition Table Header Size!" + PrimaryHeader.Header.HeaderSize = 0; +- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ Status = TpmSanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); + UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); + PrimaryHeader.Header.HeaderSize = sizeof (EFI_PARTITION_TABLE_HEADER); + + // Test that when the SizeOfPartitionEntry is too small, the function returns EFI_DEVICE_ERROR + // should print: "SizeOfPartitionEntry shall be set to a value of 128 x 2^n where n is an integer greater than or equal to zero (e.g., 128, 256, 512, etc.)!" + PrimaryHeader.SizeOfPartitionEntry = 1; +- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); ++ Status = TpmSanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); + UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); + + DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); +@@ -136,7 +136,7 @@ TestSanitizePrimaryHeaderAllocationSize ( + PrimaryHeader.NumberOfPartitionEntries = 5; + PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY; + +- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ Status = TpmSanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // Test that the allocation size is correct compared to the existing logic +@@ -145,19 +145,19 @@ TestSanitizePrimaryHeaderAllocationSize ( + // Test that an overflow is detected + PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32; + PrimaryHeader.SizeOfPartitionEntry = 5; +- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ Status = TpmSanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + // Test the inverse + PrimaryHeader.NumberOfPartitionEntries = 5; + PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; +- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ Status = TpmSanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + // Test the worst case scenario + PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32; + PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; +- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); ++ Status = TpmSanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); +@@ -195,7 +195,7 @@ TestSanitizePrimaryHeaderGptEventSize ( + NumberOfPartition = 13; + + // that the primary event size is correct +- Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); ++ Status = TpmSanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // Calculate the existing logic event size +@@ -206,12 +206,12 @@ TestSanitizePrimaryHeaderGptEventSize ( + UT_ASSERT_EQUAL (EventSize, ExistingLogicEventSize); + + // Tests that the primary event size may not overflow +- Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, MAX_UINT32, &EventSize); ++ Status = TpmSanitizePrimaryHeaderGptEventSize (&PrimaryHeader, MAX_UINT32, &EventSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + // Test that the size of partition entries may not overflow + PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32; +- Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); ++ Status = TpmSanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); +@@ -269,7 +269,7 @@ TestSanitizePeImageEventSize ( + FilePathSize = 255; + + // Test that a normal PE image passes validation +- Status = SanitizePeImageEventSize (FilePathSize, &EventSize); ++ Status = TpmSanitizePeImageEventSize (FilePathSize, &EventSize); + if (EFI_ERROR (Status)) { + UT_LOG_ERROR ("SanitizePeImageEventSize failed with %r\n", Status); + goto Exit; +@@ -285,7 +285,7 @@ TestSanitizePeImageEventSize ( + } + + // Test that the event size may not overflow +- Status = SanitizePeImageEventSize (MAX_UINT32, &EventSize); ++ Status = TpmSanitizePeImageEventSize (MAX_UINT32, &EventSize); + if (Status != EFI_BAD_BUFFER_SIZE) { + UT_LOG_ERROR ("SanitizePeImageEventSize succeded when it was supposed to fail with %r\n", Status); + goto Exit; +-- +2.25.1 + + +From fa7a1c6946d9c2abeb74f4e6620d6425b203c033 Mon Sep 17 00:00:00 2001 +From: Doug Flick +Date: Wed, 17 Jan 2024 14:47:22 -0800 +Subject: [PATCH 3/3] SecurityPkg: : Updating SecurityFixes.yaml after symbol + rename + +Adding the new commit titles for the symbol renames + +Cc: Jiewen Yao +Cc: Rahul Kumar + +Signed-off-by: Doug Flick [MSFT] +Message-Id: <5e0e851e97459e183420178888d4fcdadc2f1ae1.1705529990.git.doug.edk2@gmail.com> +Reviewed-by: Jiewen Yao +--- + SecurityPkg/SecurityFixes.yaml | 28 +++++++++++++++++----------- + 1 file changed, 17 insertions(+), 11 deletions(-) + +diff --git a/SecurityPkg/SecurityFixes.yaml b/SecurityPkg/SecurityFixes.yaml +index 833fb82..b4006b4 100644 +--- a/SecurityPkg/SecurityFixes.yaml ++++ b/SecurityPkg/SecurityFixes.yaml +@@ -9,28 +9,34 @@ CVE_2022_36763: + - "SecurityPkg: DxeTpm2Measurement: SECURITY PATCH 4117 - CVE 2022-36763" + - "SecurityPkg: DxeTpmMeasurement: SECURITY PATCH 4117 - CVE 2022-36763" + - "SecurityPkg: : Adding CVE 2022-36763 to SecurityFixes.yaml" ++ - "SecurityPkg: DxeTpm2MeasureBootLib: SECURITY PATCH 4117/4118 symbol rename" ++ - "SecurityPkg: DxeTpmMeasureBootLib: SECURITY PATCH 4117/4118 symbol rename" ++ - "SecurityPkg: : Updating SecurityFixes.yaml after symbol rename" + cve: CVE-2022-36763 + date_reported: 2022-10-25 11:31 UTC + description: (CVE-2022-36763) - Heap Buffer Overflow in Tcg2MeasureGptTable() + note: This patch is related to and supersedes TCBZ2168 + files_impacted: +- - Library\DxeTpm2MeasureBootLib\DxeTpm2MeasureBootLib.c +- - Library\DxeTpmMeasureBootLib\DxeTpmMeasureBootLib.c ++ - Library\DxeTpm2MeasureBootLib\DxeTpm2MeasureBootLib.c ++ - Library\DxeTpmMeasureBootLib\DxeTpmMeasureBootLib.c + links: +- - https://bugzilla.tianocore.org/show_bug.cgi?id=4117 +- - https://bugzilla.tianocore.org/show_bug.cgi?id=2168 +- - https://bugzilla.tianocore.org/show_bug.cgi?id=1990 ++ - https://bugzilla.tianocore.org/show_bug.cgi?id=4117 ++ - https://bugzilla.tianocore.org/show_bug.cgi?id=2168 ++ - https://bugzilla.tianocore.org/show_bug.cgi?id=1990 + CVE_2022_36764: + commit_titles: +- - "SecurityPkg: DxeTpm2MeasureBootLib: SECURITY PATCH 4118 - CVE 2022-36764" +- - "SecurityPkg: DxeTpmMeasureBootLib: SECURITY PATCH 4118 - CVE 2022-36764" +- - "SecurityPkg: : Adding CVE 2022-36764 to SecurityFixes.yaml" ++ - "SecurityPkg: DxeTpm2MeasureBootLib: SECURITY PATCH 4118 - CVE 2022-36764" ++ - "SecurityPkg: DxeTpmMeasureBootLib: SECURITY PATCH 4118 - CVE 2022-36764" ++ - "SecurityPkg: : Adding CVE 2022-36764 to SecurityFixes.yaml" ++ - "SecurityPkg: DxeTpm2MeasureBootLib: SECURITY PATCH 4117/4118 symbol rename" ++ - "SecurityPkg: DxeTpmMeasureBootLib: SECURITY PATCH 4117/4118 symbol rename" ++ - "SecurityPkg: : Updating SecurityFixes.yaml after symbol rename" + cve: CVE-2022-36764 + date_reported: 2022-10-25 12:23 UTC + description: Heap Buffer Overflow in Tcg2MeasurePeImage() + note: + files_impacted: +- - Library\DxeTpm2MeasureBootLib\DxeTpm2MeasureBootLib.c +- - Library\DxeTpmMeasureBootLib\DxeTpmMeasureBootLib.c ++ - Library\DxeTpm2MeasureBootLib\DxeTpm2MeasureBootLib.c ++ - Library\DxeTpmMeasureBootLib\DxeTpmMeasureBootLib.c + links: +- - https://bugzilla.tianocore.org/show_bug.cgi?id=4118 ++ - https://bugzilla.tianocore.org/show_bug.cgi?id=4118 +-- +2.25.1 + diff --git a/SPECS/etcd/etcd.spec b/SPECS/etcd/etcd.spec index e013c81fbcb..90c04b683b5 100644 --- a/SPECS/etcd/etcd.spec +++ b/SPECS/etcd/etcd.spec @@ -1,7 +1,7 @@ Summary: A highly-available key value store for shared configuration Name: etcd Version: 3.5.12 -Release: 4%{?dist} +Release: 5%{?dist} License: ASL 2.0 Vendor: Microsoft Corporation Distribution: Mariner @@ -117,6 +117,9 @@ install -vdm755 %{buildroot}%{_sharedstatedir}/etcd /%{_docdir}/%{name}-%{version}-tools/* %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 3.5.12-5 +- Bump release to rebuild with go 1.22.7 + * Wed Jul 17 2024 Muhammad Falak R Wani - 3.5.12-4 - Drop requirement on a specific version of golang diff --git a/SPECS/expat/expat.signatures.json b/SPECS/expat/expat.signatures.json index 130f09b7314..62916cebe26 100644 --- a/SPECS/expat/expat.signatures.json +++ b/SPECS/expat/expat.signatures.json @@ -1,5 +1,5 @@ { "Signatures": { - "expat-2.6.2.tar.bz2": "9c7c1b5dcbc3c237c500a8fb1493e14d9582146dd9b42aa8d3ffb856a3b927e0" + "expat-2.6.3.tar.bz2": "b8baef92f328eebcf731f4d18103951c61fa8c8ec21d5ff4202fb6f2198aeb2d" } } \ No newline at end of file diff --git a/SPECS/expat/expat.spec b/SPECS/expat/expat.spec index c7307391618..45e05b016b6 100644 --- a/SPECS/expat/expat.spec +++ b/SPECS/expat/expat.spec @@ -1,8 +1,8 @@ %define underscore_version %(echo %{version} | cut -d. -f1-3 --output-delimiter="_") Summary: An XML parser library Name: expat -Version: 2.6.2 -Release: 2%{?dist} +Version: 2.6.3 +Release: 1%{?dist} License: MIT Vendor: Microsoft Corporation Distribution: Mariner @@ -67,6 +67,9 @@ rm -rf %{buildroot}/%{_docdir}/%{name} %{_libdir}/libexpat.so.1* %changelog +* Mon Sep 09 2024 Gary Swalling - 2.6.3-1 +- Upgrade to 2.6.3 to fix CVE-2024-45490, CVE-2024-45491, CVE-2024-45492 + * Thu Mar 28 2024 Aditya Dubey - 2.6.2-2 - Removed unnecessary "-p2" argument in "%%autosetup". diff --git a/SPECS/flannel/flannel.spec b/SPECS/flannel/flannel.spec index 0a19351006c..a951776f197 100644 --- a/SPECS/flannel/flannel.spec +++ b/SPECS/flannel/flannel.spec @@ -4,7 +4,7 @@ Summary: Simple and easy way to configure a layer 3 network fabric designed for Kubernetes Name: flannel Version: 0.14.0 -Release: 24%{?dist} +Release: 25%{?dist} License: ASL 2.0 Vendor: Microsoft Corporation Distribution: Mariner @@ -49,6 +49,9 @@ install -p -m 755 -t %{buildroot}%{_bindir} ./dist/flanneld %{_bindir}/flanneld %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 0.14.0-25 +- Bump release to rebuild with go 1.22.7 + * Wed Jul 17 2024 Muhammad Falak R Wani - 0.14.0-24 - Drop requirement on a specific version of golang diff --git a/SPECS/gdk-pixbuf2/CVE-2022-48622.patch b/SPECS/gdk-pixbuf2/CVE-2022-48622.patch new file mode 100755 index 00000000000..8037edfda8e --- /dev/null +++ b/SPECS/gdk-pixbuf2/CVE-2022-48622.patch @@ -0,0 +1,112 @@ +From 00c071dd11f723ca608608eef45cb1aa98da89cc Mon Sep 17 00:00:00 2001 +From: Benjamin Gilbert +Date: Tue, 30 Apr 2024 07:26:54 -0500 +Subject: [PATCH 1/3] ANI: Reject files with multiple anih chunks + +An anih chunk causes us to initialize a bunch of state, which we only +expect to do once per file. + +Fixes: #202 +Fixes: CVE-2022-48622 +--- + gdk-pixbuf/io-ani.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/gdk-pixbuf/io-ani.c b/gdk-pixbuf/io-ani.c +index c6c4642cf4..a78ea7ace4 100644 +--- a/gdk-pixbuf/io-ani.c ++++ b/gdk-pixbuf/io-ani.c +@@ -295,6 +295,15 @@ ani_load_chunk (AniLoaderContext *context, GError **error) + + if (context->chunk_id == TAG_anih) + { ++ if (context->animation) ++ { ++ g_set_error_literal (error, ++ GDK_PIXBUF_ERROR, ++ GDK_PIXBUF_ERROR_CORRUPT_IMAGE, ++ _("Invalid header in animation")); ++ return FALSE; ++ } ++ + context->HeaderSize = read_int32 (context); + context->NumFrames = read_int32 (context); + context->NumSteps = read_int32 (context); +-- +GitLab + + +From d52134373594ff76614fb415125b0d1c723ddd56 Mon Sep 17 00:00:00 2001 +From: Benjamin Gilbert +Date: Tue, 30 Apr 2024 07:13:37 -0500 +Subject: [PATCH 2/3] ANI: Reject files with multiple INAM or IART chunks + +There should be at most one chunk each. These would cause memory leaks +otherwise. +--- + gdk-pixbuf/io-ani.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/gdk-pixbuf/io-ani.c b/gdk-pixbuf/io-ani.c +index a78ea7ace4..8e8414117c 100644 +--- a/gdk-pixbuf/io-ani.c ++++ b/gdk-pixbuf/io-ani.c +@@ -445,7 +445,7 @@ ani_load_chunk (AniLoaderContext *context, GError **error) + } + else if (context->chunk_id == TAG_INAM) + { +- if (!context->animation) ++ if (!context->animation || context->title) + { + g_set_error_literal (error, + GDK_PIXBUF_ERROR, +@@ -472,7 +472,7 @@ ani_load_chunk (AniLoaderContext *context, GError **error) + } + else if (context->chunk_id == TAG_IART) + { +- if (!context->animation) ++ if (!context->animation || context->author) + { + g_set_error_literal (error, + GDK_PIXBUF_ERROR, +-- +GitLab + + +From 91b8aa5cd8a0eea28acb51f0e121827ca2e7eb78 Mon Sep 17 00:00:00 2001 +From: Benjamin Gilbert +Date: Tue, 30 Apr 2024 08:17:25 -0500 +Subject: [PATCH 3/3] ANI: Validate anih chunk size + +Before reading a chunk, we verify that enough bytes are available to match +the chunk size declared by the file. However, uniquely, the anih chunk +loader doesn't verify that this size matches the number of bytes it +actually intends to read. Thus, if the chunk size is too small and the +file ends in the middle of the chunk, we populate some context fields with +stack garbage. (But we'd still fail later on because the file doesn't +contain any images.) Fix this. +--- + gdk-pixbuf/io-ani.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/gdk-pixbuf/io-ani.c b/gdk-pixbuf/io-ani.c +index 8e8414117c..cfafd7b196 100644 +--- a/gdk-pixbuf/io-ani.c ++++ b/gdk-pixbuf/io-ani.c +@@ -295,6 +295,14 @@ ani_load_chunk (AniLoaderContext *context, GError **error) + + if (context->chunk_id == TAG_anih) + { ++ if (context->chunk_size < 36) ++ { ++ g_set_error_literal (error, ++ GDK_PIXBUF_ERROR, ++ GDK_PIXBUF_ERROR_CORRUPT_IMAGE, ++ _("Malformed chunk in animation")); ++ return FALSE; ++ } + if (context->animation) + { + g_set_error_literal (error, +-- +GitLab diff --git a/SPECS/gdk-pixbuf2/gdk-pixbuf2.spec b/SPECS/gdk-pixbuf2/gdk-pixbuf2.spec index b20c3794683..43c710f543c 100644 --- a/SPECS/gdk-pixbuf2/gdk-pixbuf2.spec +++ b/SPECS/gdk-pixbuf2/gdk-pixbuf2.spec @@ -2,12 +2,13 @@ Summary: An image loading library Name: gdk-pixbuf2 Version: 2.40.0 -Release: 5%{?dist} +Release: 6%{?dist} License: LGPLv2+ Vendor: Microsoft Corporation Distribution: Mariner URL: https://gitlab.gnome.org/GNOME/gdk-pixbuf Source0: https://download.gnome.org/sources/gdk-pixbuf/2.40/gdk-pixbuf-%{version}.tar.xz +Patch0: CVE-2022-48622.patch BuildRequires: gettext BuildRequires: gtk-doc BuildRequires: jasper-devel @@ -116,6 +117,9 @@ gdk-pixbuf-query-loaders-%{__isa_bits} --update-cache %{_datadir}/installed-tests %changelog +* Thu Sep 19 2024 Sumedh Sharma - 2.40.0-6 +- Add patch for CVE-2022-48622 + * Fri Mar 31 2023 Pawel Winogrodzki - 2.40.0-5 - Bumping release to re-build with newer 'libtiff' libraries. diff --git a/SPECS/gh/gh.spec b/SPECS/gh/gh.spec index 414a57bc004..1bce25690a9 100644 --- a/SPECS/gh/gh.spec +++ b/SPECS/gh/gh.spec @@ -1,7 +1,7 @@ Summary: GitHub official command line tool Name: gh Version: 2.13.0 -Release: 19%{?dist} +Release: 21%{?dist} License: MIT Vendor: Microsoft Corporation Distribution: Mariner @@ -75,13 +75,14 @@ make test %{_datadir}/zsh/site-functions/_gh %changelog -<<<<<<< HEAD -* Wed Jul 17 2024 Muhammad Falak R Wani - 2.13.0-19 +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 2.13.0-21 +- Bump release to rebuild with go 1.22.7 + +* Wed Jul 17 2024 Muhammad Falak R Wani - 2.13.0-20 - Drop requirement on a specific version of golang -======= + * Fri Jul 19 2024 Archana Choudhary - 2.13.0-19 - Patch for CVE-2021-43565 ->>>>>>> 9b583d8ff (gh: patch CVE-2021-43565 (#9894)) * Thu Jun 06 2024 CBL-Mariner Servicing Account - 2.13.0-18 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS/git-lfs/git-lfs.spec b/SPECS/git-lfs/git-lfs.spec index 7f700a60df1..96712b5c972 100644 --- a/SPECS/git-lfs/git-lfs.spec +++ b/SPECS/git-lfs/git-lfs.spec @@ -2,7 +2,7 @@ Summary: Git extension for versioning large files Name: git-lfs Version: 3.5.1 -Release: 2%{?dist} +Release: 3%{?dist} Group: System Environment/Programming Vendor: Microsoft Corporation Distribution: Mariner @@ -79,6 +79,9 @@ git lfs uninstall %{_mandir}/man5/* %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 3.5.1-3 +- Bump release to rebuild with go 1.22.7 + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 3.5.1-2 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS/glide/glide.spec b/SPECS/glide/glide.spec index dc1b43c379c..b625e85c3a5 100644 --- a/SPECS/glide/glide.spec +++ b/SPECS/glide/glide.spec @@ -1,7 +1,7 @@ Summary: Vendor Package Management for Golang Name: glide Version: 0.13.3 -Release: 26%{?dist} +Release: 27%{?dist} License: MIT URL: https://github.com/Masterminds/glide # Source0: https://github.com/Masterminds/%{name}/archive/v%{version}.tar.gz @@ -53,6 +53,9 @@ popd %{_bindir}/glide %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 0.13.3-27 +- Bump release to rebuild with go 1.22.7 + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 0.13.3-26 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS/go-md2man/go-md2man.spec b/SPECS/go-md2man/go-md2man.spec index 6da5d49eed5..15efaa6f158 100644 --- a/SPECS/go-md2man/go-md2man.spec +++ b/SPECS/go-md2man/go-md2man.spec @@ -1,7 +1,7 @@ Summary: Converts markdown into roff (man pages) Name: go-md2man Version: 2.0.1 -Release: 23%{?dist} +Release: 24%{?dist} License: MIT Vendor: Microsoft Corporation Distribution: Mariner @@ -48,6 +48,9 @@ cp go-md2man-%{version}/LICENSE.md %{buildroot}%{_docdir}/%{name}-%{version}/LIC %{_bindir}/go-md2man %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 2.0.1-24 +- Bump release to rebuild with go 1.22.7 + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 2.0.1-23 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS/gobject-introspection/gobject-introspection.spec b/SPECS/gobject-introspection/gobject-introspection.spec index 6241cb56516..26045e3caa6 100644 --- a/SPECS/gobject-introspection/gobject-introspection.spec +++ b/SPECS/gobject-introspection/gobject-introspection.spec @@ -2,7 +2,7 @@ Summary: Introspection system for GObject-based libraries Name: gobject-introspection Version: %{BaseVersion}.0 -Release: 18%{?dist} +Release: 19%{?dist} License: GPLv2+ AND LGPLv2+ AND MIT Vendor: Microsoft Corporation Distribution: Mariner @@ -98,6 +98,9 @@ find %{buildroot} -type f -name "*.la" -delete -print %{_mandir}/man1/*.gz %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 1.71.0-19 +- Bump release to rebuild with go 1.22.7 + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 1.71.0-18 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS/golang/golang.signatures.json b/SPECS/golang/golang.signatures.json index eaad159e83c..6cf27d53064 100644 --- a/SPECS/golang/golang.signatures.json +++ b/SPECS/golang/golang.signatures.json @@ -1,8 +1,8 @@ { - "Signatures": { - "go1.17.13.src.tar.gz": "a1a48b23afb206f95e7bbaa9b898d965f90826f6f1d1fc0c1d784ada0cd300fd", - "go1.21.6.src.tar.gz": "124926a62e45f78daabbaedb9c011d97633186a33c238ffc1e25320c02046248", - "go1.22.5.src.tar.gz": "ac9c723f224969aee624bc34fd34c9e13f2a212d75c71c807de644bb46e112f6", - "go1.4-bootstrap-20171003.tar.gz": "f4ff5b5eb3a3cae1c993723f3eab519c5bae18866b5e5f96fe1102f0cb5c3e52" - } -} \ No newline at end of file + "Signatures": { + "go1.17.13.src.tar.gz": "a1a48b23afb206f95e7bbaa9b898d965f90826f6f1d1fc0c1d784ada0cd300fd", + "go1.21.6.src.tar.gz": "124926a62e45f78daabbaedb9c011d97633186a33c238ffc1e25320c02046248", + "go1.4-bootstrap-20171003.tar.gz": "f4ff5b5eb3a3cae1c993723f3eab519c5bae18866b5e5f96fe1102f0cb5c3e52", + "go1.22.7.src.tar.gz": "66432d87d85e0cfac3edffe637d5930fc4ddf5793313fe11e4a0f333023c879f" + } +} diff --git a/SPECS/golang/golang.spec b/SPECS/golang/golang.spec index 57842d0b68a..1dc3d522677 100644 --- a/SPECS/golang/golang.spec +++ b/SPECS/golang/golang.spec @@ -14,7 +14,7 @@ %define __find_requires %{nil} Summary: Go Name: golang -Version: 1.22.5 +Version: 1.22.7 Release: 1%{?dist} License: BSD-3-Clause Vendor: Microsoft Corporation @@ -156,6 +156,9 @@ fi %{_bindir}/* %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 1.22.7-1 +- Auto-upgrade to 1.22.7 - Address CVE-2024-34158, CVE-2024-34156, CVE-2024-34155 + * Mon Jul 29 2024 Bhagyashri Pathak - 1.22.5 - Bump version to 1.22.5 diff --git a/SPECS/helm/helm.spec b/SPECS/helm/helm.spec index a464e2e45fe..19ef6e875db 100644 --- a/SPECS/helm/helm.spec +++ b/SPECS/helm/helm.spec @@ -2,7 +2,7 @@ Name: helm Version: 3.14.2 -Release: 3%{?dist} +Release: 4%{?dist} Summary: The Kubernetes Package Manager Group: Applications/Networking License: Apache 2.0 @@ -55,6 +55,9 @@ install -m 755 ./helm %{buildroot}%{_bindir} go test -v ./cmd/helm %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 3.14.2-4 +- Bump release to rebuild with go 1.22.7 + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 3.14.2-3 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS/hyperv-daemons/hyperv-daemons.signatures.json b/SPECS/hyperv-daemons/hyperv-daemons.signatures.json index 333870a9de1..63c71897dd8 100644 --- a/SPECS/hyperv-daemons/hyperv-daemons.signatures.json +++ b/SPECS/hyperv-daemons/hyperv-daemons.signatures.json @@ -7,6 +7,6 @@ "hypervkvpd.service": "c1bb207cf9f388f8f3cf5b649abbf8cfe4c4fcf74538612946e68f350d1f265f", "hypervvss.rules": "94cead44245ef6553ab79c0bbac8419e3ff4b241f01bcec66e6f508098cbedd1", "hypervvssd.service": "22270d9f0f23af4ea7905f19c1d5d5495e40c1f782cbb87a99f8aec5a011078d", - "kernel-5.15.164.1.tar.gz": "3634a7f014a0c821ada6cfb2ca6bdb2e18ae90fe9ce47b0adf8f81fd2852c3d8" + "kernel-5.15.167.1.tar.gz": "2f529a3abf4167d1de5f7dd73043827db2c08d647d924990843ee914b0558ee0" } } diff --git a/SPECS/hyperv-daemons/hyperv-daemons.spec b/SPECS/hyperv-daemons/hyperv-daemons.spec index b98ba69434c..d94f05433ee 100644 --- a/SPECS/hyperv-daemons/hyperv-daemons.spec +++ b/SPECS/hyperv-daemons/hyperv-daemons.spec @@ -8,7 +8,7 @@ %global udev_prefix 70 Summary: Hyper-V daemons suite Name: hyperv-daemons -Version: 5.15.164.1 +Version: 5.15.167.1 Release: 1%{?dist} License: GPLv2+ Vendor: Microsoft Corporation @@ -219,6 +219,12 @@ fi %{_sbindir}/lsvmbus %changelog +* Wed Sep 18 2024 CBL-Mariner Servicing Account - 5.15.167.1-1 +- Auto-upgrade to 5.15.167.1 + +* Thu Aug 29 2024 CBL-Mariner Servicing Account - 5.15.165.1-1 +- Auto-upgrade to 5.15.165.1 + * Fri Aug 09 2024 CBL-Mariner Servicing Account - 5.15.164.1-1 - Auto-upgrade to 5.15.164.1 diff --git a/SPECS/influx-cli/influx-cli.spec b/SPECS/influx-cli/influx-cli.spec index 9ade7779520..ecea1559d2d 100644 --- a/SPECS/influx-cli/influx-cli.spec +++ b/SPECS/influx-cli/influx-cli.spec @@ -18,7 +18,7 @@ Summary: CLI for managing resources in InfluxDB Name: influx-cli Version: 2.6.1 -Release: 16%{?dist} +Release: 17%{?dist} License: MIT Vendor: Microsoft Corporation Distribution: Mariner @@ -81,6 +81,9 @@ bin/influx completion zsh > %{buildroot}/%{_datadir}/zsh/site-functions/_influx %{_datadir}/zsh %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 2.6.1-17 +- Bump release to rebuild with go 1.22.7 + * Tue Jul 16 2024 Muhammad Falak - 2.6.1-16 - Drop constraint on golang <= 1.18 diff --git a/SPECS/influxdb/CVE-2022-32149.patch b/SPECS/influxdb/CVE-2022-32149.patch new file mode 100644 index 00000000000..9bc9f23821f --- /dev/null +++ b/SPECS/influxdb/CVE-2022-32149.patch @@ -0,0 +1,61 @@ +From 434eadcdbc3b0256971992e8c70027278364c72c Mon Sep 17 00:00:00 2001 +From: Roland Shoemaker +Date: Fri, 2 Sep 2022 09:35:37 -0700 +Subject: [PATCH] language: reject excessively large Accept-Language strings + +The BCP 47 tag parser has quadratic time complexity due to inherent +aspects of its design. Since the parser is, by design, exposed to +untrusted user input, this can be leveraged to force a program to +consume significant time parsing Accept-Language headers. + +The parser cannot be easily rewritten to fix this behavior for +various reasons. Instead the solution implemented in this CL is to +limit the total complexity of tags passed into ParseAcceptLanguage +by limiting the number of dashes in the string to 1000. This should +be more than enough for the majority of real world use cases, where +the number of tags being sent is likely to be in the single digits. + +Thanks to the OSS-Fuzz project for discovering this issue and to Adam +Korczynski (ADA Logics) for writing the fuzz case and for reporting the +issue. + +Fixes CVE-2022-32149 +Fixes golang/go#56152 + +Change-Id: I7bda1d84cee2b945039c203f26869d58ee9374ae +Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1565112 +Reviewed-by: Damien Neil +Reviewed-by: Tatiana Bradley +Reviewed-on: https://go-review.googlesource.com/c/text/+/442235 +TryBot-Result: Gopher Robot +Auto-Submit: Roland Shoemaker +Run-TryBot: Roland Shoemaker +--- + vendor/golang.org/x/text/language/parse.go | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/vendor/golang.org/x/text/language/parse.go b/vendor/golang.org/x/text/language/parse.go +index 59b0410..b982d9e 100644 +--- a/vendor/golang.org/x/text/language/parse.go ++++ b/vendor/golang.org/x/text/language/parse.go +@@ -147,6 +147,7 @@ func update(b *language.Builder, part ...interface{}) (err error) { + } + + var errInvalidWeight = errors.New("ParseAcceptLanguage: invalid weight") ++var errTagListTooLarge = errors.New("tag list exceeds max length") + + // ParseAcceptLanguage parses the contents of an Accept-Language header as + // defined in http://www.ietf.org/rfc/rfc2616.txt and returns a list of Tags and +@@ -164,6 +165,10 @@ func ParseAcceptLanguage(s string) (tag []Tag, q []float32, err error) { + } + }() + ++ if strings.Count(s, "-") > 1000 { ++ return nil, nil, errTagListTooLarge ++ } ++ + var entry string + for s != "" { + if entry, s = split(s, ','); entry == "" { +-- +2.25.1 diff --git a/SPECS/influxdb/influxdb.spec b/SPECS/influxdb/influxdb.spec index eea5104f71a..695c0335d63 100644 --- a/SPECS/influxdb/influxdb.spec +++ b/SPECS/influxdb/influxdb.spec @@ -18,7 +18,7 @@ Summary: Scalable datastore for metrics, events, and real-time analytics Name: influxdb Version: 2.6.1 -Release: 15%{?dist} +Release: 17%{?dist} License: MIT Vendor: Microsoft Corporation Distribution: Mariner @@ -56,6 +56,7 @@ Source4: influxdb.tmpfiles Source5: config.yaml Source6: influxdb-user.conf Patch0: CVE-2024-6104.patch +Patch1: CVE-2022-32149.patch BuildRequires: clang BuildRequires: golang <= 1.18.8 BuildRequires: kernel-headers @@ -145,6 +146,12 @@ go test ./... %{_tmpfilesdir}/influxdb.conf %changelog +* Tue Sep 17 2024 Sumedh Sharma - 2.6.1-17 +- Add patch to resolve CVE-2022-32149 + +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 2.6.1-16 +- Bump release to rebuild with go 1.22.7 + * Thu Aug 01 2024 Bala - 2.6.1.15 - Fix CVE 2024-6104 by patching vendor packages diff --git a/SPECS/jasper/CVE-2023-51257.patch b/SPECS/jasper/CVE-2023-51257.patch new file mode 100644 index 00000000000..0bef5db0102 --- /dev/null +++ b/SPECS/jasper/CVE-2023-51257.patch @@ -0,0 +1,37 @@ +Date: Thu, 14 Dec 2023 19:04:19 -0800 +Subject: [PATCH] Fixes #367. + +Fixed an integer-overflow bug in the ICC profile parsing code. +Added another invalid image to the test set. +--- + src/libjasper/base/jas_icc.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/src/libjasper/base/jas_icc.c b/src/libjasper/base/jas_icc.c +index 0a34587..2b26b5d 100644 +--- a/src/libjasper/base/jas_icc.c ++++ b/src/libjasper/base/jas_icc.c +@@ -1293,10 +1293,20 @@ static int jas_icctxt_input(jas_iccattrval_t *attrval, jas_stream_t *in, + { + jas_icctxt_t *txt = &attrval->data.txt; + txt->string = 0; ++ /* The string must at least contain a single null character. */ ++ if (cnt < 1) { ++ goto error; ++ } + if (!(txt->string = jas_malloc(cnt))) + goto error; + if (jas_stream_read(in, txt->string, cnt) != cnt) + goto error; ++ /* Ensure that the string is null terminated. */ ++ if (txt->string[cnt - 1] != '\0') { ++ goto error; ++ } ++ /* The following line is redundant, unless we do not enforce that ++ the last character must be null. */ + txt->string[cnt - 1] = '\0'; + if (strlen(txt->string) + 1 != cnt) + goto error; +-- +2.25.1 + diff --git a/SPECS/jasper/jasper.spec b/SPECS/jasper/jasper.spec index 1f083f6c0c6..744b7d2f2f7 100644 --- a/SPECS/jasper/jasper.spec +++ b/SPECS/jasper/jasper.spec @@ -1,7 +1,7 @@ Summary: Implementation of the JPEG-2000 standard, Part 1 Name: jasper Version: 2.0.32 -Release: 3%{?dist} +Release: 4%{?dist} License: JasPer Vendor: Microsoft Corporation Distribution: Mariner @@ -12,6 +12,7 @@ Patch2: jasper-2.0.14-rpath.patch # architecture related patches Patch100: jasper-2.0.2-test-ppc64-disable.patch Patch101: jasper-2.0.2-test-ppc64le-disable.patch +Patch102: CVE-2023-51257.patch # autoreconf BuildRequires: cmake BuildRequires: gcc @@ -73,6 +74,8 @@ Requires: %{name}-libs%{?_isa} = %{version}-%{release} %patch101 -p1 -b .test-ppc64le-disable %endif +%patch102 -p1 -b .cve-2023-51257.patch + %build mkdir builder %cmake \ @@ -113,6 +116,9 @@ make test -C builder %{_libdir}/libjasper.so.4* %changelog +* Fri Aug 23 2024 Sumedh Sharma - 2.0.32-4 +- Add patch to resolve CVE-2023-51257 + * Wed Sep 20 2023 Jon Slobodzian - 2.0.32-3 - Recompile with stack-protection fixed gcc version (CVE-2023-4039) diff --git a/SPECS/jx/jx.spec b/SPECS/jx/jx.spec index 0409fe120c9..a99501c8c36 100644 --- a/SPECS/jx/jx.spec +++ b/SPECS/jx/jx.spec @@ -1,7 +1,7 @@ Summary: Command line tool for working with Jenkins X. Name: jx Version: 3.2.236 -Release: 19%{?dist} +Release: 20%{?dist} License: Apache-2.0 Vendor: Microsoft Corporation Distribution: Mariner @@ -72,6 +72,9 @@ make test && \ %{_bindir}/jx %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 3.2.236-20 +- Bump release to rebuild with go 1.22.7 + * Thu Aug 22 2024 Sumedh Sharma - 3.2.236-19 - Add patch to resolve CVE-2023-45288 diff --git a/SPECS/kata-containers-cc/kata-containers-cc.spec b/SPECS/kata-containers-cc/kata-containers-cc.spec index 7805b80346b..26dc873a10b 100644 --- a/SPECS/kata-containers-cc/kata-containers-cc.spec +++ b/SPECS/kata-containers-cc/kata-containers-cc.spec @@ -13,7 +13,7 @@ Name: kata-containers-cc Version: 3.2.0.azl2 -Release: 3%{?dist} +Release: 4%{?dist} Summary: Kata Confidential Containers package developed for Confidential Containers on AKS License: ASL 2.0 Vendor: Microsoft Corporation @@ -288,6 +288,9 @@ install -D -m 0755 %{_builddir}/%{name}-%{version}/tools/osbuilder/image-builder %exclude %{osbuilder}/tools/osbuilder/rootfs-builder/ubuntu %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 3.2.0.azl2-4 +- Bump release to rebuild with go 1.22.7 + * Mon Jul 15 2024 Manuel Huber - 3.2.0.azl2-4 - Call make clean with OS distro variable diff --git a/SPECS/kata-containers/kata-containers.spec b/SPECS/kata-containers/kata-containers.spec index e85497ec256..4e271c48e79 100644 --- a/SPECS/kata-containers/kata-containers.spec +++ b/SPECS/kata-containers/kata-containers.spec @@ -39,7 +39,7 @@ Summary: Kata Containers Name: kata-containers Version: 3.2.0.azl2 -Release: 3%{?dist} +Release: 4%{?dist} License: ASL 2.0 Vendor: Microsoft Corporation URL: https://github.com/microsoft/kata-containers @@ -215,6 +215,9 @@ ln -sf %{_bindir}/kata-runtime %{buildroot}%{_prefix}/local/bin/kata-runtime %exclude %{kataosbuilderdir}/rootfs-builder/ubuntu %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 3.2.0.azl2-4 +- Bump release to rebuild with go 1.22.7 + * Mon Jul 15 2024 Manuel Huber - 3.2.0.azl2-3 - Call make clean with OS distro variable diff --git a/SPECS/keda/CVE-2022-32149.patch b/SPECS/keda/CVE-2022-32149.patch new file mode 100644 index 00000000000..aa946a17820 --- /dev/null +++ b/SPECS/keda/CVE-2022-32149.patch @@ -0,0 +1,68 @@ +From 7ee36713a66401f828dfe476196ca290f7c23ffe Mon Sep 17 00:00:00 2001 +From: Sindhu Karri +Date: Wed, 28 Aug 2024 05:01:17 +0000 +Subject: [PATCH] Fix CVE-2022-32149 + +--- +From 434eadcdbc3b0256971992e8c70027278364c72c Mon Sep 17 00:00:00 2001 +From: Roland Shoemaker +Date: Fri, 2 Sep 2022 09:35:37 -0700 +Subject: [PATCH] language: reject excessively large Accept-Language strings + +The BCP 47 tag parser has quadratic time complexity due to inherent +aspects of its design. Since the parser is, by design, exposed to +untrusted user input, this can be leveraged to force a program to +consume significant time parsing Accept-Language headers. + +The parser cannot be easily rewritten to fix this behavior for +various reasons. Instead the solution implemented in this CL is to +limit the total complexity of tags passed into ParseAcceptLanguage +by limiting the number of dashes in the string to 1000. This should +be more than enough for the majority of real world use cases, where +the number of tags being sent is likely to be in the single digits. + +Thanks to the OSS-Fuzz project for discovering this issue and to Adam +Korczynski (ADA Logics) for writing the fuzz case and for reporting the +issue. + +Fixes CVE-2022-32149 +Fixes golang/go#56152 + +Change-Id: I7bda1d84cee2b945039c203f26869d58ee9374ae +Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1565112 +Reviewed-by: Damien Neil +Reviewed-by: Tatiana Bradley +Reviewed-on: https://go-review.googlesource.com/c/text/+/442235 +TryBot-Result: Gopher Robot +Auto-Submit: Roland Shoemaker +Run-TryBot: Roland Shoemaker +--- + vendor/golang.org/x/text/language/parse.go | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/vendor/golang.org/x/text/language/parse.go b/vendor/golang.org/x/text/language/parse.go +index 11acfd8..11d11f4 100644 +--- a/vendor/golang.org/x/text/language/parse.go ++++ b/vendor/golang.org/x/text/language/parse.go +@@ -133,6 +133,7 @@ func update(b *language.Builder, part ...interface{}) (err error) { + } + + var errInvalidWeight = errors.New("ParseAcceptLanguage: invalid weight") ++var errTagListTooLarge = errors.New("tag list exceeds max length") + + // ParseAcceptLanguage parses the contents of an Accept-Language header as + // defined in http://www.ietf.org/rfc/rfc2616.txt and returns a list of Tags and +@@ -150,6 +151,10 @@ func ParseAcceptLanguage(s string) (tag []Tag, q []float32, err error) { + + entry, weight := split(entry, ';') + ++ if strings.Count(s, "-") > 1000 { ++ return nil, nil, errTagListTooLarge ++ } ++ + // Scan the language. + t, err := Parse(entry) + if err != nil { +-- +2.33.8 + diff --git a/SPECS/keda/keda.spec b/SPECS/keda/keda.spec index 9a03bd5beca..eea8cff568c 100644 --- a/SPECS/keda/keda.spec +++ b/SPECS/keda/keda.spec @@ -1,7 +1,7 @@ Summary: Kubernetes-based Event Driven Autoscaling Name: keda Version: 2.4.0 -Release: 22%{?dist} +Release: 24%{?dist} License: ASL 2.0 Vendor: Microsoft Corporation Distribution: Mariner @@ -31,7 +31,9 @@ Source1: %{name}-%{version}-vendor-v2.tar.gz Patch0: CVE-2022-21698.patch Patch1: CVE-2023-44487.patch Patch2: CVE-2021-44716.patch -Patch3: CVE-2024-6104.patch +Patch3: CVE-2022-32149.patch +Patch4: CVE-2024-6104.patch + BuildRequires: golang @@ -67,6 +69,12 @@ cp ./bin/keda-adapter %{buildroot}%{_bindir} %{_bindir}/%{name}-adapter %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 2.4.0-24 +- Bump release to rebuild with go 1.22.7 + +* Fri Aug 30 2024 Sindhu Karri - 2.4.0-23 +- Fix CVE-2022-32149 with a patch + * Thu Aug 01 2024 Bala - 2.4.0-22 - Patch CVE-2024-6104 diff --git a/SPECS/keepalived/CVE-2024-41184.patch b/SPECS/keepalived/CVE-2024-41184.patch new file mode 100644 index 00000000000..d6b5c5b5646 --- /dev/null +++ b/SPECS/keepalived/CVE-2024-41184.patch @@ -0,0 +1,379 @@ +From f3a32e3557520dccb298b36b4952eff3e236fb86 Mon Sep 17 00:00:00 2001 +From: Quentin Armitage +Date: Fri, 12 Jul 2024 15:11:13 +0100 +Subject: [PATCH 1/5] lib: don't return subtracted addresses for rb_find() + compare function + +If sizeof(int) < sizeof(void *) returning the difference between two +addresses in an int can cause an overflow. + +Use less_equal_greater_than() for comparing addresses. + +Signed-off-by: Quentin Armitage +--- + lib/memory.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/memory.c b/lib/memory.c +index c7217fdd..4b250ac9 100644 +--- a/lib/memory.c ++++ b/lib/memory.c +@@ -200,7 +200,7 @@ static unsigned free_list_size; + static inline int + memcheck_ptr_cmp(const void *key, const struct rb_node *a) + { +- return (const char *)key - (char *)rb_entry_const(a, MEMCHECK, t)->ptr; ++ return less_equal_greater_than((const char *)key, (char *)rb_entry_const(a, MEMCHECK, t)->ptr); + } + + static inline bool +-- +2.34.1 + + +From e78513fe0ce5d83c226ea2c0bd222f375c2438e7 Mon Sep 17 00:00:00 2001 +From: Quentin Armitage +Date: Fri, 12 Jul 2024 15:16:47 +0100 +Subject: [PATCH 2/5] vrrp: Handle empty ipset names with vrrp_ipsets keyword + +We now handle empty ipset names and return a config error. + +Signed-off-by: Quentin Armitage +--- + keepalived/core/global_parser.c | 40 ++++++++++++++++++--------------- + 1 file changed, 22 insertions(+), 18 deletions(-) + +diff --git a/keepalived/core/global_parser.c b/keepalived/core/global_parser.c +index ed76b5cb..8935e502 100644 +--- a/keepalived/core/global_parser.c ++++ b/keepalived/core/global_parser.c +@@ -1099,6 +1099,22 @@ vrrp_iptables_handler(const vector_t *strvec) + } + } + #ifdef _HAVE_LIBIPSET_ ++static bool ++check_valid_ipset_name(const vector_t *strvec, unsigned entry, const char *log_name) ++{ ++ if (strlen(strvec_slot(strvec, entry)) >= IPSET_MAXNAMELEN - 1) { ++ report_config_error(CONFIG_GENERAL_ERROR, "VRRP Error : ipset %s name too long - ignored", log_name); ++ return false; ++ } ++ ++ if (strlen(strvec_slot(strvec, entry)) == 0) { ++ report_config_error(CONFIG_GENERAL_ERROR, "VRRP Error : ipset %s name empty - ignored", log_name); ++ return false; ++ } ++ ++ return true; ++} ++ + static void + vrrp_ipsets_handler(const vector_t *strvec) + { +@@ -1119,17 +1135,13 @@ vrrp_ipsets_handler(const vector_t *strvec) + return; + } + +- if (strlen(strvec_slot(strvec,1)) >= IPSET_MAXNAMELEN - 1) { +- report_config_error(CONFIG_GENERAL_ERROR, "VRRP Error : ipset address name too long - ignored"); ++ if (!check_valid_ipset_name(strvec, 1, "address")) + return; +- } + global_data->vrrp_ipset_address = STRDUP(strvec_slot(strvec,1)); + + if (vector_size(strvec) >= 3) { +- if (strlen(strvec_slot(strvec,2)) >= IPSET_MAXNAMELEN - 1) { +- report_config_error(CONFIG_GENERAL_ERROR, "VRRP Error : ipset IPv6 address name too long - ignored"); ++ if (!check_valid_ipset_name(strvec, 2, "IPv6 address")) + return; +- } + global_data->vrrp_ipset_address6 = STRDUP(strvec_slot(strvec,2)); + } else { + /* No second set specified, copy first name and add "6" */ +@@ -1140,10 +1152,8 @@ vrrp_ipsets_handler(const vector_t *strvec) + } + + if (vector_size(strvec) >= 4) { +- if (strlen(strvec_slot(strvec,3)) >= IPSET_MAXNAMELEN - 1) { +- report_config_error(CONFIG_GENERAL_ERROR, "VRRP Error : ipset IPv6 address_iface name too long - ignored"); ++ if (!check_valid_ipset_name(strvec, 3, "IPv6 address_iface")) + return; +- } + global_data->vrrp_ipset_address_iface6 = STRDUP(strvec_slot(strvec,3)); + } else { + /* No third set specified, copy second name and add "_if6" */ +@@ -1157,10 +1167,8 @@ vrrp_ipsets_handler(const vector_t *strvec) + } + + if (vector_size(strvec) >= 5) { +- if (strlen(strvec_slot(strvec,4)) >= IPSET_MAXNAMELEN - 1) { +- report_config_error(CONFIG_GENERAL_ERROR, "VRRP Error : ipset IGMP name too long - ignored"); ++ if (!check_valid_ipset_name(strvec, 4, "IGMP")) + return; +- } + global_data->vrrp_ipset_igmp = STRDUP(strvec_slot(strvec,4)); + } else { + /* No second set specified, copy first name and add "_igmp" */ +@@ -1171,10 +1179,8 @@ vrrp_ipsets_handler(const vector_t *strvec) + } + + if (vector_size(strvec) >= 6) { +- if (strlen(strvec_slot(strvec,5)) >= IPSET_MAXNAMELEN - 1) { +- report_config_error(CONFIG_GENERAL_ERROR, "VRRP Error : ipset MLD name too long - ignored"); ++ if (!check_valid_ipset_name(strvec, 5, "MLD")) + return; +- } + global_data->vrrp_ipset_mld = STRDUP(strvec_slot(strvec,5)); + } else { + /* No second set specified, copy first name and add "_mld" */ +@@ -1186,10 +1192,8 @@ vrrp_ipsets_handler(const vector_t *strvec) + + #ifdef _HAVE_VRRP_VMAC_ + if (vector_size(strvec) >= 7) { +- if (strlen(strvec_slot(strvec,6)) >= IPSET_MAXNAMELEN - 1) { +- report_config_error(CONFIG_GENERAL_ERROR, "VRRP Error : ipset ND name too long - ignored"); ++ if (!check_valid_ipset_name(strvec, 6, "ND")) + return; +- } + global_data->vrrp_ipset_vmac_nd = STRDUP(strvec_slot(strvec,6)); + } else { + /* No second set specified, copy first name and add "_nd" */ +-- +2.34.1 + + +From 281de3aa8a0990fa3cd694a9addc0bf28953da0b Mon Sep 17 00:00:00 2001 +From: Quentin Armitage +Date: Fri, 12 Jul 2024 15:18:20 +0100 +Subject: [PATCH 3/5] vrrp: handle empty iptables chain names - vrrp_iptables + keyword + +We now return an error if a chain name is empty. + +Signed-off-by: Quentin Armitage +--- + keepalived/core/global_parser.c | 42 ++++++++++++++++++++------------- + 1 file changed, 25 insertions(+), 17 deletions(-) + +diff --git a/keepalived/core/global_parser.c b/keepalived/core/global_parser.c +index 8935e502..3d436e49 100644 +--- a/keepalived/core/global_parser.c ++++ b/keepalived/core/global_parser.c +@@ -1072,6 +1072,28 @@ vrrp_higher_prio_send_advert_handler(const vector_t *strvec) + global_data->vrrp_higher_prio_send_advert = true; + } + #ifdef _WITH_IPTABLES_ ++static bool ++check_valid_iptables_ipset_name(const vector_t *strvec, unsigned entry, unsigned max_len, const char *type_name, const char *log_name) ++{ ++ if (strlen(strvec_slot(strvec, entry)) >= max_len - 1) { ++ report_config_error(CONFIG_GENERAL_ERROR, "VRRP Error : %s %s name too long - ignored", type_name, log_name); ++ return false; ++ } ++ ++ if (strlen(strvec_slot(strvec, entry)) == 0) { ++ report_config_error(CONFIG_GENERAL_ERROR, "VRRP Error : %s %s name empty - ignored", type_name, log_name); ++ return false; ++ } ++ ++ return true; ++} ++ ++static bool ++check_valid_iptables_chain_name(const vector_t *strvec, unsigned entry, const char *log_name) ++{ ++ return check_valid_iptables_ipset_name(strvec, entry, XT_EXTENSION_MAXNAMELEN, "iptables", log_name); ++} ++ + static void + vrrp_iptables_handler(const vector_t *strvec) + { +@@ -1081,16 +1103,12 @@ vrrp_iptables_handler(const vector_t *strvec) + } + + if (vector_size(strvec) >= 2) { +- if (strlen(strvec_slot(strvec,1)) >= XT_EXTENSION_MAXNAMELEN - 1) { +- report_config_error(CONFIG_GENERAL_ERROR, "VRRP Error : iptables in chain name too long - ignored"); ++ if (!check_valid_iptables_chain_name(strvec, 1, "in chain")) + return; +- } + global_data->vrrp_iptables_inchain = STRDUP(strvec_slot(strvec,1)); + if (vector_size(strvec) >= 3) { +- if (strlen(strvec_slot(strvec,2)) >= XT_EXTENSION_MAXNAMELEN - 1) { +- report_config_error(CONFIG_GENERAL_ERROR, "VRRP Error : iptables out chain name too long - ignored"); ++ if (!check_valid_iptables_chain_name(strvec, 2, "out chain")) + return; +- } + global_data->vrrp_iptables_outchain = STRDUP(strvec_slot(strvec,2)); + } + } else { +@@ -1102,17 +1120,7 @@ vrrp_iptables_handler(const vector_t *strvec) + static bool + check_valid_ipset_name(const vector_t *strvec, unsigned entry, const char *log_name) + { +- if (strlen(strvec_slot(strvec, entry)) >= IPSET_MAXNAMELEN - 1) { +- report_config_error(CONFIG_GENERAL_ERROR, "VRRP Error : ipset %s name too long - ignored", log_name); +- return false; +- } +- +- if (strlen(strvec_slot(strvec, entry)) == 0) { +- report_config_error(CONFIG_GENERAL_ERROR, "VRRP Error : ipset %s name empty - ignored", log_name); +- return false; +- } +- +- return true; ++ return check_valid_iptables_ipset_name(strvec, entry, IPSET_MAXNAMELEN, "ipset", log_name); + } + + static void +-- +2.34.1 + + +From 1e5902c4793ac01b810f0faa3b5cf47b41ae95c1 Mon Sep 17 00:00:00 2001 +From: Quentin Armitage +Date: Fri, 12 Jul 2024 15:32:35 +0100 +Subject: [PATCH 4/5] vrrp and ipvs: handle empty nftables chain names + +We now return an error if a chain name is empty. + +Signed-off-by: Quentin Armitage +--- + keepalived/core/global_parser.c | 25 +++++++++++++++---------- + 1 file changed, 15 insertions(+), 10 deletions(-) + +diff --git a/keepalived/core/global_parser.c b/keepalived/core/global_parser.c +index 3d436e49..0a8f53ac 100644 +--- a/keepalived/core/global_parser.c ++++ b/keepalived/core/global_parser.c +@@ -1071,9 +1071,10 @@ vrrp_higher_prio_send_advert_handler(const vector_t *strvec) + else + global_data->vrrp_higher_prio_send_advert = true; + } +-#ifdef _WITH_IPTABLES_ ++ ++#if defined _WITH_IPTABLES_ || defined _WITH_NFTABLES_ + static bool +-check_valid_iptables_ipset_name(const vector_t *strvec, unsigned entry, unsigned max_len, const char *type_name, const char *log_name) ++check_valid_iptables_ipset_nftables_name(const vector_t *strvec, unsigned entry, unsigned max_len, const char *type_name, const char *log_name) + { + if (strlen(strvec_slot(strvec, entry)) >= max_len - 1) { + report_config_error(CONFIG_GENERAL_ERROR, "VRRP Error : %s %s name too long - ignored", type_name, log_name); +@@ -1087,11 +1088,13 @@ check_valid_iptables_ipset_name(const vector_t *strvec, unsigned entry, unsigned + + return true; + } ++#endif + ++#ifdef _WITH_IPTABLES_ + static bool + check_valid_iptables_chain_name(const vector_t *strvec, unsigned entry, const char *log_name) + { +- return check_valid_iptables_ipset_name(strvec, entry, XT_EXTENSION_MAXNAMELEN, "iptables", log_name); ++ return check_valid_iptables_ipset_nftables_name(strvec, entry, XT_EXTENSION_MAXNAMELEN, "iptables", log_name); + } + + static void +@@ -1120,7 +1123,7 @@ vrrp_iptables_handler(const vector_t *strvec) + static bool + check_valid_ipset_name(const vector_t *strvec, unsigned entry, const char *log_name) + { +- return check_valid_iptables_ipset_name(strvec, entry, IPSET_MAXNAMELEN, "ipset", log_name); ++ return check_valid_iptables_ipset_nftables_name(strvec, entry, IPSET_MAXNAMELEN, "ipset", log_name); + } + + static void +@@ -1229,6 +1232,12 @@ vrrp_iptables_handler(__attribute__((unused)) const vector_t *strvec) + + #ifdef _WITH_NFTABLES_ + #ifdef _WITH_VRRP_ ++static bool ++check_valid_nftables_chain_name(const vector_t *strvec, unsigned entry, const char *log_name) ++{ ++ return check_valid_iptables_ipset_nftables_name(strvec, entry, NFT_TABLE_MAXNAMELEN, "nftables", log_name); ++} ++ + static void + vrrp_nftables_handler(__attribute__((unused)) const vector_t *strvec) + { +@@ -1240,10 +1249,8 @@ vrrp_nftables_handler(__attribute__((unused)) const vector_t *strvec) + } + + if (vector_size(strvec) >= 2) { +- if (strlen(strvec_slot(strvec, 1)) >= NFT_TABLE_MAXNAMELEN) { +- report_config_error(CONFIG_GENERAL_ERROR, "nftables table name too long - ignoring"); ++ if (!check_valid_nftables_chain_name(strvec, 1, "chain")) + return; +- } + name = strvec_slot(strvec, 1); + } + else { +@@ -1283,10 +1290,8 @@ ipvs_nftables_handler(__attribute__((unused)) const vector_t *strvec) + } + + if (vector_size(strvec) >= 2) { +- if (strlen(strvec_slot(strvec, 1)) >= NFT_TABLE_MAXNAMELEN) { +- report_config_error(CONFIG_GENERAL_ERROR, "ipvs nftables table name too long - ignoring"); ++ if (!check_valid_nftables_chain_name(strvec, 1, "ipvs chain")) + return; +- } + name = strvec_slot(strvec, 1); + } + else { +-- +2.34.1 + + +From 7e2cabdb1391f9378fbb76513c2ee9c88b15dba8 Mon Sep 17 00:00:00 2001 +From: Quentin Armitage +Date: Fri, 12 Jul 2024 15:34:54 +0100 +Subject: [PATCH 5/5] configure: add --enable-sanitize-address option + +Signed-off-by: Quentin Armitage +--- + configure.ac | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/configure.ac b/configure.ac +index 180beb6f..1ba691b6 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -263,6 +263,8 @@ AC_ARG_ENABLE(stacktrace, + [AS_HELP_STRING([--enable-stacktrace], [compile with stacktrace support])]) + AC_ARG_ENABLE(perf, + [AS_HELP_STRING([--enable-perf], [compile with perf performance data recording support for vrrp process])]) ++AC_ARG_ENABLE(sanitize-address, ++ [AS_HELP_STRING([--enable-sanitize-address], [compile with sanitize=address (ASAN) support])]) + AC_ARG_ENABLE(log-file, + [AS_HELP_STRING([--enable-log-file], [enable logging to file (-g)])]) + AC_ARG_ENABLE(dump-threads, +@@ -2848,6 +2850,16 @@ else + ENABLE_PERF=No + fi + ++dnl ----[ sanitize=address testing or not? ]---- ++if test "${enable_sanitize_address}" = yes; then ++# AC_DEFINE([_WITH_SANITIZE_ADDRESS_], [ 1 ], [Define to 1 to build with sanitize=address support]) ++ ENABLE_SANITIZE_ADDRESS=Yes ++ add_config_opt([SANITIZE_ADDRESS]) ++ add_to_var([KA_CFLAGS], [-fsanitize=address -g]) ++else ++ ENABLE_SANITIZE_ADDRESS=No ++fi ++ + if test "${enable_log_file}" = yes; then + AC_DEFINE([ENABLE_LOG_TO_FILE], [ 1 ], [Define if enabling logging to files]) + ENABLE_LOG_FILE_APPEND=Yes +@@ -3271,6 +3283,9 @@ fi + if test ${ENABLE_PERF} = Yes; then + echo "Perf support : Yes" + fi ++if test ${ENABLE_SANITIZE_ADDRESS} = Yes; then ++ echo "sanitize=address testing : Yes" ++fi + if test ${MEM_CHECK} = Yes; then + echo "Memory alloc check : Yes" + echo "Memory alloc check log : ${MEM_CHECK_LOG}" +-- +2.34.1 + diff --git a/SPECS/keepalived/keepalived.signatures.json b/SPECS/keepalived/keepalived.signatures.json index a98e4f6cf9a..ce75fa5589a 100644 --- a/SPECS/keepalived/keepalived.signatures.json +++ b/SPECS/keepalived/keepalived.signatures.json @@ -1,6 +1,6 @@ { "Signatures": { - "keepalived-2.2.7.tar.gz": "c61940d874154a560a54627ecf7ef47adebdf832164368d10bf242a4d9b7d49d", + "keepalived-2.3.1.tar.gz": "92f4b69bfd998e2306d1995ad16fdad1b59e70be694c883385c5f55e02c62aa3", "keepalived.service": "533fac0ed629192f87b42f5fa2ba4443bccc3ac383e9495be97369616b95d6bd" } -} \ No newline at end of file +} diff --git a/SPECS/keepalived/keepalived.spec b/SPECS/keepalived/keepalived.spec index 4cbcf798a7a..1cd443247d8 100644 --- a/SPECS/keepalived/keepalived.spec +++ b/SPECS/keepalived/keepalived.spec @@ -1,6 +1,6 @@ Summary: HA monitor built upon LVS, VRRP and services poller Name: keepalived -Version: 2.2.7 +Version: 2.3.1 Release: 1%{?dist} License: GPLv2 Vendor: Microsoft Corporation @@ -9,6 +9,7 @@ Group: Applications/System URL: https://www.keepalived.org/ Source0: https://www.keepalived.org/software/%{name}-%{version}.tar.gz Source1: %{name}.service +Patch0: CVE-2024-41184.patch BuildRequires: autoconf BuildRequires: automake @@ -45,7 +46,7 @@ failover. So in short keepalived is a userspace daemon for LVS cluster nodes healthchecks and LVS directors failover. %prep -%setup -q +%autosetup -p1 %build autoreconf -f -i @@ -109,6 +110,10 @@ fi %{_mandir}/man8/keepalived.8* %changelog +* Fri Sep 13 2024 Harshit Gupta - 2.3.1-1 +- Add patch for CVE-2024-41184.patch. +- Use autosetup. + * Tue Feb 08 2022 Cameron Baird - 2.2.7-1 - Update source to v2.2.7 - Using Fedora 36 spec (license: MIT) for guidance. diff --git a/SPECS/kernel-azure/config b/SPECS/kernel-azure/config index 618e594f242..10615306ef2 100644 --- a/SPECS/kernel-azure/config +++ b/SPECS/kernel-azure/config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/x86_64 5.15.164.1 Kernel Configuration +# Linux/x86_64 5.15.167.1 Kernel Configuration # CONFIG_CC_VERSION_TEXT="gcc (GCC) 11.2.0" CONFIG_CC_IS_GCC=y diff --git a/SPECS/kernel-azure/config_aarch64 b/SPECS/kernel-azure/config_aarch64 index 86e48b414e4..e52cf7dc401 100644 --- a/SPECS/kernel-azure/config_aarch64 +++ b/SPECS/kernel-azure/config_aarch64 @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm64 5.15.164.1 Kernel Configuration +# Linux/arm64 5.15.167.1 Kernel Configuration # CONFIG_CC_VERSION_TEXT="gcc (GCC) 11.2.0" CONFIG_CC_IS_GCC=y @@ -374,6 +374,7 @@ CONFIG_ARM64_ERRATUM_2457168=y CONFIG_ARM64_WORKAROUND_TSB_FLUSH_FAILURE=y CONFIG_ARM64_ERRATUM_2054223=y CONFIG_ARM64_ERRATUM_2067961=y +CONFIG_ARM64_ERRATUM_3194386=y CONFIG_CAVIUM_ERRATUM_22375=y CONFIG_CAVIUM_ERRATUM_23144=y CONFIG_CAVIUM_ERRATUM_23154=y diff --git a/SPECS/kernel-azure/kernel-azure.signatures.json b/SPECS/kernel-azure/kernel-azure.signatures.json index 991a9088e9f..d7d95e0ee6a 100644 --- a/SPECS/kernel-azure/kernel-azure.signatures.json +++ b/SPECS/kernel-azure/kernel-azure.signatures.json @@ -1,9 +1,9 @@ { "Signatures": { "cbl-mariner-ca-20211013.pem": "5ef124b0924cb1047c111a0ecff1ae11e6ad7cac8d1d9b40f98f99334121f0b0", - "config": "a84f20c07e5f2a8a76db3a5bc7c7da29cb8b5bccb457a75ac52cfef847b7e743", - "config_aarch64": "2e737ff36bf79ea1cebaffc145e6e24c6a292992cb3191a4a5bf7e7b51aafb6b", + "config": "97d9d65905746afb5c23e03bc0d5c4c2703f1701ffb61031dda00e8541ecf185", + "config_aarch64": "616ea3ccfdf311b10a2702e7eac052f561fb0556a94b0c5e1b72c6293fca5083", "sha512hmac-openssl.sh": "02ab91329c4be09ee66d759e4d23ac875037c3b56e5a598e32fd1206da06a27f", - "kernel-5.15.164.1.tar.gz": "3634a7f014a0c821ada6cfb2ca6bdb2e18ae90fe9ce47b0adf8f81fd2852c3d8" + "kernel-5.15.167.1.tar.gz": "2f529a3abf4167d1de5f7dd73043827db2c08d647d924990843ee914b0558ee0" } } diff --git a/SPECS/kernel-azure/kernel-azure.spec b/SPECS/kernel-azure/kernel-azure.spec index 14be7cdf305..f20f660ec2b 100644 --- a/SPECS/kernel-azure/kernel-azure.spec +++ b/SPECS/kernel-azure/kernel-azure.spec @@ -27,7 +27,7 @@ Summary: Linux Kernel Name: kernel-azure -Version: 5.15.164.1 +Version: 5.15.167.1 Release: 1%{?dist} License: GPLv2 Vendor: Microsoft Corporation @@ -420,6 +420,12 @@ ln -sf linux-%{uname_r}.cfg /boot/mariner.cfg %{_sysconfdir}/bash_completion.d/bpftool %changelog +* Wed Sep 18 2024 CBL-Mariner Servicing Account - 5.15.167.1-1 +- Auto-upgrade to 5.15.167.1 + +* Thu Aug 29 2024 CBL-Mariner Servicing Account - 5.15.165.1-1 +- Auto-upgrade to 5.15.165.1 + * Fri Aug 09 2024 CBL-Mariner Servicing Account - 5.15.164.1-1 - Auto-upgrade to 5.15.164.1 diff --git a/SPECS/kernel-hci/config b/SPECS/kernel-hci/config index 3547b750d88..e0d9c89a206 100644 --- a/SPECS/kernel-hci/config +++ b/SPECS/kernel-hci/config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/x86_64 5.15.164.1 Kernel Configuration +# Linux/x86_64 5.15.167.1 Kernel Configuration # CONFIG_CC_VERSION_TEXT="gcc (GCC) 11.2.0" CONFIG_CC_IS_GCC=y diff --git a/SPECS/kernel-hci/kernel-hci.signatures.json b/SPECS/kernel-hci/kernel-hci.signatures.json index 32247f3f364..50e01ad2585 100644 --- a/SPECS/kernel-hci/kernel-hci.signatures.json +++ b/SPECS/kernel-hci/kernel-hci.signatures.json @@ -1,7 +1,7 @@ { "Signatures": { "cbl-mariner-ca-20211013.pem": "5ef124b0924cb1047c111a0ecff1ae11e6ad7cac8d1d9b40f98f99334121f0b0", - "config": "a2580de76388be81d6c393c90b1d0e01befa4cc1b668e3f68d4f2e7337a473ea", - "kernel-5.15.164.1.tar.gz": "3634a7f014a0c821ada6cfb2ca6bdb2e18ae90fe9ce47b0adf8f81fd2852c3d8" + "config": "05cee91e9e1f815e6bf8cebfb5866aeef51e849e41b0c37834d9e0c5a09cea59", + "kernel-5.15.167.1.tar.gz": "2f529a3abf4167d1de5f7dd73043827db2c08d647d924990843ee914b0558ee0" } } diff --git a/SPECS/kernel-hci/kernel-hci.spec b/SPECS/kernel-hci/kernel-hci.spec index 415ec5cdb62..7ad05b0fff0 100644 --- a/SPECS/kernel-hci/kernel-hci.spec +++ b/SPECS/kernel-hci/kernel-hci.spec @@ -17,7 +17,7 @@ %define config_source %{SOURCE1} Summary: Linux Kernel for HCI Name: kernel-hci -Version: 5.15.164.1 +Version: 5.15.167.1 Release: 1%{?dist} License: GPLv2 Vendor: Microsoft Corporation @@ -547,6 +547,12 @@ ln -sf linux-%{uname_r}.cfg /boot/mariner.cfg %{_sysconfdir}/bash_completion.d/bpftool %changelog +* Wed Sep 18 2024 CBL-Mariner Servicing Account - 5.15.167.1-1 +- Auto-upgrade to 5.15.167.1 + +* Thu Aug 29 2024 CBL-Mariner Servicing Account - 5.15.165.1-1 +- Auto-upgrade to 5.15.165.1 + * Fri Aug 09 2024 CBL-Mariner Servicing Account - 5.15.164.1-1 - Auto-upgrade to 5.15.164.1 diff --git a/SPECS/kernel-headers/kernel-headers.signatures.json b/SPECS/kernel-headers/kernel-headers.signatures.json index b2885a5f6e3..e96ab9d2c7a 100644 --- a/SPECS/kernel-headers/kernel-headers.signatures.json +++ b/SPECS/kernel-headers/kernel-headers.signatures.json @@ -1,5 +1,5 @@ { "Signatures": { - "kernel-5.15.164.1.tar.gz": "3634a7f014a0c821ada6cfb2ca6bdb2e18ae90fe9ce47b0adf8f81fd2852c3d8" + "kernel-5.15.167.1.tar.gz": "2f529a3abf4167d1de5f7dd73043827db2c08d647d924990843ee914b0558ee0" } } diff --git a/SPECS/kernel-headers/kernel-headers.spec b/SPECS/kernel-headers/kernel-headers.spec index f41fc616438..baa5bdebb86 100644 --- a/SPECS/kernel-headers/kernel-headers.spec +++ b/SPECS/kernel-headers/kernel-headers.spec @@ -11,7 +11,7 @@ Summary: Linux API header files Name: kernel-headers -Version: 5.15.164.1 +Version: 5.15.167.1 Release: 1%{?dist} License: GPLv2 Vendor: Microsoft Corporation @@ -73,6 +73,15 @@ done %endif %changelog +* Wed Sep 18 2024 CBL-Mariner Servicing Account - 5.15.167.1-1 +- Auto-upgrade to 5.15.167.1 + +* Thu Aug 29 2024 CBL-Mariner Servicing Account - 5.15.165.1-1 +- Auto-upgrade to 5.15.165.1 + +* Tue Aug 27 2024 Chris Co - 5.15.164.1-2 +- Bump release to match kernel + * Fri Aug 09 2024 CBL-Mariner Servicing Account - 5.15.164.1-1 - Auto-upgrade to 5.15.164.1 diff --git a/SPECS/kernel/CVE-2023-52889.nopatch b/SPECS/kernel/CVE-2023-52889.nopatch new file mode 100644 index 00000000000..5f8c6832ab6 --- /dev/null +++ b/SPECS/kernel/CVE-2023-52889.nopatch @@ -0,0 +1,3 @@ +CVE-2023-52889 - patched in 5.15.165.1 - (generated by autopatch tool) +upstream fce09ea314505a52f2436397608fa0a5d0934fb1 - stable 290a6b88e8c19b6636ed1acc733d1458206f7697 + diff --git a/SPECS/kernel/CVE-2024-39472.nopatch b/SPECS/kernel/CVE-2024-39472.nopatch new file mode 100644 index 00000000000..8fef2ca6e7e --- /dev/null +++ b/SPECS/kernel/CVE-2024-39472.nopatch @@ -0,0 +1,3 @@ +CVE-2024-39472 - patched in 5.15.165.1 - (generated by autopatch tool) +upstream 45cf976008ddef4a9c9a30310c9b4fb2a9a6602a - stable f754591b17d0ee91c2b45fe9509d0cdc420527cb + diff --git a/SPECS/kernel/CVE-2024-42114.nopatch b/SPECS/kernel/CVE-2024-42114.nopatch new file mode 100644 index 00000000000..5b25dd83f17 --- /dev/null +++ b/SPECS/kernel/CVE-2024-42114.nopatch @@ -0,0 +1,3 @@ +CVE-2024-42114 - patched in 5.15.165.1 - (generated by autopatch tool) +upstream d1cba2ea8121e7fdbe1328cea782876b1dd80993 - stable 33ac5a4eb3d4bea2146658f1b6d1fa86d62d2b22 + diff --git a/SPECS/kernel/CVE-2024-42240.nopatch b/SPECS/kernel/CVE-2024-42240.nopatch new file mode 100644 index 00000000000..7a5102af154 --- /dev/null +++ b/SPECS/kernel/CVE-2024-42240.nopatch @@ -0,0 +1,3 @@ +CVE-2024-42240 - patched in 5.15.163.1 - (generated by autopatch tool) +upstream ac8b270b61d48fcc61f052097777e3b5e11591e0 - stable db56615e96c439e13783d7715330e824b4fd4b84 + diff --git a/SPECS/kernel/CVE-2024-42269.nopatch b/SPECS/kernel/CVE-2024-42269.nopatch new file mode 100644 index 00000000000..215ea4223da --- /dev/null +++ b/SPECS/kernel/CVE-2024-42269.nopatch @@ -0,0 +1,3 @@ +CVE-2024-42269 - patched in 5.15.165.1 - (generated by autopatch tool) +upstream c22921df777de5606f1047b1345b8d22ef1c0b34 - stable 419ee6274c5153b89c4393c1946faa4c3cad4f9e + diff --git a/SPECS/kernel/CVE-2024-42270.nopatch b/SPECS/kernel/CVE-2024-42270.nopatch new file mode 100644 index 00000000000..07948172eff --- /dev/null +++ b/SPECS/kernel/CVE-2024-42270.nopatch @@ -0,0 +1,3 @@ +CVE-2024-42270 - patched in 5.15.165.1 - (generated by autopatch tool) +upstream 5830aa863981d43560748aa93589c0695191d95d - stable b98ddb65fa1674b0e6b52de8af9103b63f51b643 + diff --git a/SPECS/kernel/CVE-2024-42271.nopatch b/SPECS/kernel/CVE-2024-42271.nopatch new file mode 100644 index 00000000000..118c683a483 --- /dev/null +++ b/SPECS/kernel/CVE-2024-42271.nopatch @@ -0,0 +1,3 @@ +CVE-2024-42271 - patched in 5.15.165.1 - (generated by autopatch tool) +upstream f558120cd709682b739207b48cf7479fd9568431 - stable ac758e1f663fe9bc64f6b47212a2aa18697524f5 + diff --git a/SPECS/kernel/CVE-2024-42283.nopatch b/SPECS/kernel/CVE-2024-42283.nopatch new file mode 100644 index 00000000000..605bf956085 --- /dev/null +++ b/SPECS/kernel/CVE-2024-42283.nopatch @@ -0,0 +1,3 @@ +CVE-2024-42283 - patched in 5.15.165.1 - (generated by autopatch tool) +upstream 6d745cd0e9720282cd291d36b9db528aea18add2 - stable 9e8f558a3afe99ce51a642ce0d3637ddc2b5d5d0 + diff --git a/SPECS/kernel/CVE-2024-42284.nopatch b/SPECS/kernel/CVE-2024-42284.nopatch new file mode 100644 index 00000000000..5d535c99956 --- /dev/null +++ b/SPECS/kernel/CVE-2024-42284.nopatch @@ -0,0 +1,3 @@ +CVE-2024-42284 - patched in 5.15.165.1 - (generated by autopatch tool) +upstream fa96c6baef1b5385e2f0c0677b32b3839e716076 - stable 5eea127675450583680c8170358bcba43227bd69 + diff --git a/SPECS/kernel/CVE-2024-42285.nopatch b/SPECS/kernel/CVE-2024-42285.nopatch new file mode 100644 index 00000000000..880c869d5fb --- /dev/null +++ b/SPECS/kernel/CVE-2024-42285.nopatch @@ -0,0 +1,3 @@ +CVE-2024-42285 - patched in 5.15.165.1 - (generated by autopatch tool) +upstream aee2424246f9f1dadc33faa78990c1e2eb7826e4 - stable 557d035fe88d78dd51664f4dc0e1896c04c97cf6 + diff --git a/SPECS/kernel/CVE-2024-42301.nopatch b/SPECS/kernel/CVE-2024-42301.nopatch new file mode 100644 index 00000000000..ef2cfd80304 --- /dev/null +++ b/SPECS/kernel/CVE-2024-42301.nopatch @@ -0,0 +1,3 @@ +CVE-2024-42301 - patched in 5.15.165.1 - (generated by autopatch tool) +upstream ab11dac93d2d568d151b1918d7b84c2d02bacbd5 - stable c719b393374d3763e64900ee19aaed767d5a08d6 + diff --git a/SPECS/kernel/CVE-2024-42302.nopatch b/SPECS/kernel/CVE-2024-42302.nopatch new file mode 100644 index 00000000000..69d89407793 --- /dev/null +++ b/SPECS/kernel/CVE-2024-42302.nopatch @@ -0,0 +1,3 @@ +CVE-2024-42302 - patched in 5.15.165.1 - (generated by autopatch tool) +upstream 11a1f4bc47362700fcbde717292158873fb847ed - stable 2c111413f38ca5cf87557cab89f6d82b0e3433e7 + diff --git a/SPECS/kernel/CVE-2024-42309.nopatch b/SPECS/kernel/CVE-2024-42309.nopatch new file mode 100644 index 00000000000..c0de4965065 --- /dev/null +++ b/SPECS/kernel/CVE-2024-42309.nopatch @@ -0,0 +1,3 @@ +CVE-2024-42309 - patched in 5.15.165.1 - (generated by autopatch tool) +upstream 2df7aac81070987b0f052985856aa325a38debf6 - stable 7e52c62ff029f95005915c0a11863b5fb5185c8c + diff --git a/SPECS/kernel/CVE-2024-42310.nopatch b/SPECS/kernel/CVE-2024-42310.nopatch new file mode 100644 index 00000000000..6a3b1bd2e70 --- /dev/null +++ b/SPECS/kernel/CVE-2024-42310.nopatch @@ -0,0 +1,3 @@ +CVE-2024-42310 - patched in 5.15.165.1 - (generated by autopatch tool) +upstream cb520c3f366c77e8d69e4e2e2781a8ce48d98e79 - stable 08f45102c81ad8bc9f85f7a25e9f64e128edb87d + diff --git a/SPECS/kernel/CVE-2024-42313.nopatch b/SPECS/kernel/CVE-2024-42313.nopatch new file mode 100644 index 00000000000..53367c7ccc2 --- /dev/null +++ b/SPECS/kernel/CVE-2024-42313.nopatch @@ -0,0 +1,3 @@ +CVE-2024-42313 - patched in 5.15.165.1 - (generated by autopatch tool) +upstream a0157b5aa34eb43ec4c5510f9c260bbb03be937e - stable f8e9a63b982a8345470c225679af4ba86e4a7282 + diff --git a/SPECS/kernel/CVE-2024-43828.nopatch b/SPECS/kernel/CVE-2024-43828.nopatch new file mode 100644 index 00000000000..485a4a6997d --- /dev/null +++ b/SPECS/kernel/CVE-2024-43828.nopatch @@ -0,0 +1,3 @@ +CVE-2024-43828 - patched in 5.15.165.1 - (generated by autopatch tool) +upstream 907c3fe532253a6ef4eb9c4d67efb71fab58c706 - stable 0619f7750f2b178a1309808832ab20d85e0ad121 + diff --git a/SPECS/kernel/CVE-2024-43854.nopatch b/SPECS/kernel/CVE-2024-43854.nopatch new file mode 100644 index 00000000000..550c1c62a56 --- /dev/null +++ b/SPECS/kernel/CVE-2024-43854.nopatch @@ -0,0 +1,3 @@ +CVE-2024-43854 - patched in 5.15.165.1 - (generated by autopatch tool) +upstream 899ee2c3829c5ac14bfc7d3c4a5846c0b709b78f - stable cf6b45ea7a8df0f61bded1dc4a8561ac6ad143d2 + diff --git a/SPECS/kernel/CVE-2024-43855.nopatch b/SPECS/kernel/CVE-2024-43855.nopatch new file mode 100644 index 00000000000..a7e0cad37af --- /dev/null +++ b/SPECS/kernel/CVE-2024-43855.nopatch @@ -0,0 +1,4 @@ +CVE-2024-43855 - Introducing commit(s) not present in LTS - (generated by autopatch tool) +upstream fix commit: 611d5cbc0b35a752e657a83eebadf40d814d006b +upstream introducing commit: fa2bbff7b0b4e211fec5e5686ef96350690597b5 + diff --git a/SPECS/kernel/CVE-2024-43856.nopatch b/SPECS/kernel/CVE-2024-43856.nopatch new file mode 100644 index 00000000000..b5fccc880ae --- /dev/null +++ b/SPECS/kernel/CVE-2024-43856.nopatch @@ -0,0 +1,3 @@ +CVE-2024-43856 - patched in 5.15.165.1 - (generated by autopatch tool) +upstream 28e8b7406d3a1f5329a03aa25a43aa28e087cb20 - stable 87b34c8c94e29fa01d744e5147697f592998d954 + diff --git a/SPECS/kernel/CVE-2024-43858.nopatch b/SPECS/kernel/CVE-2024-43858.nopatch new file mode 100644 index 00000000000..651a087a728 --- /dev/null +++ b/SPECS/kernel/CVE-2024-43858.nopatch @@ -0,0 +1,3 @@ +CVE-2024-43858 - patched in 5.15.165.1 - (generated by autopatch tool) +upstream f73f969b2eb39ad8056f6c7f3a295fa2f85e313a - stable 63f7fdf733add82f126ea00e2e48f6eba15ac4b9 + diff --git a/SPECS/kernel/CVE-2024-43860.nopatch b/SPECS/kernel/CVE-2024-43860.nopatch new file mode 100644 index 00000000000..f9e5c673fff --- /dev/null +++ b/SPECS/kernel/CVE-2024-43860.nopatch @@ -0,0 +1,3 @@ +CVE-2024-43860 - patched in 5.15.165.1 - (generated by autopatch tool) +upstream 2fa26ca8b786888673689ccc9da6094150939982 - stable 4e13b7c23988c0a13fdca92e94296a3bc2ff9f21 + diff --git a/SPECS/kernel/CVE-2024-43889.nopatch b/SPECS/kernel/CVE-2024-43889.nopatch new file mode 100644 index 00000000000..42425e72190 --- /dev/null +++ b/SPECS/kernel/CVE-2024-43889.nopatch @@ -0,0 +1,3 @@ +CVE-2024-43889 - patched in 5.15.165.1 - (generated by autopatch tool) +upstream 6d45e1c948a8b7ed6ceddb14319af69424db730c - stable 8f5ffd2af7274853ff91d6cd62541191d9fbd10d + diff --git a/SPECS/kernel/CVE-2024-43902.nopatch b/SPECS/kernel/CVE-2024-43902.nopatch new file mode 100644 index 00000000000..0d8b28fad9e --- /dev/null +++ b/SPECS/kernel/CVE-2024-43902.nopatch @@ -0,0 +1,3 @@ +CVE-2024-43902 - patched in 5.15.165.1 - (generated by autopatch tool) +upstream 8092aa3ab8f7b737a34b71f91492c676a843043a - stable d0b8b23b9c2ebec693a36fea518d8f13493ad655 + diff --git a/SPECS/kernel/CVE-2024-43907.nopatch b/SPECS/kernel/CVE-2024-43907.nopatch new file mode 100644 index 00000000000..3358938e8f4 --- /dev/null +++ b/SPECS/kernel/CVE-2024-43907.nopatch @@ -0,0 +1,3 @@ +CVE-2024-43907 - patched in 5.15.165.1 - (generated by autopatch tool) +upstream d19fb10085a49b77578314f69fff21562f7cd054 - stable 0c065e50445aea2e0a1815f12e97ee49e02cbaac + diff --git a/SPECS/kernel/CVE-2024-43908.nopatch b/SPECS/kernel/CVE-2024-43908.nopatch new file mode 100644 index 00000000000..e9576ec6a9a --- /dev/null +++ b/SPECS/kernel/CVE-2024-43908.nopatch @@ -0,0 +1,3 @@ +CVE-2024-43908 - patched in 5.15.165.1 - (generated by autopatch tool) +upstream 4c11d30c95576937c6c35e6f29884761f2dddb43 - stable 56e848034ccabe44e8f22ffcf49db771c17b0d0a + diff --git a/SPECS/kernel/CVE-2024-43909.nopatch b/SPECS/kernel/CVE-2024-43909.nopatch new file mode 100644 index 00000000000..94038f2e515 --- /dev/null +++ b/SPECS/kernel/CVE-2024-43909.nopatch @@ -0,0 +1,3 @@ +CVE-2024-43909 - patched in 5.15.165.1 - (generated by autopatch tool) +upstream c02c1960c93eede587576625a1221205a68a904f - stable 37b9df457cbcf095963d18f17d6cb7dfa0a03fce + diff --git a/SPECS/kernel/CVE-2024-44934.nopatch b/SPECS/kernel/CVE-2024-44934.nopatch new file mode 100644 index 00000000000..fef5118ddcc --- /dev/null +++ b/SPECS/kernel/CVE-2024-44934.nopatch @@ -0,0 +1,3 @@ +CVE-2024-44934 - patched in 5.15.165.1 - (generated by autopatch tool) +upstream 92c4ee25208d0f35dafc3213cdf355fbe449e078 - stable 1e16828020c674b3be85f52685e8b80f9008f50f + diff --git a/SPECS/kernel/CVE-2024-44935.nopatch b/SPECS/kernel/CVE-2024-44935.nopatch new file mode 100644 index 00000000000..bee4bfa38cd --- /dev/null +++ b/SPECS/kernel/CVE-2024-44935.nopatch @@ -0,0 +1,3 @@ +CVE-2024-44935 - patched in 5.15.165.1 - (generated by autopatch tool) +upstream 9ab0faa7f9ffe31296dbb9bbe6f76c72c14eea18 - stable 54b303d8f9702b8ab618c5032fae886b16356928 + diff --git a/SPECS/kernel/config b/SPECS/kernel/config index dd55c0d1e05..1e78db239c5 100644 --- a/SPECS/kernel/config +++ b/SPECS/kernel/config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/x86_64 5.15.164.1 Kernel Configuration +# Linux/x86_64 5.15.167.1 Kernel Configuration # CONFIG_CC_VERSION_TEXT="gcc (GCC) 11.2.0" CONFIG_CC_IS_GCC=y @@ -5243,7 +5243,7 @@ CONFIG_USB_HCD_SSB=m CONFIG_USB_ACM=m # CONFIG_USB_PRINTER is not set CONFIG_USB_WDM=m -# CONFIG_USB_TMC is not set +CONFIG_USB_TMC=m # # NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may diff --git a/SPECS/kernel/config_aarch64 b/SPECS/kernel/config_aarch64 index f9bf261712d..80894ddb8d3 100644 --- a/SPECS/kernel/config_aarch64 +++ b/SPECS/kernel/config_aarch64 @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm64 5.15.164.1 Kernel Configuration +# Linux/arm64 5.15.167.1 Kernel Configuration # CONFIG_CC_VERSION_TEXT="gcc (GCC) 11.2.0" CONFIG_CC_IS_GCC=y @@ -374,6 +374,7 @@ CONFIG_ARM64_ERRATUM_2457168=y CONFIG_ARM64_WORKAROUND_TSB_FLUSH_FAILURE=y CONFIG_ARM64_ERRATUM_2054223=y CONFIG_ARM64_ERRATUM_2067961=y +CONFIG_ARM64_ERRATUM_3194386=y CONFIG_CAVIUM_ERRATUM_22375=y CONFIG_CAVIUM_ERRATUM_23144=y CONFIG_CAVIUM_ERRATUM_23154=y diff --git a/SPECS/kernel/kernel.signatures.json b/SPECS/kernel/kernel.signatures.json index 172e0493814..42ccdb1d085 100644 --- a/SPECS/kernel/kernel.signatures.json +++ b/SPECS/kernel/kernel.signatures.json @@ -1,9 +1,9 @@ { "Signatures": { "cbl-mariner-ca-20211013.pem": "5ef124b0924cb1047c111a0ecff1ae11e6ad7cac8d1d9b40f98f99334121f0b0", - "config": "a4e1b93311b05b42f33414d155c9f238f176ea32a699387e3cbeaf8dada0d567", - "config_aarch64": "42131349224a7e6b890637a816eb688e46251e4ed2a0f60363cd2d882b2b9e8c", + "config": "dc024483419fd8d1df7191058e01d80d7421d1c141f0bfc30f330201abb51ed3", + "config_aarch64": "784b95a886e48269d5da1ca7451ead489a84d8af9a8579874f9554741fa73916", "sha512hmac-openssl.sh": "02ab91329c4be09ee66d759e4d23ac875037c3b56e5a598e32fd1206da06a27f", - "kernel-5.15.164.1.tar.gz": "3634a7f014a0c821ada6cfb2ca6bdb2e18ae90fe9ce47b0adf8f81fd2852c3d8" + "kernel-5.15.167.1.tar.gz": "2f529a3abf4167d1de5f7dd73043827db2c08d647d924990843ee914b0558ee0" } } diff --git a/SPECS/kernel/kernel.spec b/SPECS/kernel/kernel.spec index 77cfbbcca26..e306af0fe70 100644 --- a/SPECS/kernel/kernel.spec +++ b/SPECS/kernel/kernel.spec @@ -27,7 +27,7 @@ Summary: Linux Kernel Name: kernel -Version: 5.15.164.1 +Version: 5.15.167.1 Release: 1%{?dist} License: GPLv2 Vendor: Microsoft Corporation @@ -426,6 +426,15 @@ ln -sf linux-%{uname_r}.cfg /boot/mariner.cfg %{_sysconfdir}/bash_completion.d/bpftool %changelog +* Wed Sep 18 2024 CBL-Mariner Servicing Account - 5.15.167.1-1 +- Auto-upgrade to 5.15.167.1 + +* Thu Aug 29 2024 CBL-Mariner Servicing Account - 5.15.165.1-1 +- Auto-upgrade to 5.15.165.1 + +* Tue Aug 27 2024 Chris Co - 5.15.164.1-2 +- Enable USB_TMC + * Fri Aug 09 2024 CBL-Mariner Servicing Account - 5.15.164.1-1 - Auto-upgrade to 5.15.164.1 diff --git a/SPECS/krb5/CVE-2023-36054.patch b/SPECS/krb5/CVE-2023-36054.patch new file mode 100644 index 00000000000..b26f2ff9ece --- /dev/null +++ b/SPECS/krb5/CVE-2023-36054.patch @@ -0,0 +1,61 @@ +From ef08b09c9459551aabbe7924fb176f1583053cdd Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Wed, 21 Jun 2023 10:57:39 -0400 +Subject: [PATCH] Ensure array count consistency in kadm5 RPC + +In _xdr_kadm5_principal_ent_rec(), ensure that n_key_data matches the +key_data array count when decoding. Otherwise when the structure is +later freed, xdr_array() could iterate over the wrong number of +elements, either leaking some memory or freeing uninitialized +pointers. Reported by Robert Morris. + +CVE-2023-36054: + +An authenticated attacker can cause a kadmind process to crash by +freeing uninitialized pointers. Remote code execution is unlikely. +An attacker with control of a kadmin server can cause a kadmin client +to crash by freeing uninitialized pointers. + +ticket: 9099 (new) +tags: pullup +target_version: 1.21-next +target_version: 1.20-next +--- + src/lib/kadm5/kadm_rpc_xdr.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/src/lib/kadm5/kadm_rpc_xdr.c b/src/lib/kadm5/kadm_rpc_xdr.c +index 0411c3fd3f4..287cae750f9 100644 +--- a/src/lib/kadm5/kadm_rpc_xdr.c ++++ b/src/lib/kadm5/kadm_rpc_xdr.c +@@ -390,6 +390,7 @@ _xdr_kadm5_principal_ent_rec(XDR *xdrs, kadm5_principal_ent_rec *objp, + int v) + { + unsigned int n; ++ bool_t r; + + if (!xdr_krb5_principal(xdrs, &objp->principal)) { + return (FALSE); +@@ -443,6 +444,9 @@ _xdr_kadm5_principal_ent_rec(XDR *xdrs, kadm5_principal_ent_rec *objp, + if (!xdr_krb5_int16(xdrs, &objp->n_key_data)) { + return (FALSE); + } ++ if (xdrs->x_op == XDR_DECODE && objp->n_key_data < 0) { ++ return (FALSE); ++ } + if (!xdr_krb5_int16(xdrs, &objp->n_tl_data)) { + return (FALSE); + } +@@ -451,9 +455,10 @@ _xdr_kadm5_principal_ent_rec(XDR *xdrs, kadm5_principal_ent_rec *objp, + return FALSE; + } + n = objp->n_key_data; +- if (!xdr_array(xdrs, (caddr_t *) &objp->key_data, +- &n, ~0, sizeof(krb5_key_data), +- xdr_krb5_key_data_nocontents)) { ++ r = xdr_array(xdrs, (caddr_t *) &objp->key_data, &n, objp->n_key_data, ++ sizeof(krb5_key_data), xdr_krb5_key_data_nocontents); ++ objp->n_key_data = n; ++ if (!r) { + return (FALSE); + } diff --git a/SPECS/krb5/CVE-2024-26461.patch b/SPECS/krb5/CVE-2024-26461.patch new file mode 100644 index 00000000000..f44347c3c51 --- /dev/null +++ b/SPECS/krb5/CVE-2024-26461.patch @@ -0,0 +1,195 @@ +From c929e7d18bdd47b9e9316de173359efc76810b29 Mon Sep 17 00:00:00 2001 +From: ankita +Date: Mon, 2 Sep 2024 12:34:38 +0530 +Subject: [PATCH] krb5: Fix CVE-2024-26458 and CVE-2024-26461 + +--- + src/lib/gssapi/krb5/k5sealv3.c | 56 +++++++++++++++------------------- + src/lib/rpc/pmap_rmt.c | 9 +++--- + 2 files changed, 29 insertions(+), 36 deletions(-) + +diff --git a/src/lib/gssapi/krb5/k5sealv3.c b/src/lib/gssapi/krb5/k5sealv3.c +index 1fcbdfb..d3210c1 100644 +--- a/src/lib/gssapi/krb5/k5sealv3.c ++++ b/src/lib/gssapi/krb5/k5sealv3.c +@@ -65,7 +65,7 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, + int conf_req_flag, int toktype) + { + size_t bufsize = 16; +- unsigned char *outbuf = 0; ++ unsigned char *outbuf = NULL; + krb5_error_code err; + int key_usage; + unsigned char acceptor_flag; +@@ -75,9 +75,13 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, + #endif + size_t ec; + unsigned short tok_id; +- krb5_checksum sum; ++ krb5_checksum sum = { 0 }; + krb5_key key; + krb5_cksumtype cksumtype; ++ krb5_data plain = empty_data(); ++ ++ token->value = NULL; ++ token->length = 0; + + acceptor_flag = ctx->initiate ? 0 : FLAG_SENDER_IS_ACCEPTOR; + key_usage = (toktype == KG_TOK_WRAP_MSG +@@ -107,14 +111,15 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, + #endif + + if (toktype == KG_TOK_WRAP_MSG && conf_req_flag) { +- krb5_data plain; + krb5_enc_data cipher; + size_t ec_max; + size_t encrypt_size; + + /* 300: Adds some slop. */ +- if (SIZE_MAX - 300 < message->length) +- return ENOMEM; ++ if (SIZE_MAX - 300 < message->length) { ++ err = ENOMEM; ++ goto cleanup; ++ } + ec_max = SIZE_MAX - message->length - 300; + if (ec_max > 0xffff) + ec_max = 0xffff; +@@ -126,20 +131,20 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, + #endif + err = alloc_data(&plain, message->length + 16 + ec); + if (err) +- return err; ++ goto cleanup; + + /* Get size of ciphertext. */ + encrypt_size = krb5_encrypt_size(plain.length, key->keyblock.enctype); + if (encrypt_size > SIZE_MAX / 2) { + err = ENOMEM; +- goto error; ++ goto cleanup; + } + bufsize = 16 + encrypt_size; + /* Allocate space for header plus encrypted data. */ + outbuf = gssalloc_malloc(bufsize); + if (outbuf == NULL) { +- free(plain.data); +- return ENOMEM; ++ err = ENOMEM; ++ goto cleanup; + } + + /* TOK_ID */ +@@ -164,11 +169,8 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, + cipher.ciphertext.length = bufsize - 16; + cipher.enctype = key->keyblock.enctype; + err = krb5_k_encrypt(context, key, key_usage, 0, &plain, &cipher); +- zap(plain.data, plain.length); +- free(plain.data); +- plain.data = 0; + if (err) +- goto error; ++ goto cleanup; + + /* Now that we know we're returning a valid token.... */ + ctx->seq_send++; +@@ -181,7 +183,6 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, + /* If the rotate fails, don't worry about it. */ + #endif + } else if (toktype == KG_TOK_WRAP_MSG && !conf_req_flag) { +- krb5_data plain; + size_t cksumsize; + + /* Here, message is the application-supplied data; message2 is +@@ -193,21 +194,19 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, + wrap_with_checksum: + err = alloc_data(&plain, message->length + 16); + if (err) +- return err; ++ goto cleanup; + + err = krb5_c_checksum_length(context, cksumtype, &cksumsize); + if (err) +- goto error; ++ goto cleanup; + + assert(cksumsize <= 0xffff); + + bufsize = 16 + message2->length + cksumsize; + outbuf = gssalloc_malloc(bufsize); + if (outbuf == NULL) { +- free(plain.data); +- plain.data = 0; + err = ENOMEM; +- goto error; ++ goto cleanup; + } + + /* TOK_ID */ +@@ -239,23 +238,15 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, + if (message2->length) + memcpy(outbuf + 16, message2->value, message2->length); + +- sum.contents = outbuf + 16 + message2->length; +- sum.length = cksumsize; +- + err = krb5_k_make_checksum(context, cksumtype, key, + key_usage, &plain, &sum); +- zap(plain.data, plain.length); +- free(plain.data); +- plain.data = 0; + if (err) { + zap(outbuf,bufsize); +- goto error; ++ goto cleanup; + } + if (sum.length != cksumsize) + abort(); + memcpy(outbuf + 16 + message2->length, sum.contents, cksumsize); +- krb5_free_checksum_contents(context, &sum); +- sum.contents = 0; + /* Now that we know we're actually generating the token... */ + ctx->seq_send++; + +@@ -285,12 +276,13 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, + + token->value = outbuf; + token->length = bufsize; +- return 0; ++ outbuf = NULL; ++ err = 0; + +-error: ++cleanup: ++ krb5_free_checksum_contents(context, &sum); ++ zapfree(plain.data, plain.length); + gssalloc_free(outbuf); +- token->value = NULL; +- token->length = 0; + return err; + } + +diff --git a/src/lib/rpc/pmap_rmt.c b/src/lib/rpc/pmap_rmt.c +index 8c7e30c..115a55a 100644 +--- a/src/lib/rpc/pmap_rmt.c ++++ b/src/lib/rpc/pmap_rmt.c +@@ -160,11 +160,12 @@ xdr_rmtcallres( + caddr_t port_ptr; + + port_ptr = (caddr_t)(void *)crp->port_ptr; +- if (xdr_reference(xdrs, &port_ptr, sizeof (uint32_t), +- xdr_u_int32) && xdr_u_int32(xdrs, &crp->resultslen)) { +- crp->port_ptr = (uint32_t *)(void *)port_ptr; ++ if (!xdr_reference(xdrs, &port_ptr, sizeof (uint32_t), ++ xdr_u_int32)) ++ return (FALSE); ++ crp->port_ptr = (uint32_t *)(void *)port_ptr; ++ if (xdr_u_int32(xdrs, &crp->resultslen)) + return ((*(crp->xdr_results))(xdrs, crp->results_ptr)); +- } + return (FALSE); + } + +-- +2.34.1 + diff --git a/SPECS/krb5/CVE-2024-37370.patch b/SPECS/krb5/CVE-2024-37370.patch new file mode 100644 index 00000000000..9a792507df1 --- /dev/null +++ b/SPECS/krb5/CVE-2024-37370.patch @@ -0,0 +1,575 @@ +From 548da160b52b25a106e9f6077d6a42c2c049586c Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Tue, 7 Mar 2023 00:19:33 -0500 +Subject: [PATCH] Add a simple DER support header + +--- + src/include/k5-der.h | 150 ++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 150 insertions(+) + create mode 100644 src/include/k5-der.h + +diff --git a/src/include/k5-der.h b/src/include/k5-der.h +new file mode 100644 +index 0000000000..b8371d9b4d +--- /dev/null ++++ b/src/include/k5-der.h +@@ -0,0 +1,150 @@ ++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* include/k5-der.h - Distinguished Encoding Rules (DER) declarations */ ++/* ++ * Copyright (C) 2023 by the Massachusetts ++ * Institute of Technology. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/* ++ * Most ASN.1 encoding and decoding is done using the table-driven framework in ++ * libkrb5. When that is not an option, these helpers can be used to encode ++ * and decode simple types. ++ */ ++ ++#ifndef K5_DER_H ++#define K5_DER_H ++ ++#include ++#include ++#include "k5-buf.h" ++#include "k5-input.h" ++ ++/* Return the number of bytes needed to encode len as a DER encoding length. */ ++static inline size_t ++k5_der_len_len(size_t len) ++{ ++ size_t llen; ++ ++ if (len < 128) ++ return 1; ++ llen = 1; ++ while (len > 0) { ++ len >>= 8; ++ llen++; ++ } ++ return llen; ++} ++ ++/* Return the number of bytes needed to encode a DER value (with identifier ++ * byte and length) for a given contents length. */ ++static inline size_t ++k5_der_value_len(size_t contents_len) ++{ ++ return 1 + k5_der_len_len(contents_len) + contents_len; ++} ++ ++/* Add a DER identifier byte (composed by the caller, including the ASN.1 ++ * class, tag, and constructed bit) and length. */ ++static inline void ++k5_der_add_taglen(struct k5buf *buf, uint8_t idbyte, size_t len) ++{ ++ uint8_t *p; ++ size_t llen = k5_der_len_len(len); ++ ++ p = k5_buf_get_space(buf, 1 + llen); ++ if (p == NULL) ++ return; ++ *p++ = idbyte; ++ if (len < 128) { ++ *p = len; ++ } else { ++ *p = 0x80 | (llen - 1); ++ /* Encode the length bytes backwards so the most significant byte is ++ * first. */ ++ p += llen; ++ while (len > 0) { ++ *--p = len & 0xFF; ++ len >>= 8; ++ } ++ } ++} ++ ++/* Add a DER value (identifier byte, length, and contents). */ ++static inline void ++k5_der_add_value(struct k5buf *buf, uint8_t idbyte, const void *contents, ++ size_t len) ++{ ++ k5_der_add_taglen(buf, idbyte, len); ++ k5_buf_add_len(buf, contents, len); ++} ++ ++/* ++ * If the next byte in in matches idbyte and the subsequent DER length is ++ * valid, advance in past the value, set *contents_out to the value contents, ++ * and return true. Otherwise return false. Only set an error on in if the ++ * next bytes matches idbyte but the ensuing length is invalid. contents_out ++ * may be aliased to in; it will only be written to on successful decoding of a ++ * value. ++ */ ++static inline bool ++k5_der_get_value(struct k5input *in, uint8_t idbyte, ++ struct k5input *contents_out) ++{ ++ uint8_t lenbyte, i; ++ size_t len; ++ const void *bytes; ++ ++ /* Do nothing if in is empty or the next byte doesn't match idbyte. */ ++ if (in->status || in->len == 0 || *in->ptr != idbyte) ++ return false; ++ ++ /* Advance past the identifier byte and decode the length. */ ++ (void)k5_input_get_byte(in); ++ lenbyte = k5_input_get_byte(in); ++ if (lenbyte < 128) { ++ len = lenbyte; ++ } else { ++ len = 0; ++ for (i = 0; i < (lenbyte & 0x7F); i++) { ++ if (len > (SIZE_MAX >> 8)) { ++ k5_input_set_status(in, EOVERFLOW); ++ return false; ++ } ++ len = (len << 8) | k5_input_get_byte(in); ++ } ++ } ++ ++ bytes = k5_input_get_bytes(in, len); ++ if (bytes == NULL) ++ return false; ++ k5_input_init(contents_out, bytes, len); ++ return true; ++} ++ ++#endif /* K5_DER_H */ + + +From 55fbf435edbe2e92dd8101669b1ce7144bc96fef Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Fri, 14 Jun 2024 10:56:12 -0400 +Subject: [PATCH] Fix vulnerabilities in GSS message token handling +In gss_krb5int_unseal_token_v3() and gss_krb5int_unseal_v3_iov(), +verify the Extra Count field of CFX wrap tokens against the encrypted +header. Reported by Jacob Champion. +In gss_krb5int_unseal_token_v3(), check for a decrypted plaintext +length too short to contain the encrypted header and extra count +bytes. Reported by Jacob Champion. +In kg_unseal_iov_token(), separately track the header IOV length and +complete token length when parsing the token's ASN.1 wrapper. This +fix contains modified versions of functions from k5-der.h and +util_token.c; this duplication will be cleaned up in a future commit. +CVE-2024-37370: +In MIT krb5 release 1.3 and later, an attacker can modify the +plaintext Extra Count field of a confidential GSS krb5 wrap token, +causing the unwrapped token to appear truncated to the application. +CVE-2024-37371: +In MIT krb5 release 1.3 and later, an attacker can cause invalid +memory reads by sending message tokens with invalid length fields. +(cherry picked from commit b0a2f8a5365f2eec3e27d78907de9f9d2c80505a) +diff --git a/src/lib/gssapi/krb5/k5sealv3.c b/src/lib/gssapi/krb5/k5sealv3.c +index e881eee..d3210c1 100644 +--- a/src/lib/gssapi/krb5/k5sealv3.c ++++ b/src/lib/gssapi/krb5/k5sealv3.c +@@ -400,10 +400,15 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr, + /* Don't use bodysize here! Use the fact that + cipher.ciphertext.length has been adjusted to the + correct length. */ ++ if (plain.length < 16 + ec) { ++ free(plain.data); ++ goto defective; ++ } + althdr = (unsigned char *)plain.data + plain.length - 16; + if (load_16_be(althdr) != KG2_TOK_WRAP_MSG + || althdr[2] != ptr[2] + || althdr[3] != ptr[3] ++ || load_16_be(althdr+4) != ec + || memcmp(althdr+8, ptr+8, 8)) { + free(plain.data); + goto defective; +diff --git a/src/lib/gssapi/krb5/k5sealv3iov.c b/src/lib/gssapi/krb5/k5sealv3iov.c +index 333ee12..f8e90c3 100644 +--- a/src/lib/gssapi/krb5/k5sealv3iov.c ++++ b/src/lib/gssapi/krb5/k5sealv3iov.c +@@ -402,9 +402,10 @@ gss_krb5int_unseal_v3_iov(krb5_context context, + if (load_16_be(althdr) != KG2_TOK_WRAP_MSG + || althdr[2] != ptr[2] + || althdr[3] != ptr[3] ++ || load_16_be(althdr + 4) != ec + || memcmp(althdr + 8, ptr + 8, 8) != 0) { + *minor_status = 0; +- return GSS_S_BAD_SIG; ++ return GSS_S_DEFECTIVE_TOKEN; + } + } else { + /* Verify checksum: note EC is checksum size here, not padding */ +diff --git a/src/lib/gssapi/krb5/k5unsealiov.c b/src/lib/gssapi/krb5/k5unsealiov.c +index 85a9574..21b5017 100644 +--- a/src/lib/gssapi/krb5/k5unsealiov.c ++++ b/src/lib/gssapi/krb5/k5unsealiov.c +@@ -25,6 +25,7 @@ + */ + + #include "k5-int.h" ++#include "k5-der.h" + #include "gssapiP_krb5.h" + + static OM_uint32 +@@ -265,6 +266,73 @@ cleanup: + return retval; + } + ++/* Similar to k5_der_get_value(), but output an unchecked content length ++ * instead of a k5input containing the contents. */ ++static inline bool ++get_der_tag(struct k5input *in, uint8_t idbyte, size_t *len_out) ++{ ++ uint8_t lenbyte, i; ++ size_t len; ++ ++ /* Do nothing if in is empty or the next byte doesn't match idbyte. */ ++ if (in->status || in->len == 0 || *in->ptr != idbyte) ++ return false; ++ ++ /* Advance past the identifier byte and decode the length. */ ++ (void)k5_input_get_byte(in); ++ lenbyte = k5_input_get_byte(in); ++ if (lenbyte < 128) { ++ len = lenbyte; ++ } else { ++ len = 0; ++ for (i = 0; i < (lenbyte & 0x7F); i++) { ++ if (len > (SIZE_MAX >> 8)) { ++ k5_input_set_status(in, EOVERFLOW); ++ return false; ++ } ++ len = (len << 8) | k5_input_get_byte(in); ++ } ++ } ++ ++ if (in->status) ++ return false; ++ ++ *len_out = len; ++ return true; ++} ++ ++/* ++ * Similar to g_verify_token_header() without toktype or flags, but do not read ++ * more than *header_len bytes of ASN.1 wrapper, and on output set *header_len ++ * to the remaining number of header bytes. Verify the outer DER tag's length ++ * against token_len, which may be larger (but not smaller) than *header_len. ++ */ ++static gss_int32 ++verify_detached_wrapper(const gss_OID_desc *mech, size_t *header_len, ++ uint8_t **header_in, size_t token_len) ++{ ++ struct k5input in, mech_der; ++ gss_OID_desc toid; ++ size_t len; ++ ++ k5_input_init(&in, *header_in, *header_len); ++ ++ if (get_der_tag(&in, 0x60, &len)) { ++ if (len != token_len - (in.ptr - *header_in)) ++ return G_BAD_TOK_HEADER; ++ if (!k5_der_get_value(&in, 0x06, &mech_der)) ++ return G_BAD_TOK_HEADER; ++ toid.elements = (uint8_t *)mech_der.ptr; ++ toid.length = mech_der.len; ++ if (!g_OID_equal(&toid, mech)) ++ return G_WRONG_MECH; ++ } ++ ++ *header_in = (uint8_t *)in.ptr; ++ *header_len = in.len; ++ return 0; ++} ++ + /* + * Caller must provide TOKEN | DATA | PADDING | TRAILER, except + * for DCE in which case it can just provide TOKEN | DATA (must +@@ -285,8 +353,7 @@ kg_unseal_iov_token(OM_uint32 *minor_status, + gss_iov_buffer_t header; + gss_iov_buffer_t padding; + gss_iov_buffer_t trailer; +- size_t input_length; +- unsigned int bodysize; ++ size_t input_length, hlen; + int toktype2; + + header = kg_locate_header_iov(iov, iov_count, toktype); +@@ -316,15 +383,14 @@ kg_unseal_iov_token(OM_uint32 *minor_status, + input_length += trailer->buffer.length; + } + +- code = g_verify_token_header(ctx->mech_used, +- &bodysize, &ptr, -1, +- input_length, 0); ++ hlen = header->buffer.length; ++ code = verify_detached_wrapper(ctx->mech_used, &hlen, &ptr, input_length); + if (code != 0) { + *minor_status = code; + return GSS_S_DEFECTIVE_TOKEN; + } + +- if (bodysize < 2) { ++ if (hlen < 2) { + *minor_status = (OM_uint32)G_BAD_TOK_HEADER; + return GSS_S_DEFECTIVE_TOKEN; + } +@@ -332,7 +398,7 @@ kg_unseal_iov_token(OM_uint32 *minor_status, + toktype2 = load_16_be(ptr); + + ptr += 2; +- bodysize -= 2; ++ hlen -= 2; + + switch (toktype2) { + case KG2_TOK_MIC_MSG: +diff --git a/src/tests/gssapi/t_invalid.c b/src/tests/gssapi/t_invalid.c +index 9876a11..4cd9c90 100644 +--- a/src/tests/gssapi/t_invalid.c ++++ b/src/tests/gssapi/t_invalid.c +@@ -36,31 +36,41 @@ + * + * 1. A pre-CFX wrap or MIC token processed with a CFX-only context causes a + * null pointer dereference. (The token must use SEAL_ALG_NONE or it will +- * be rejected.) ++ * be rejected.) This vulnerability also applies to IOV unwrap. + * +- * 2. A pre-CFX wrap or MIC token with fewer than 24 bytes after the ASN.1 ++ * 2. A CFX wrap token with a different value of EC between the plaintext and ++ * encrypted copies will be erroneously accepted, which allows a message ++ * truncation attack. This vulnerability also applies to IOV unwrap. ++ * ++ * 3. A CFX wrap token with a plaintext length fewer than 16 bytes causes an ++ * access before the beginning of the input buffer, possibly leading to a ++ * crash. ++ * ++ * 4. A CFX wrap token with a plaintext EC value greater than the plaintext ++ * length - 16 causes an integer underflow when computing the result length, ++ * likely causing a crash. ++ * ++ * 5. An IOV unwrap operation will overrun the header buffer if an ASN.1 ++ * wrapper longer than the header buffer is present. ++ * ++ * 6. A pre-CFX wrap or MIC token with fewer than 24 bytes after the ASN.1 + * header causes an input buffer overrun, usually leading to either a segv + * or a GSS_S_DEFECTIVE_TOKEN error due to garbage algorithm, filler, or +- * sequence number values. ++ * sequence number values. This vulnerability also applies to IOV unwrap. + * +- * 3. A pre-CFX wrap token with fewer than 16 + cksumlen bytes after the ASN.1 ++ * 7. A pre-CFX wrap token with fewer than 16 + cksumlen bytes after the ASN.1 + * header causes an integer underflow when computing the ciphertext length, + * leading to an allocation error on 32-bit platforms or a segv on 64-bit + * platforms. A pre-CFX MIC token of this size causes an input buffer + * overrun when comparing the checksum, perhaps leading to a segv. + * +- * 4. A pre-CFX wrap token with fewer than conflen + padlen bytes in the ++ * 8. A pre-CFX wrap token with fewer than conflen + padlen bytes in the + * ciphertext (where padlen is the last byte of the decrypted ciphertext) + * causes an integer underflow when computing the original message length, + * leading to an allocation error. + * +- * 5. In the mechglue, truncated encapsulation in the initial context token can ++ * 9. In the mechglue, truncated encapsulation in the initial context token can + * cause input buffer overruns in gss_accept_sec_context(). +- * +- * Vulnerabilities #1 and #2 also apply to IOV unwrap, although tokens with +- * fewer than 16 bytes after the ASN.1 header will be rejected. +- * Vulnerabilities #2 and #5 can only be robustly detected using a +- * memory-checking environment such as valgrind. + */ + + #include "k5-int.h" +@@ -109,17 +119,25 @@ struct test { + } + }; + +-/* Fake up enough of a CFX GSS context for gss_unwrap, using an AES key. */ ++static void * ++ealloc(size_t len) ++{ ++ void *ptr = calloc(len, 1); ++ ++ if (ptr == NULL) ++ abort(); ++ return ptr; ++} ++ ++/* Fake up enough of a CFX GSS context for gss_unwrap, using an AES key. ++ * The context takes ownership of subkey. */ + static gss_ctx_id_t +-make_fake_cfx_context() ++make_fake_cfx_context(krb5_key subkey) + { + gss_union_ctx_id_t uctx; + krb5_gss_ctx_id_t kgctx; +- krb5_keyblock kb; + +- kgctx = calloc(1, sizeof(*kgctx)); +- if (kgctx == NULL) +- abort(); ++ kgctx = ealloc(sizeof(*kgctx)); + kgctx->established = 1; + kgctx->proto = 1; + if (g_seqstate_init(&kgctx->seqstate, 0, 0, 0, 0) != 0) +@@ -128,15 +146,10 @@ make_fake_cfx_context() + kgctx->sealalg = -1; + kgctx->signalg = -1; + +- kb.enctype = ENCTYPE_AES128_CTS_HMAC_SHA1_96; +- kb.length = 16; +- kb.contents = (unsigned char *)"1234567887654321"; +- if (krb5_k_create_key(NULL, &kb, &kgctx->subkey) != 0) +- abort(); ++ kgctx->subkey = subkey; ++ kgctx->cksumtype = CKSUMTYPE_HMAC_SHA1_96_AES128; + +- uctx = calloc(1, sizeof(*uctx)); +- if (uctx == NULL) +- abort(); ++ uctx = ealloc(sizeof(*uctx)); + uctx->mech_type = &mech_krb5; + uctx->internal_ctx_id = (gss_ctx_id_t)kgctx; + return (gss_ctx_id_t)uctx; +@@ -150,9 +163,7 @@ make_fake_context(const struct test *test) + krb5_gss_ctx_id_t kgctx; + krb5_keyblock kb; + +- kgctx = calloc(1, sizeof(*kgctx)); +- if (kgctx == NULL) +- abort(); ++ kgctx = ealloc(sizeof(*kgctx)); + kgctx->established = 1; + if (g_seqstate_init(&kgctx->seqstate, 0, 0, 0, 0) != 0) + abort(); +@@ -174,9 +185,7 @@ make_fake_context(const struct test *test) + if (krb5_k_create_key(NULL, &kb, &kgctx->enc) != 0) + abort(); + +- uctx = calloc(1, sizeof(*uctx)); +- if (uctx == NULL) +- abort(); ++ uctx = ealloc(sizeof(*uctx)); + uctx->mech_type = &mech_krb5; + uctx->internal_ctx_id = (gss_ctx_id_t)kgctx; + return (gss_ctx_id_t)uctx; +@@ -206,9 +215,7 @@ make_token(unsigned char *token, size_t len, gss_buffer_t out) + + assert(mech_krb5.length == 9); + assert(len + 11 < 128); +- wrapped = malloc(len + 13); +- if (wrapped == NULL) +- abort(); ++ wrapped = ealloc(len + 13); + wrapped[0] = 0x60; + wrapped[1] = len + 11; + wrapped[2] = 0x06; +@@ -219,6 +226,18 @@ make_token(unsigned char *token, size_t len, gss_buffer_t out) + out->value = wrapped; + } + ++/* Create a 16-byte header for a CFX confidential wrap token to be processed by ++ * the fake CFX context. */ ++static void ++write_cfx_header(uint16_t ec, uint8_t *out) ++{ ++ memset(out, 0, 16); ++ store_16_be(KG2_TOK_WRAP_MSG, out); ++ out[2] = FLAG_WRAP_CONFIDENTIAL; ++ out[3] = 0xFF; ++ store_16_be(ec, out + 4); ++} ++ + /* Unwrap a superficially valid RFC 1964 token with a CFX-only context, with + * regular and IOV unwrap. */ + static void +@@ -250,6 +269,31 @@ test_bogus_1964_token(gss_ctx_id_t ctx) + free(in.value); + } + ++static void ++test_iov_large_asn1_wrapper(gss_ctx_id_t ctx) ++{ ++ OM_uint32 minor, major; ++ uint8_t databuf[10] = { 0 }; ++ gss_iov_buffer_desc iov[2]; ++ ++ /* ++ * In this IOV array, the header contains a DER tag with a dangling eight ++ * bytes of length field. The data IOV indicates a total token length ++ * sufficient to contain the length bytes. ++ */ ++ iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER; ++ iov[0].buffer.value = ealloc(2); ++ iov[0].buffer.length = 2; ++ memcpy(iov[0].buffer.value, "\x60\x88", 2); ++ iov[1].type = GSS_IOV_BUFFER_TYPE_DATA; ++ iov[1].buffer.value = databuf; ++ iov[1].buffer.length = 10; ++ major = gss_unwrap_iov(&minor, ctx, NULL, NULL, iov, 2); ++ if (major != GSS_S_DEFECTIVE_TOKEN) ++ abort(); ++ free(iov[0].buffer.value); ++} ++ + /* Process wrap and MIC tokens with incomplete headers. */ + static void + test_short_header(gss_ctx_id_t ctx) +@@ -399,9 +443,7 @@ try_accept(void *value, size_t len) + gss_ctx_id_t ctx = GSS_C_NO_CONTEXT; + + /* Copy the provided value to make input overruns more obvious. */ +- in.value = malloc(len); +- if (in.value == NULL) +- abort(); ++ in.value = ealloc(len); + memcpy(in.value, value, len); + in.length = len; + (void)gss_accept_sec_context(&minor, &ctx, GSS_C_NO_CREDENTIAL, &in, +@@ -436,11 +478,20 @@ test_short_encapsulation() + int + main(int argc, char **argv) + { ++ krb5_keyblock kb; ++ krb5_key cfx_subkey; + gss_ctx_id_t ctx; + size_t i; + +- ctx = make_fake_cfx_context(); ++ kb.enctype = ENCTYPE_AES128_CTS_HMAC_SHA1_96; ++ kb.length = 16; ++ kb.contents = (unsigned char *)"1234567887654321"; ++ if (krb5_k_create_key(NULL, &kb, &cfx_subkey) != 0) ++ abort(); ++ ++ ctx = make_fake_cfx_context(cfx_subkey); + test_bogus_1964_token(ctx); ++ test_iov_large_asn1_wrapper(ctx); + free_fake_context(ctx); + + for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) { diff --git a/SPECS/krb5/krb5.signatures.json b/SPECS/krb5/krb5.signatures.json index dc04ad0f0a2..c9df66d7b77 100644 --- a/SPECS/krb5/krb5.signatures.json +++ b/SPECS/krb5/krb5.signatures.json @@ -1,6 +1,6 @@ { "Signatures": { "krb5.conf": "54ce761ea22e55923f4b10b5a8ed306f98c579217b4253163437c33eec243720", - "krb5-1.21.3.tar.gz": "b7a4cd5ead67fb08b980b21abd150ff7217e85ea320c9ed0c6dadd304840ad35" + "krb5-1.19.4.tar.gz": "41f5981c5a4de0a26b3937e679a116cd5b3739641fd253124aac91f7179b54eb" } } diff --git a/SPECS/krb5/krb5.spec b/SPECS/krb5/krb5.spec index f842f5d4da4..f6702e0fc3c 100644 --- a/SPECS/krb5/krb5.spec +++ b/SPECS/krb5/krb5.spec @@ -3,8 +3,9 @@ Summary: The Kerberos newtork authentication system Name: krb5 -Version: 1.21.3 -Release: 1%{?dist} +Epoch: 1 +Version: 1.19.4 +Release: 3%{?dist} License: MIT Vendor: Microsoft Corporation Distribution: Mariner @@ -12,11 +13,14 @@ Group: System Environment/Security URL: https://web.mit.edu/kerberos/ Source0: https://kerberos.org/dist/%{name}/%{maj_version}/%{name}-%{version}.tar.gz Source1: krb5.conf +Patch0: CVE-2023-36054.patch +Patch1: CVE-2024-26461.patch +Patch2: CVE-2024-37370.patch BuildRequires: e2fsprogs-devel BuildRequires: openssl-devel Requires: e2fsprogs-libs Requires: openssl -Provides: %{name}-libs = %{version}-%{release} +Provides: %{name}-libs = %{epoch}:%{version}-%{release} %description Kerberos V5 is a trusted-third-party network authentication system, @@ -25,7 +29,7 @@ practice of clear text passwords. %package devel Summary: Libraries and header files for krb5 -Requires: %{name} = %{version}-%{release} +Requires: %{name} = %{epoch}:%{version}-%{release} Requires: e2fsprogs-devel %description devel @@ -34,7 +38,7 @@ Static libraries and header files for the support library for krb5 %package lang Summary: Additional language files for krb5 Group: System Environment/Security -Requires: %{name} = %{version}-%{release} +Requires: %{name} = %{epoch}:%{version}-%{release} %description lang These are the additional language files of krb5. @@ -44,6 +48,7 @@ These are the additional language files of krb5. %build cd src +sed -e 's@\^u}@^u cols 300}@' -i tests/dejagnu/config/default.exp CPPFLAGS="-D_GNU_SOURCE %{getenv:CPPFLAGS}" \ autoconf && ./configure \ @@ -125,6 +130,12 @@ make check %{_datarootdir}/locale/* %changelog +* Thu Sep 12 2024 Adit Jha - 1:1.19.4-3 +- Revert to 1.19.4, add epoch and add patch for CVE-2024-37371 and CVE-2024-37370 + +* Mon Sep 2 2024 Ankita Pareek - 1.21.3-2 +- Add patch for CVE-2024-26458 and CVE-2024-26461 + * Wed Jul 24 2024 CBL-Mariner Servicing Account - 1.21.3-1 - Auto-upgrade to 1.21.3 - CVE-2024-37371, CVE-2024-37370 diff --git a/SPECS/kube-vip-cloud-provider/kube-vip-cloud-provider.spec b/SPECS/kube-vip-cloud-provider/kube-vip-cloud-provider.spec index 344688e966c..24742036846 100644 --- a/SPECS/kube-vip-cloud-provider/kube-vip-cloud-provider.spec +++ b/SPECS/kube-vip-cloud-provider/kube-vip-cloud-provider.spec @@ -1,7 +1,7 @@ Summary: The Kube-Vip cloud provider functions as a general-purpose cloud provider for on-premises bare-metal or virtualized setups Name: kube-vip-cloud-provider Version: 0.0.2 -Release: 17%{?dist} +Release: 18%{?dist} License: ASL 2.0 URL: https://github.com/kube-vip/kube-vip-cloud-provider Group: Applications/Text @@ -49,6 +49,9 @@ go test -mod=vendor ./... %{_bindir}/kube-vip-cloud-provider %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 0.0.2-18 +- Bump release to rebuild with go 1.22.7 + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 0.0.2-17 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS/kubernetes/kubernetes.spec b/SPECS/kubernetes/kubernetes.spec index 273884434e5..7814bf23675 100644 --- a/SPECS/kubernetes/kubernetes.spec +++ b/SPECS/kubernetes/kubernetes.spec @@ -10,7 +10,7 @@ Summary: Microsoft Kubernetes Name: kubernetes Version: 1.28.4 -Release: 9%{?dist} +Release: 10%{?dist} License: ASL 2.0 Vendor: Microsoft Corporation Distribution: Mariner @@ -268,6 +268,9 @@ fi %{_exec_prefix}/local/bin/pause %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 1.28.4-10 +- Bump release to rebuild with go 1.22.7 + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 1.28.4-9 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS/kubevirt/CVE-2022-32149.patch b/SPECS/kubevirt/CVE-2022-32149.patch new file mode 100644 index 00000000000..9c597159cee --- /dev/null +++ b/SPECS/kubevirt/CVE-2022-32149.patch @@ -0,0 +1,59 @@ +From 434eadcdbc3b0256971992e8c70027278364c72c Mon Sep 17 00:00:00 2001 +From: Roland Shoemaker +Date: Fri, 2 Sep 2022 09:35:37 -0700 +Subject: [PATCH] language: reject excessively large Accept-Language strings + +The BCP 47 tag parser has quadratic time complexity due to inherent +aspects of its design. Since the parser is, by design, exposed to +untrusted user input, this can be leveraged to force a program to +consume significant time parsing Accept-Language headers. + +The parser cannot be easily rewritten to fix this behavior for +various reasons. Instead the solution implemented in this CL is to +limit the total complexity of tags passed into ParseAcceptLanguage +by limiting the number of dashes in the string to 1000. This should +be more than enough for the majority of real world use cases, where +the number of tags being sent is likely to be in the single digits. + +Thanks to the OSS-Fuzz project for discovering this issue and to Adam +Korczynski (ADA Logics) for writing the fuzz case and for reporting the +issue. + +Fixes CVE-2022-32149 +Fixes golang/go#56152 + +Change-Id: I7bda1d84cee2b945039c203f26869d58ee9374ae +Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1565112 +Reviewed-by: Damien Neil +Reviewed-by: Tatiana Bradley +Reviewed-on: https://go-review.googlesource.com/c/text/+/442235 +TryBot-Result: Gopher Robot +Auto-Submit: Roland Shoemaker +Run-TryBot: Roland Shoemaker +--- + vendor/golang.org/x/text/language/parse.go | 5 +++++ + 1 files changed, 5 insertions(+) + +diff --git a/vendor/golang.org/x/text/language/parse.go b/vendor/golang.org/x/text/language/parse.go +index 59b04100..b982d9e4 100644 +--- a/vendor/golang.org/x/text/language/parse.go ++++ b/vendor/golang.org/x/text/language/parse.go +@@ -147,6 +147,7 @@ func update(b *language.Builder, part ...interface{}) (err error) { + } + + var errInvalidWeight = errors.New("ParseAcceptLanguage: invalid weight") ++var errTagListTooLarge = errors.New("tag list exceeds max length") + + // ParseAcceptLanguage parses the contents of an Accept-Language header as + // defined in http://www.ietf.org/rfc/rfc2616.txt and returns a list of Tags and +@@ -164,6 +165,10 @@ func ParseAcceptLanguage(s string) (tag []Tag, q []float32, err error) { + } + }() + ++ if strings.Count(s, "-") > 1000 { ++ return nil, nil, errTagListTooLarge ++ } ++ + var entry string + for s != "" { + if entry, s = split(s, ','); entry == "" { diff --git a/SPECS/kubevirt/CVE-2023-26484.patch b/SPECS/kubevirt/CVE-2023-26484.patch new file mode 100644 index 00000000000..3a1f4a78230 --- /dev/null +++ b/SPECS/kubevirt/CVE-2023-26484.patch @@ -0,0 +1,389 @@ +From 5fc09595bb88f4e0ae2998dcc1a271cf810d77fc Mon Sep 17 00:00:00 2001 +From: Luboslav Pivarc +Date: Thu, 30 May 2024 10:37:24 +0200 +Subject: [PATCH 1/3] Node restiction + +Introduce NodeRestriction feature gate. This enables +us to check if a virt-handler request is authorized to +modify VMI. + +This feature requires following Kubernetes feature gate +ServiceAccountTokenPodNodeInfo. The feature gate is available +in 1.30 as Beta. + +Signed-off-by: Luboslav Pivarc +--- + pkg/virt-api/webhooks/utils.go | 18 +- + .../validating-webhook/admitters/BUILD.bazel | 2 + + .../admitters/vmi-update-admitter.go | 43 ++++- + .../admitters/vmi-update-admitter_test.go | 156 ++++++++++++++++++ + pkg/virt-config/feature-gates.go | 11 ++ + tests/decorators/decorators.go | 3 + + 8 files changed, 336 insertions(+), 6 deletions(-) + create mode 100644 tests/infrastructure/security.go + +diff --git a/pkg/virt-api/webhooks/utils.go b/pkg/virt-api/webhooks/utils.go +index 1307cb366fdb..e6ee54431f91 100644 +--- a/pkg/virt-api/webhooks/utils.go ++++ b/pkg/virt-api/webhooks/utils.go +@@ -79,7 +79,11 @@ type Informers struct { + DataSourceInformer cache.SharedIndexInformer + } + +-func IsKubeVirtServiceAccount(serviceAccount string) bool { ++func IsComponentServiceAccount(serviceAccount, namespace, component string) bool { ++ return serviceAccount == fmt.Sprintf("system:serviceaccount:%s:%s", namespace, component) ++} ++ ++func GetNamespace() string { + ns, err := clientutil.GetNamespace() + logger := log.DefaultLogger() + +@@ -87,11 +91,14 @@ func IsKubeVirtServiceAccount(serviceAccount string) bool { + logger.Info("Failed to get namespace. Fallback to default: 'kubevirt'") + ns = "kubevirt" + } ++ return ns ++} + +- prefix := fmt.Sprintf("system:serviceaccount:%s", ns) +- return serviceAccount == fmt.Sprintf("%s:%s", prefix, rbac.ApiServiceAccountName) || +- serviceAccount == fmt.Sprintf("%s:%s", prefix, rbac.HandlerServiceAccountName) || +- serviceAccount == fmt.Sprintf("%s:%s", prefix, rbac.ControllerServiceAccountName) ++func IsKubeVirtServiceAccount(serviceAccount string) bool { ++ ns := GetNamespace() ++ return IsComponentServiceAccount(serviceAccount, ns, rbac.ApiServiceAccountName) || ++ IsComponentServiceAccount(serviceAccount, ns, rbac.HandlerServiceAccountName) || ++ IsComponentServiceAccount(serviceAccount, ns, rbac.ControllerServiceAccountName) + } + + func IsARM64() bool { +diff --git a/pkg/virt-api/webhooks/validating-webhook/admitters/BUILD.bazel b/pkg/virt-api/webhooks/validating-webhook/admitters/BUILD.bazel +index 1a71fdf6eab2..8c507b7d9bc2 100644 +--- a/pkg/virt-api/webhooks/validating-webhook/admitters/BUILD.bazel ++++ b/pkg/virt-api/webhooks/validating-webhook/admitters/BUILD.bazel +@@ -43,6 +43,7 @@ go_library( + "//pkg/virt-config:go_default_library", + "//pkg/virt-handler/node-labeller/util:go_default_library", + "//pkg/virt-operator/resource/generate/rbac:go_default_library", ++ "//pkg/virt-operator/resource/generate/components:go_default_library", + "//staging/src/kubevirt.io/api/clone:go_default_library", + "//staging/src/kubevirt.io/api/clone/v1alpha1:go_default_library", + "//staging/src/kubevirt.io/api/core:go_default_library", +@@ -135,6 +136,7 @@ go_test( + "//vendor/github.com/golang/mock/gomock:go_default_library", + "//vendor/github.com/onsi/ginkgo/v2:go_default_library", + "//vendor/github.com/onsi/gomega:go_default_library", ++ "//vendor/github.com/onsi/gomega/gstruct:go_default_library", + "//vendor/github.com/onsi/gomega/types:go_default_library", + "//vendor/k8s.io/api/admission/v1:go_default_library", + "//vendor/k8s.io/api/authentication/v1:go_default_library", +diff --git a/pkg/virt-api/webhooks/validating-webhook/admitters/vmi-update-admitter.go b/pkg/virt-api/webhooks/validating-webhook/admitters/vmi-update-admitter.go +index b33f167eb37b..2c56c4be80dd 100644 +--- a/pkg/virt-api/webhooks/validating-webhook/admitters/vmi-update-admitter.go ++++ b/pkg/virt-api/webhooks/validating-webhook/admitters/vmi-update-admitter.go +@@ -29,18 +29,20 @@ import ( + + "kubevirt.io/kubevirt/pkg/virt-api/webhooks" + virtconfig "kubevirt.io/kubevirt/pkg/virt-config" ++ "kubevirt.io/kubevirt/pkg/virt-operator/resource/generate/rbac" + + v1 "kubevirt.io/api/core/v1" + + webhookutils "kubevirt.io/kubevirt/pkg/util/webhooks" + ) + ++const nodeNameExtraInfo = "authentication.kubernetes.io/node-name" ++ + type VMIUpdateAdmitter struct { + ClusterConfig *virtconfig.ClusterConfig + } + + func (admitter *VMIUpdateAdmitter) Admit(ar *admissionv1.AdmissionReview) *admissionv1.AdmissionResponse { +- + if resp := webhookutils.ValidateSchema(v1.VirtualMachineInstanceGroupVersionKind, ar.Request.Object.Raw); resp != nil { + return resp + } +@@ -50,6 +52,45 @@ func (admitter *VMIUpdateAdmitter) Admit(ar *admissionv1.AdmissionReview) *admis + return webhookutils.ToAdmissionResponseError(err) + } + ++ if admitter.ClusterConfig.NodeRestrictionEnabled() && webhooks.IsComponentServiceAccount(ar.Request.UserInfo.Username, webhooks.GetNamespace(), rbac.HandlerServiceAccountName) { ++ values, exist := ar.Request.UserInfo.Extra[nodeNameExtraInfo] ++ if exist && len(values) > 0 { ++ nodeName := values[0] ++ sourceNode := oldVMI.Status.NodeName ++ targetNode := "" ++ if oldVMI.Status.MigrationState != nil { ++ targetNode = oldVMI.Status.MigrationState.TargetNode ++ } ++ ++ // Check that source or target is making this request ++ if nodeName != sourceNode && (targetNode == "" || nodeName != targetNode) { ++ return webhookutils.ToAdmissionResponse([]metav1.StatusCause{ ++ { ++ Type: metav1.CauseTypeFieldValueInvalid, ++ Message: "Node restriction, virt-handler is only allowed to modify VMIs it owns", ++ }, ++ }) ++ } ++ ++ // Check that handler is not setting target ++ if targetNode == "" && newVMI.Status.MigrationState != nil && newVMI.Status.MigrationState.TargetNode != targetNode { ++ return webhookutils.ToAdmissionResponse([]metav1.StatusCause{ ++ { ++ Type: metav1.CauseTypeFieldValueInvalid, ++ Message: "Node restriction, virt-handler is not allowed to set target node", ++ }, ++ }) ++ } ++ } else { ++ return webhookutils.ToAdmissionResponse([]metav1.StatusCause{ ++ { ++ Type: metav1.CauseTypeFieldValueInvalid, ++ Message: "Node restriction failed, virt-handler service account is missing node name", ++ }, ++ }) ++ } ++ } ++ + // Reject VMI update if VMI spec changed + if !equality.Semantic.DeepEqual(newVMI.Spec, oldVMI.Spec) { + // Only allow the KubeVirt SA to modify the VMI spec, since that means it went through the sub resource. +diff --git a/pkg/virt-api/webhooks/validating-webhook/admitters/vmi-update-admitter_test.go b/pkg/virt-api/webhooks/validating-webhook/admitters/vmi-update-admitter_test.go +index a12cd35a4207..edfe94022436 100644 +--- a/pkg/virt-api/webhooks/validating-webhook/admitters/vmi-update-admitter_test.go ++++ b/pkg/virt-api/webhooks/validating-webhook/admitters/vmi-update-admitter_test.go +@@ -25,6 +25,7 @@ import ( + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" ++ "github.com/onsi/gomega/gstruct" + "github.com/onsi/gomega/types" + admissionv1 "k8s.io/api/admission/v1" + authv1 "k8s.io/api/authentication/v1" +@@ -76,6 +77,161 @@ var _ = Describe("Validating VMIUpdate Admitter", func() { + config, _, _ := testutils.NewFakeClusterConfigUsingKV(kv) + vmiUpdateAdmitter := &VMIUpdateAdmitter{config} + ++ Context("Node restriction", func() { ++ mustMarshal := func(vmi *v1.VirtualMachineInstance) []byte { ++ b, err := json.Marshal(vmi) ++ Expect(err).To(Not(HaveOccurred())) ++ return b ++ } ++ ++ admissionWithCustomUpdate := func(vmi, updatedVMI *v1.VirtualMachineInstance, handlernode string) *admissionv1.AdmissionReview { ++ newVMIBytes := mustMarshal(updatedVMI) ++ oldVMIBytes := mustMarshal(vmi) ++ return &admissionv1.AdmissionReview{ ++ Request: &admissionv1.AdmissionRequest{ ++ UserInfo: authv1.UserInfo{ ++ Username: "system:serviceaccount:kubevirt:kubevirt-handler", ++ Extra: map[string]authv1.ExtraValue{ ++ "authentication.kubernetes.io/node-name": {handlernode}, ++ }, ++ }, ++ Resource: webhooks.VirtualMachineInstanceGroupVersionResource, ++ Object: runtime.RawExtension{ ++ Raw: newVMIBytes, ++ }, ++ OldObject: runtime.RawExtension{ ++ Raw: oldVMIBytes, ++ }, ++ Operation: admissionv1.Update, ++ }, ++ } ++ } ++ ++ admission := func(vmi *v1.VirtualMachineInstance, handlernode string) *admissionv1.AdmissionReview { ++ updatedVMI := vmi.DeepCopy() ++ if updatedVMI.Labels == nil { ++ updatedVMI.Labels = map[string]string{} ++ } ++ updatedVMI.Labels["allowed.io"] = "value" ++ return admissionWithCustomUpdate(vmi, updatedVMI, handlernode) ++ } ++ ++ Context("with Node Restriction feature gate enabled", func() { ++ BeforeEach(func() { enableFeatureGate(virtconfig.NodeRestrictionGate) }) ++ ++ shouldNotAllowCrossNodeRequest := And( ++ WithTransform(func(resp *admissionv1.AdmissionResponse) bool { return resp.Allowed }, ++ BeFalse(), ++ ), ++ WithTransform(func(resp *admissionv1.AdmissionResponse) []metav1.StatusCause { return resp.Result.Details.Causes }, ++ ContainElement( ++ gstruct.MatchFields(gstruct.IgnoreExtras, gstruct.Fields{ ++ "Message": Equal("Node restriction, virt-handler is only allowed to modify VMIs it owns"), ++ }), ++ ), ++ ), ++ ) ++ ++ shouldBeAllowed := WithTransform(func(resp *admissionv1.AdmissionResponse) bool { return resp.Allowed }, ++ BeTrue(), ++ ) ++ ++ DescribeTable("and NodeName set", func(handlernode string, matcher types.GomegaMatcher) { ++ vmi := api.NewMinimalVMI("testvmi") ++ vmi.Status.NodeName = "got" ++ ++ resp := vmiUpdateAdmitter.Admit(admission(vmi, handlernode)) ++ Expect(resp).To(matcher) ++ }, ++ Entry("should deny request if handler is on different node", "diff", ++ shouldNotAllowCrossNodeRequest, ++ ), ++ Entry("should allow request if handler is on same node", "got", ++ shouldBeAllowed, ++ ), ++ ) ++ ++ DescribeTable("and TargetNode set", func(handlernode string, matcher types.GomegaMatcher) { ++ vmi := api.NewMinimalVMI("testvmi") ++ vmi.Status.NodeName = "got" ++ vmi.Status.MigrationState = &v1.VirtualMachineInstanceMigrationState{ ++ TargetNode: "git", ++ } ++ ++ resp := vmiUpdateAdmitter.Admit(admission(vmi, handlernode)) ++ Expect(resp).To(matcher) ++ }, ++ Entry("should deny request if handler is on different node", "diff", ++ shouldNotAllowCrossNodeRequest, ++ ), ++ Entry("should allow request if handler is on same node", "git", ++ shouldBeAllowed, ++ ), ++ ) ++ ++ DescribeTable("and both NodeName and TargetNode set", func(handlernode string, matcher types.GomegaMatcher) { ++ vmi := api.NewMinimalVMI("testvmi") ++ vmi.Status.NodeName = "got" ++ vmi.Status.MigrationState = &v1.VirtualMachineInstanceMigrationState{ ++ TargetNode: "target", ++ } ++ ++ resp := vmiUpdateAdmitter.Admit(admission(vmi, handlernode)) ++ Expect(resp).To(matcher) ++ }, ++ Entry("should deny request if handler is on different node", "diff", ++ shouldNotAllowCrossNodeRequest, ++ ), ++ Entry("should allow request if handler is on source node", "got", ++ shouldBeAllowed, ++ ), ++ ++ Entry("should allow request if handler is on target node", "target", ++ shouldBeAllowed, ++ ), ++ ) ++ ++ It("should allow finalize migration", func() { ++ vmi := api.NewMinimalVMI("testvmi") ++ vmi.Status.NodeName = "got" ++ vmi.Status.MigrationState = &v1.VirtualMachineInstanceMigrationState{ ++ TargetNode: "target", ++ } ++ ++ updatedVMI := vmi.DeepCopy() ++ updatedVMI.Status.NodeName = "target" ++ ++ resp := vmiUpdateAdmitter.Admit(admissionWithCustomUpdate(vmi, updatedVMI, "got")) ++ Expect(resp.Allowed).To(BeTrue()) ++ }) ++ ++ It("should not allow to set targetNode to source handler", func() { ++ vmi := api.NewMinimalVMI("testvmi") ++ vmi.Status.NodeName = "got" ++ ++ updatedVMI := vmi.DeepCopy() ++ updatedVMI.Status.MigrationState = &v1.VirtualMachineInstanceMigrationState{ ++ TargetNode: "target", ++ } ++ resp := vmiUpdateAdmitter.Admit(admissionWithCustomUpdate(vmi, updatedVMI, "got")) ++ Expect(resp.Allowed).To(BeFalse()) ++ }) ++ }) ++ ++ DescribeTable("with Node Restriction feature gate disabled should allow different handler", func(migrationState *v1.VirtualMachineInstanceMigrationState) { ++ vmi := api.NewMinimalVMI("testvmi") ++ vmi.Status.NodeName = "got" ++ vmi.Status.MigrationState = migrationState ++ ++ resp := vmiUpdateAdmitter.Admit(admission(vmi, "diff")) ++ Expect(resp.Allowed).To(BeTrue()) ++ }, ++ Entry("when TargetNode is not set", nil), ++ Entry("when TargetNode is set", &v1.VirtualMachineInstanceMigrationState{TargetNode: "git"}), ++ ) ++ ++ }) ++ + DescribeTable("should reject documents containing unknown or missing fields for", func(data string, validationResult string, gvr metav1.GroupVersionResource, review func(ar *admissionv1.AdmissionReview) *admissionv1.AdmissionResponse) { + input := map[string]interface{}{} + json.Unmarshal([]byte(data), &input) +diff --git a/pkg/virt-config/feature-gates.go b/pkg/virt-config/feature-gates.go +index f1b7ecfb2ad2..71551da7de7b 100644 +--- a/pkg/virt-config/feature-gates.go ++++ b/pkg/virt-config/feature-gates.go +@@ -85,6 +85,13 @@ const ( + // KubevirtSeccompProfile indicate that Kubevirt will install its custom profile and + // user can tell Kubevirt to use it + KubevirtSeccompProfile = "KubevirtSeccompProfile" ++ // Owner: @xpivarc ++ // Alpha: v1.3.0 ++ // ++ // NodeRestriction enables Kubelet's like NodeRestriction but for Kubevirt's virt-handler. ++ // This feature requires following Kubernetes feature gate "ServiceAccountTokenPodNodeInfo". The feature gate is available ++ // in Kubernetes 1.30 as Beta. ++ NodeRestrictionGate = "NodeRestriction" + ) + + var deprecatedFeatureGates = [...]string{ +@@ -256,3 +263,7 @@ func (config *ClusterConfig) VolumesUpdateStrategyEnabled() bool { + func (config *ClusterConfig) KubevirtSeccompProfileEnabled() bool { + return config.isFeatureGateEnabled(KubevirtSeccompProfile) + } ++ ++func (config *ClusterConfig) NodeRestrictionEnabled() bool { ++ return config.isFeatureGateEnabled(NodeRestrictionGate) ++} +diff --git a/tests/decorators/decorators.go b/tests/decorators/decorators.go +index 6f728b176c0e..a39c77f569b7 100644 +--- a/tests/decorators/decorators.go ++++ b/tests/decorators/decorators.go +@@ -56,4 +56,7 @@ var ( + Upgrade = []interface{}{Label("Upgrade")} + CustomSELinux = []interface{}{Label("CustomSELinux")} + Istio = []interface{}{Label("Istio")} ++ ++ // Kubernetes versions ++ Kubernetes130 = []interface{}{Label("kubernetes130")} + ) +From d1d26f9cba0decb69e3e610971ed70edba53d906 Mon Sep 17 00:00:00 2001 +From: Luboslav Pivarc +Date: Tue, 11 Jun 2024 13:47:46 +0200 +Subject: [PATCH 3/3] Run NodeIsolation tests only on 1.30 lane + +Signed-off-by: Luboslav Pivarc +--- + automation/test.sh | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/automation/test.sh b/automation/test.sh +index b3bf13dacc55..4ea306a710bf 100755 +--- a/automation/test.sh ++++ b/automation/test.sh +@@ -455,6 +455,10 @@ if [[ -z ${KUBEVIRT_E2E_FOCUS} && -z ${KUBEVIRT_E2E_SKIP} && -z ${label_filter} + else + label_filter='(!(Multus,SRIOV,Macvtap,GPU,VGPU))' + fi ++ ++ if [[ ! $TARGET =~ k8s-1\.3[0-9].* ]]; then ++ add_to_label_filter "(!kubernetes130)" "&&" ++ fi + fi + + add_to_label_filter() { diff --git a/SPECS/kubevirt/Hotplug_detach_grace_period.patch b/SPECS/kubevirt/Hotplug_detach_grace_period.patch deleted file mode 100644 index 86fc07d0dce..00000000000 --- a/SPECS/kubevirt/Hotplug_detach_grace_period.patch +++ /dev/null @@ -1,194 +0,0 @@ -diff --git a/pkg/virt-launcher/virtwrap/manager.go b/pkg/virt-launcher/virtwrap/manager.go -index 63d8d43d2..0e608c4bb 100644 ---- a/pkg/virt-launcher/virtwrap/manager.go -+++ b/pkg/virt-launcher/virtwrap/manager.go -@@ -97,6 +97,11 @@ const ( - const maxConcurrentHotplugHostDevices = 1 - const maxConcurrentMemoryDumps = 1 - -+// TODO: Make this configurable from the VMI object? -+const hotplugDetachmentGracePeriod = 5 * time.Second -+ -+const hotplugDetachmentVerbosity = 4 -+ - type contextStore struct { - ctx context.Context - cancel context.CancelFunc -@@ -142,6 +147,7 @@ type LibvirtDomainManager struct { - - hotplugHostDevicesInProgress chan struct{} - memoryDumpInProgress chan struct{} -+ cancelDiskDetachChannels map[string]chan struct{} - - virtShareDir string - ephemeralDiskDir string -@@ -204,6 +210,7 @@ func newLibvirtDomainManager(connection cli.Connection, virtShareDir, ephemeralD - cancelSafetyUnfreezeChan: make(chan struct{}), - migrateInfoStats: &stats.DomainJobInfo{}, - metadataCache: metadataCache, -+ cancelDiskDetachChannels: make(map[string]chan struct{}), - } - - manager.hotplugHostDevicesInProgress = make(chan struct{}, maxConcurrentHotplugHostDevices) -@@ -828,11 +835,11 @@ func (l *LibvirtDomainManager) generateConverterContext(vmi *v1.VirtualMachineIn - } - - func (l *LibvirtDomainManager) SyncVMI(vmi *v1.VirtualMachineInstance, allowEmulation bool, options *cmdv1.VirtualMachineOptions) (*api.DomainSpec, error) { -+ - l.domainModifyLock.Lock() - defer l.domainModifyLock.Unlock() - - logger := log.Log.Object(vmi) -- - domain := &api.Domain{} - - c, err := l.generateConverterContext(vmi, allowEmulation, options, false) -@@ -922,19 +929,94 @@ func (l *LibvirtDomainManager) SyncVMI(vmi *v1.VirtualMachineInstance, allowEmul - return nil, err - } - -+ // Get list of disks that should be detached -+ detachedDisks := getDetachedDisks(vmi.Name, vmi.Namespace, oldSpec.Devices.Disks, domain.Spec.Devices.Disks) -+ logger.V(hotplugDetachmentVerbosity).Infof("Hotplug detached disks: %+v", len(detachedDisks)) -+ -+ // Check list of detached disks against the list of detachment goroutines. Cancel the goroutines -+ // that are no longer needed. -+ for cancelDiskDetachChannelName, cancelDiskDetachChannel := range l.cancelDiskDetachChannels { -+ if _, ok := detachedDisks[cancelDiskDetachChannelName]; ok { -+ // If disk is already a detach goroutine and in the detachedDisk list, do not cancel -+ // the goroutine. -+ logger.V(hotplugDetachmentVerbosity).Infof("Hotplug detach stil requested, continue grace period = [%+v]", cancelDiskDetachChannelName) -+ } else { -+ // If disk is already a detach goroutine and is no longer in detachedDisk list, it no -+ // longer needs to be detached. Signal detach cancellation and remove from detachedDisks -+ // list. -+ logger.V(hotplugDetachmentVerbosity).Infof("Hotplug detach not longer needed, cancel it [%+v]", cancelDiskDetachChannelName) -+ // Signal detach goutine to cancel -+ cancelDiskDetachChannel <- struct{}{} -+ // Remove from detachedDisks list so detach goutine is not recreated -+ delete(detachedDisks, cancelDiskDetachChannelName) -+ } -+ } - // Look up all the disks to detach -- for _, detachDisk := range getDetachedDisks(oldSpec.Devices.Disks, domain.Spec.Devices.Disks) { -- logger.V(1).Infof("Detaching disk %s, target %s", detachDisk.Alias.GetName(), detachDisk.Target.Device) -+ for detachDiskKey, detachDisk := range detachedDisks { -+ - detachBytes, err := xml.Marshal(detachDisk) - if err != nil { - logger.Reason(err).Error("marshalling detached disk failed") - return nil, err - } -- err = dom.DetachDeviceFlags(strings.ToLower(string(detachBytes)), affectLiveAndConfigLibvirtFlags) -- if err != nil { -- logger.Reason(err).Error("detaching device") -- return nil, err -- } -+ -+ // Create goroutine to do detachment so we can wait to see if the disk is reattached. -+ go func(namespacedDiskName, detachDiskName, detachDiskTargetDevice, domainName string, detachBytes []byte) { -+ logger.V(hotplugDetachmentVerbosity).Infof("Potentially detaching hotplug disk %s", namespacedDiskName) -+ // Claim mutex again to work on protected data like the channels map and the domain. -+ l.domainModifyLock.Lock() -+ // If channel has already been created, a goroutine is already waiting for the disk to be detached. Exit -+ // so there aren't multiple goroutines waiting to detach the same disk. -+ if _, ok := l.cancelDiskDetachChannels[namespacedDiskName]; ok { -+ logger.V(hotplugDetachmentVerbosity).Infof("Potential hotplug disk detaching already handled: %s", namespacedDiskName) -+ // Unlock the mutex so protected data can be accessed -+ l.domainModifyLock.Unlock() -+ return -+ } -+ // There are no other goroutines waiting to detach this disk, create a channel enable subsequent calls to -+ // SyncVMI to cancel this detach (if attach is requested within the grace period: 5 seconds) -+ cancelChannel := make(chan struct{}) -+ l.cancelDiskDetachChannels[namespacedDiskName] = cancelChannel -+ // Unlock the mutex during the grace period wait so SyncVMI can continue to run -+ l.domainModifyLock.Unlock() -+ -+ doDetach := false -+ // Wait for either the grace period to expire (in which case: proceed to detach) or for the attach channel -+ // to be triggered (in which case: cancel the detach) -+ select { -+ case <-cancelChannel: -+ // Disk attach has been requested within the grace period, cancel the detach -+ logger.V(hotplugDetachmentVerbosity).Infof("Potential hotplug disk detaching was cancelled: %s", namespacedDiskName) -+ case <-time.After(hotplugDetachmentGracePeriod): -+ // Grace period has expired without an attach request, proceed to detach -+ doDetach = true -+ } -+ -+ // Claim mutex again to work on protected data like the channels map and the domain. -+ l.domainModifyLock.Lock() -+ // Ensure that the detach cancel channel is cleared and the mutex is unlocked before exiting -+ defer func() { -+ // Detach request has been handled, remove channel from map -+ delete(l.cancelDiskDetachChannels, namespacedDiskName) -+ // Unlock the mutex so protected data can be accessed -+ l.domainModifyLock.Unlock() -+ }() -+ -+ if doDetach { -+ // Detach the volume -+ logger.V(1).Infof("Detaching disk %s, target %s", detachDiskName, detachDiskTargetDevice) -+ dom, err := l.virConn.LookupDomainByName(domainName) -+ if err != nil { -+ logger.Reason(err).Error("getting domain for device detach") -+ return -+ } -+ err = dom.DetachDeviceFlags(strings.ToLower(string(detachBytes)), affectLiveAndConfigLibvirtFlags) -+ if err != nil { -+ logger.Reason(err).Error("detaching device") -+ } -+ dom.Free() -+ } -+ }(detachDiskKey, detachDisk.Alias.GetName(), detachDisk.Target.Device, domain.Spec.Name, detachBytes) - } - // Look up all the disks to attach - for _, attachDisk := range getAttachedDisks(oldSpec.Devices.Disks, domain.Spec.Devices.Disks) { -@@ -945,7 +1027,18 @@ func (l *LibvirtDomainManager) SyncVMI(vmi *v1.VirtualMachineInstance, allowEmul - if !allowAttach { - continue - } -- logger.V(1).Infof("Attaching disk %s, target %s", attachDisk.Alias.GetName(), attachDisk.Target.Device) -+ attachDiskName := attachDisk.Alias.GetName() -+ namespacedDiskName := fmt.Sprintf("%s_%s_%s", vmi.Namespace, vmi.Name, attachDiskName) -+ if _, ok := l.cancelDiskDetachChannels[namespacedDiskName]; ok { -+ logger.V(hotplugDetachmentVerbosity).Infof("Hotplug attach during detach grace period, signal detach goroutine: %s", namespacedDiskName) -+ // a goroutine is waiting to detach this disk, signal it to stop -+ l.cancelDiskDetachChannels[namespacedDiskName] <- struct{}{} -+ // no need to reattach if the disk is already attached -+ logger.V(hotplugDetachmentVerbosity).Infof("Skip hotplug detach/reattach disk: %s", namespacedDiskName) -+ continue -+ } -+ -+ logger.V(1).Infof("Attaching disk %s, target %s", attachDiskName, attachDisk.Target.Device) - // set drivers cache mode - err = converter.SetDriverCacheMode(&attachDisk, l.directIOChecker) - if err != nil { -@@ -1032,7 +1125,7 @@ func isHotplugDisk(disk api.Disk) bool { - return strings.HasPrefix(getSourceFile(disk), v1.HotplugDiskDir) - } - --func getDetachedDisks(oldDisks, newDisks []api.Disk) []api.Disk { -+func getDetachedDisks(vmiName, vmiNamespace string, oldDisks, newDisks []api.Disk) map[string]api.Disk { - newDiskMap := make(map[string]api.Disk) - for _, disk := range newDisks { - file := getSourceFile(disk) -@@ -1040,14 +1133,15 @@ func getDetachedDisks(oldDisks, newDisks []api.Disk) []api.Disk { - newDiskMap[file] = disk - } - } -- res := make([]api.Disk, 0) -+ res := map[string]api.Disk{} - for _, oldDisk := range oldDisks { - if !isHotplugDisk(oldDisk) { - continue - } - if _, ok := newDiskMap[getSourceFile(oldDisk)]; !ok { - // This disk got detached, add it to the list -- res = append(res, oldDisk) -+ namespacedDiskName := fmt.Sprintf("%s_%s_%s", vmiNamespace, vmiName, oldDisk.Alias.GetName()) -+ res[namespacedDiskName] = oldDisk - } - } - return res diff --git a/SPECS/kubevirt/kubevirt.spec b/SPECS/kubevirt/kubevirt.spec index f56a5c329d9..4a979271e2c 100644 --- a/SPECS/kubevirt/kubevirt.spec +++ b/SPECS/kubevirt/kubevirt.spec @@ -19,7 +19,7 @@ Summary: Container native virtualization Name: kubevirt Version: 0.59.0 -Release: 19%{?dist} +Release: 22%{?dist} License: ASL 2.0 Vendor: Microsoft Corporation Distribution: Mariner @@ -29,15 +29,16 @@ Source0: https://github.com/kubevirt/kubevirt/archive/refs/tags/v%{versio Source1: disks-images-provider.yaml # Nexus team needs these to-be-upstreamed patches for the operator Edge to work # correctly. -Patch0: Cleanup-housekeeping-cgroup-on-vm-del.patch -Patch1: Allocate-2-cpu-for-the-emulator-thread.patch -Patch2: Hotplug_detach_grace_period.patch -Patch3: CVE-2023-44487.patch -Patch4: CVE-2024-21626.patch -Patch5: Hp-volume-pod-should-respect-blockdevices.patch -Patch6: CVE-2022-41723.patch -Patch7: CVE-2024-24786.patch -Patch8: CVE-2023-45288.patch +Patch00: Cleanup-housekeeping-cgroup-on-vm-del.patch +Patch01: Allocate-2-cpu-for-the-emulator-thread.patch +Patch02: CVE-2023-44487.patch +Patch03: CVE-2024-21626.patch +Patch04: Hp-volume-pod-should-respect-blockdevices.patch +Patch05: CVE-2022-41723.patch +Patch06: CVE-2024-24786.patch +Patch07: CVE-2023-45288.patch +Patch08: CVE-2022-32149.patch +Patch09: CVE-2023-26484.patch %global debug_package %{nil} BuildRequires: glibc-devel BuildRequires: glibc-static >= 2.35-7%{?dist} @@ -217,6 +218,16 @@ install -p -m 0644 cmd/virt-handler/nsswitch.conf %{buildroot}%{_datadir}/kube-v %{_bindir}/virt-tests %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 0.59.0-22 +- Bump release to rebuild with go 1.22.7 + +* Wed Sep 11 2024 Sharath Srikanth Chellappa - 0.59.0-21 +- Remove hotplug detach patch since it is no longer required. + +* Thu Aug 22 2024 Brian Fjeldstad - 0.59.0-20 +- Fix for CVE-2022-32149 +- Fix for CVE-2023-26484 + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 0.59.0-19 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS/kured/kured.spec b/SPECS/kured/kured.spec index 8fd822756d8..043e7df8b48 100644 --- a/SPECS/kured/kured.spec +++ b/SPECS/kured/kured.spec @@ -25,7 +25,7 @@ Summary: Kubernetes daemonset to perform safe automatic node reboots Name: kured Version: 1.14.2 -Release: 4%{?dist} +Release: 5%{?dist} License: Apache-2.0 Vendor: Microsoft Corporation Distribution: Mariner @@ -119,6 +119,9 @@ sed -i -e 's|image: .*|image: registry.opensuse.org/kubic/kured:%{version}|g' %{ %{_datarootdir}/k8s-yaml/kured/kured.yaml %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 1.14.2-5 +- Bump release to rebuild with go 1.22.7 + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 1.14.2-4 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS/libcontainers-common/CVE-2022-32149.patch b/SPECS/libcontainers-common/CVE-2022-32149.patch new file mode 100644 index 00000000000..cf9ed3f1975 --- /dev/null +++ b/SPECS/libcontainers-common/CVE-2022-32149.patch @@ -0,0 +1,35 @@ +From 7ee36713a66401f828dfe476196ca290f7c23ffe Mon Sep 17 00:00:00 2001 +From: Sindhu Karri +Date: Wed, 28 Aug 2024 05:01:17 +0000 +Subject: [PATCH] Fix CVE-2022-32149 + +--- + vendor/golang.org/x/text/language/parse.go | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/vendor/golang.org/x/text/language/parse.go b/vendor/golang.org/x/text/language/parse.go +index 11acfd8..11d11f4 100644 +--- a/vendor/golang.org/x/text/language/parse.go ++++ b/vendor/golang.org/x/text/language/parse.go +@@ -133,6 +133,7 @@ func update(b *language.Builder, part ...interface{}) (err error) { + } + + var errInvalidWeight = errors.New("ParseAcceptLanguage: invalid weight") ++var errTagListTooLarge = errors.New("tag list exceeds max length") + + // ParseAcceptLanguage parses the contents of an Accept-Language header as + // defined in http://www.ietf.org/rfc/rfc2616.txt and returns a list of Tags and +@@ -150,6 +151,10 @@ func ParseAcceptLanguage(s string) (tag []Tag, q []float32, err error) { + + entry, weight := split(entry, ';') + ++ if strings.Count(s, "-") > 1000 { ++ return nil, nil, errTagListTooLarge ++ } ++ + // Scan the language. + t, err := Parse(entry) + if err != nil { +-- +2.33.8 + diff --git a/SPECS/libcontainers-common/CVE-2024-3727.patch b/SPECS/libcontainers-common/CVE-2024-3727.patch new file mode 100644 index 00000000000..53efa09536a --- /dev/null +++ b/SPECS/libcontainers-common/CVE-2024-3727.patch @@ -0,0 +1,536 @@ +From f20a95cee488de958f42db02bb5121ba52981a1d Mon Sep 17 00:00:00 2001 +From: Sudipta Pandit +Date: Thu, 12 Sep 2024 17:08:02 +0530 +Subject: [PATCH] Backport upstream patch for containers/image + +--- + .../image/v5/directory/directory_dest.go | 23 ++++++++-- + .../image/v5/directory/directory_src.go | 18 ++++++-- + .../image/v5/directory/directory_transport.go | 25 ++++++---- + .../image/v5/docker/docker_client.go | 4 ++ + .../image/v5/docker/docker_image.go | 7 ++- + .../image/v5/docker/docker_image_dest.go | 4 ++ + .../image/v5/docker/docker_image_src.go | 6 +++ + .../image/v5/docker/internal/tarfile/dest.go | 12 ++++- + .../v5/docker/internal/tarfile/writer.go | 34 +++++++++++--- + .../containers/image/v5/ostree/ostree_dest.go | 10 ++++ + .../containers/image/v5/ostree/ostree_src.go | 4 +- + .../image/v5/storage/storage_image.go | 46 +++++++++++++++---- + .../image/v5/storage/storage_reference.go | 10 +++- + 13 files changed, 165 insertions(+), 38 deletions(-) + +diff --git a/vendor/github.com/containers/image/v5/directory/directory_dest.go b/vendor/github.com/containers/image/v5/directory/directory_dest.go +index ea20e7c5..72ec5a70 100644 +--- a/vendor/github.com/containers/image/v5/directory/directory_dest.go ++++ b/vendor/github.com/containers/image/v5/directory/directory_dest.go +@@ -188,7 +188,11 @@ func (d *dirImageDestination) PutBlob(ctx context.Context, stream io.Reader, inp + } + } + +- blobPath := d.ref.layerPath(blobDigest) ++ // Custom backport for CVE-2024-3727 ++ blobPath, err := d.ref.layerPath(blobDigest) ++ if err != nil { ++ return types.BlobInfo{}, err ++ } + // need to explicitly close the file, since a rename won't otherwise not work on Windows + blobFile.Close() + explicitClosed = true +@@ -212,7 +216,10 @@ func (d *dirImageDestination) TryReusingBlob(ctx context.Context, info types.Blo + if info.Digest == "" { + return false, types.BlobInfo{}, errors.Errorf(`"Can not check for a blob with unknown digest`) + } +- blobPath := d.ref.layerPath(info.Digest) ++ blobPath, err := d.ref.layerPath(info.Digest) ++ if err != nil { ++ return false, types.BlobInfo{}, err ++ } + finfo, err := os.Stat(blobPath) + if err != nil && os.IsNotExist(err) { + return false, types.BlobInfo{}, nil +@@ -232,7 +239,11 @@ func (d *dirImageDestination) TryReusingBlob(ctx context.Context, info types.Blo + // If the destination is in principle available, refuses this manifest type (e.g. it does not recognize the schema), + // but may accept a different manifest type, the returned error must be an ManifestTypeRejectedError. + func (d *dirImageDestination) PutManifest(ctx context.Context, manifest []byte, instanceDigest *digest.Digest) error { +- return ioutil.WriteFile(d.ref.manifestPath(instanceDigest), manifest, 0644) ++ manifestPath, err := d.ref.manifestPath(instanceDigest) ++ if err != nil { ++ return err ++ } ++ return ioutil.WriteFile(manifestPath, manifest, 0644) + } + + // PutSignatures writes a set of signatures to the destination. +@@ -240,7 +251,11 @@ func (d *dirImageDestination) PutManifest(ctx context.Context, manifest []byte, + // (when the primary manifest is a manifest list); this should always be nil if the primary manifest is not a manifest list. + func (d *dirImageDestination) PutSignatures(ctx context.Context, signatures [][]byte, instanceDigest *digest.Digest) error { + for i, sig := range signatures { +- if err := ioutil.WriteFile(d.ref.signaturePath(i, instanceDigest), sig, 0644); err != nil { ++ signaturePath, err := d.ref.signaturePath(i, instanceDigest) ++ if err != nil { ++ return err ++ } ++ if err := ioutil.WriteFile(signaturePath, sig, 0644); err != nil { + return err + } + } +diff --git a/vendor/github.com/containers/image/v5/directory/directory_src.go b/vendor/github.com/containers/image/v5/directory/directory_src.go +index ad9129d4..420cee2f 100644 +--- a/vendor/github.com/containers/image/v5/directory/directory_src.go ++++ b/vendor/github.com/containers/image/v5/directory/directory_src.go +@@ -37,7 +37,11 @@ func (s *dirImageSource) Close() error { + // If instanceDigest is not nil, it contains a digest of the specific manifest instance to retrieve (when the primary manifest is a manifest list); + // this never happens if the primary manifest is not a manifest list (e.g. if the source never returns manifest lists). + func (s *dirImageSource) GetManifest(ctx context.Context, instanceDigest *digest.Digest) ([]byte, string, error) { +- m, err := ioutil.ReadFile(s.ref.manifestPath(instanceDigest)) ++ path, err := s.ref.manifestPath(instanceDigest) ++ if err != nil { ++ return nil, "", err ++ } ++ m, err := ioutil.ReadFile(path) + if err != nil { + return nil, "", err + } +@@ -53,7 +57,11 @@ func (s *dirImageSource) HasThreadSafeGetBlob() bool { + // The Digest field in BlobInfo is guaranteed to be provided, Size may be -1 and MediaType may be optionally provided. + // May update BlobInfoCache, preferably after it knows for certain that a blob truly exists at a specific location. + func (s *dirImageSource) GetBlob(ctx context.Context, info types.BlobInfo, cache types.BlobInfoCache) (io.ReadCloser, int64, error) { +- r, err := os.Open(s.ref.layerPath(info.Digest)) ++ path, err := s.ref.layerPath(info.Digest) ++ if err != nil { ++ return nil, -1, err ++ } ++ r, err := os.Open(path) + if err != nil { + return nil, -1, err + } +@@ -71,7 +79,11 @@ func (s *dirImageSource) GetBlob(ctx context.Context, info types.BlobInfo, cache + func (s *dirImageSource) GetSignatures(ctx context.Context, instanceDigest *digest.Digest) ([][]byte, error) { + signatures := [][]byte{} + for i := 0; ; i++ { +- signature, err := ioutil.ReadFile(s.ref.signaturePath(i, instanceDigest)) ++ path, err := s.ref.signaturePath(i, instanceDigest) ++ if err != nil { ++ return nil, err ++ } ++ signature, err := ioutil.ReadFile(path) + if err != nil { + if os.IsNotExist(err) { + break +diff --git a/vendor/github.com/containers/image/v5/directory/directory_transport.go b/vendor/github.com/containers/image/v5/directory/directory_transport.go +index e542d888..ea280707 100644 +--- a/vendor/github.com/containers/image/v5/directory/directory_transport.go ++++ b/vendor/github.com/containers/image/v5/directory/directory_transport.go +@@ -162,25 +162,34 @@ func (ref dirReference) DeleteImage(ctx context.Context, sys *types.SystemContex + } + + // manifestPath returns a path for the manifest within a directory using our conventions. +-func (ref dirReference) manifestPath(instanceDigest *digest.Digest) string { ++func (ref dirReference) manifestPath(instanceDigest *digest.Digest) (string, error) { + if instanceDigest != nil { +- return filepath.Join(ref.path, instanceDigest.Encoded()+".manifest.json") ++ if err := instanceDigest.Validate(); err != nil { // digest.Digest.Encoded() panics on failure, and could possibly result in a path with ../, so validate explicitly. ++ return "", err ++ } ++ return filepath.Join(ref.path, instanceDigest.Encoded()+".manifest.json"), nil + } +- return filepath.Join(ref.path, "manifest.json") ++ return filepath.Join(ref.path, "manifest.json"), nil + } + + // layerPath returns a path for a layer tarball within a directory using our conventions. +-func (ref dirReference) layerPath(digest digest.Digest) string { ++func (ref dirReference) layerPath(digest digest.Digest) (string, error) { ++ if err := digest.Validate(); err != nil { // digest.Digest.Encoded() panics on failure, and could possibly result in a path with ../, so validate explicitly. ++ return "", err ++ } + // FIXME: Should we keep the digest identification? +- return filepath.Join(ref.path, digest.Encoded()) ++ return filepath.Join(ref.path, digest.Encoded()), nil + } + + // signaturePath returns a path for a signature within a directory using our conventions. +-func (ref dirReference) signaturePath(index int, instanceDigest *digest.Digest) string { ++func (ref dirReference) signaturePath(index int, instanceDigest *digest.Digest) (string, error) { + if instanceDigest != nil { +- return filepath.Join(ref.path, fmt.Sprintf(instanceDigest.Encoded()+".signature-%d", index+1)) ++ if err := instanceDigest.Validate(); err != nil { // digest.Digest.Encoded() panics on failure, and could possibly result in a path with ../, so validate explicitly. ++ return "", err ++ } ++ return filepath.Join(ref.path, fmt.Sprintf(instanceDigest.Encoded()+".signature-%d", index+1)), nil + } +- return filepath.Join(ref.path, fmt.Sprintf("signature-%d", index+1)) ++ return filepath.Join(ref.path, fmt.Sprintf("signature-%d", index+1)), nil + } + + // versionPath returns a path for the version file within a directory using our conventions. +diff --git a/vendor/github.com/containers/image/v5/docker/docker_client.go b/vendor/github.com/containers/image/v5/docker/docker_client.go +index 3fe9a11d..08f5d66e 100644 +--- a/vendor/github.com/containers/image/v5/docker/docker_client.go ++++ b/vendor/github.com/containers/image/v5/docker/docker_client.go +@@ -796,6 +796,10 @@ func (c *dockerClient) detectProperties(ctx context.Context) error { + // getExtensionsSignatures returns signatures from the X-Registry-Supports-Signatures API extension, + // using the original data structures. + func (c *dockerClient) getExtensionsSignatures(ctx context.Context, ref dockerReference, manifestDigest digest.Digest) (*extensionSignatureList, error) { ++ // Custom patch for CVE-2024-3727 ++ if err := manifestDigest.Validate(); err != nil { // Make sure manifestDigest.String() does not contain any unexpected characters ++ return nil, err ++ } + path := fmt.Sprintf(extensionsSignaturePath, reference.Path(ref.ref), manifestDigest) + res, err := c.makeRequest(ctx, http.MethodGet, path, nil, nil, v2Auth, nil) + if err != nil { +diff --git a/vendor/github.com/containers/image/v5/docker/docker_image.go b/vendor/github.com/containers/image/v5/docker/docker_image.go +index c84bb37d..284b39f5 100644 +--- a/vendor/github.com/containers/image/v5/docker/docker_image.go ++++ b/vendor/github.com/containers/image/v5/docker/docker_image.go +@@ -83,7 +83,12 @@ func GetRepositoryTags(ctx context.Context, sys *types.SystemContext, ref types. + if err = json.NewDecoder(res.Body).Decode(&tagsHolder); err != nil { + return nil, err + } +- tags = append(tags, tagsHolder.Tags...) ++ for _, tag := range tagsHolder.Tags { ++ if _, err := reference.WithTag(dr.ref, tag); err != nil { // Ensure the tag does not contain unexpected values ++ return nil, fmt.Errorf("registry returned invalid tag %q: %w", tag, err) ++ } ++ tags = append(tags, tag) ++ } + + link := res.Header.Get("Link") + if link == "" { +diff --git a/vendor/github.com/containers/image/v5/docker/docker_image_dest.go b/vendor/github.com/containers/image/v5/docker/docker_image_dest.go +index 80701a76..ce08333c 100644 +--- a/vendor/github.com/containers/image/v5/docker/docker_image_dest.go ++++ b/vendor/github.com/containers/image/v5/docker/docker_image_dest.go +@@ -215,6 +215,9 @@ func (d *dockerImageDestination) PutBlob(ctx context.Context, stream io.Reader, + // If the destination does not contain the blob, or it is unknown, blobExists ordinarily returns (false, -1, nil); + // it returns a non-nil error only on an unexpected failure. + func (d *dockerImageDestination) blobExists(ctx context.Context, repo reference.Named, digest digest.Digest, extraScope *authScope) (bool, int64, error) { ++ if err := digest.Validate(); err != nil { // Make sure digest.String() does not contain any unexpected characters ++ return false, -1, err ++ } + checkPath := fmt.Sprintf(blobsPath, reference.Path(repo), digest.String()) + logrus.Debugf("Checking %s", checkPath) + res, err := d.c.makeRequest(ctx, http.MethodHead, checkPath, nil, nil, v2Auth, extraScope) +@@ -641,6 +644,7 @@ sigExists: + return err + } + ++ // manifestDigest is known to be valid because it was not rejected by getExtensionsSignatures above. + path := fmt.Sprintf(extensionsSignaturePath, reference.Path(d.ref.ref), manifestDigest.String()) + res, err := d.c.makeRequest(ctx, http.MethodPut, path, nil, bytes.NewReader(body), v2Auth, nil) + if err != nil { +diff --git a/vendor/github.com/containers/image/v5/docker/docker_image_src.go b/vendor/github.com/containers/image/v5/docker/docker_image_src.go +index 1333cf9e..1c3cf448 100644 +--- a/vendor/github.com/containers/image/v5/docker/docker_image_src.go ++++ b/vendor/github.com/containers/image/v5/docker/docker_image_src.go +@@ -178,6 +178,9 @@ func simplifyContentType(contentType string) string { + // this never happens if the primary manifest is not a manifest list (e.g. if the source never returns manifest lists). + func (s *dockerImageSource) GetManifest(ctx context.Context, instanceDigest *digest.Digest) ([]byte, string, error) { + if instanceDigest != nil { ++ if err := instanceDigest.Validate(); err != nil { // Make sure instanceDigest.String() does not contain any unexpected characters ++ return nil, "", err ++ } + return s.fetchManifest(ctx, instanceDigest.String()) + } + err := s.ensureManifestIsLoaded(ctx) +@@ -364,6 +367,9 @@ func (s *dockerImageSource) GetBlobAt(ctx context.Context, info types.BlobInfo, + return nil, nil, fmt.Errorf("external URLs not supported with GetBlobAt") + } + ++ if err := info.Digest.Validate(); err != nil { // Make sure info.Digest.String() does not contain any unexpected characters ++ return nil, nil, err ++ } + path := fmt.Sprintf(blobsPath, reference.Path(s.physicalRef.ref), info.Digest.String()) + logrus.Debugf("Downloading %s", path) + res, err := s.c.makeRequest(ctx, http.MethodGet, path, headers, nil, v2Auth, nil) +diff --git a/vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go b/vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go +index 44b0af11..e9162668 100644 +--- a/vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go ++++ b/vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go +@@ -141,11 +141,19 @@ func (d *Destination) PutBlob(ctx context.Context, stream io.Reader, inputInfo t + return types.BlobInfo{}, errors.Wrap(err, "reading Config file stream") + } + d.config = buf +- if err := d.archive.sendFileLocked(d.archive.configPath(inputInfo.Digest), inputInfo.Size, bytes.NewReader(buf)); err != nil { ++ configPath, err := d.archive.configPath(inputInfo.Digest) ++ if err != nil { ++ return types.BlobInfo{}, errors.Wrap(err, "getting config path") ++ } ++ if err := d.archive.sendFileLocked(configPath, inputInfo.Size, bytes.NewReader(buf)); err != nil { + return types.BlobInfo{}, errors.Wrap(err, "writing Config file") + } + } else { +- if err := d.archive.sendFileLocked(d.archive.physicalLayerPath(inputInfo.Digest), inputInfo.Size, stream); err != nil { ++ layerPath, err := d.archive.physicalLayerPath(inputInfo.Digest) ++ if err != nil { ++ return types.BlobInfo{}, err ++ } ++ if err := d.archive.sendFileLocked(layerPath, inputInfo.Size, stream); err != nil { + return types.BlobInfo{}, err + } + } +diff --git a/vendor/github.com/containers/image/v5/docker/internal/tarfile/writer.go b/vendor/github.com/containers/image/v5/docker/internal/tarfile/writer.go +index 255f0d35..742f977c 100644 +--- a/vendor/github.com/containers/image/v5/docker/internal/tarfile/writer.go ++++ b/vendor/github.com/containers/image/v5/docker/internal/tarfile/writer.go +@@ -92,7 +92,10 @@ func (w *Writer) ensureSingleLegacyLayerLocked(layerID string, layerDigest diges + if _, ok := w.legacyLayers[layerID]; !ok { + // Create a symlink for the legacy format, where there is one subdirectory per layer ("image"). + // See also the comment in physicalLayerPath. +- physicalLayerPath := w.physicalLayerPath(layerDigest) ++ physicalLayerPath, err := w.physicalLayerPath(layerDigest) ++ if err != nil { ++ return err ++ } + if err := w.sendSymlinkLocked(filepath.Join(layerID, legacyLayerFileName), filepath.Join("..", physicalLayerPath)); err != nil { + return errors.Wrap(err, "creating layer symbolic link") + } +@@ -136,6 +139,9 @@ func (w *Writer) writeLegacyMetadataLocked(layerDescriptors []manifest.Schema2De + } + + // This chainID value matches the computation in docker/docker/layer.CreateChainID … ++ if err := l.Digest.Validate(); err != nil { // This should never fail on this code path, still: make sure the chainID computation is unambiguous. ++ return err ++ } + if chainID == "" { + chainID = l.Digest + } else { +@@ -206,12 +212,20 @@ func checkManifestItemsMatch(a, b *ManifestItem) error { + func (w *Writer) ensureManifestItemLocked(layerDescriptors []manifest.Schema2Descriptor, configDigest digest.Digest, repoTags []reference.NamedTagged) error { + layerPaths := []string{} + for _, l := range layerDescriptors { +- layerPaths = append(layerPaths, w.physicalLayerPath(l.Digest)) ++ p, err := w.physicalLayerPath(l.Digest) ++ if err != nil { ++ return err ++ } ++ layerPaths = append(layerPaths, p) + } + + var item *ManifestItem ++ configPath, err := w.configPath(configDigest) ++ if err != nil { ++ return err ++ } + newItem := ManifestItem{ +- Config: w.configPath(configDigest), ++ Config: configPath, + RepoTags: []string{}, + Layers: layerPaths, + Parent: "", // We don’t have this information +@@ -296,21 +310,27 @@ func (w *Writer) Close() error { + // configPath returns a path we choose for storing a config with the specified digest. + // NOTE: This is an internal implementation detail, not a format property, and can change + // any time. +-func (w *Writer) configPath(configDigest digest.Digest) string { +- return configDigest.Hex() + ".json" ++func (w *Writer) configPath(configDigest digest.Digest) (string, error) { ++ if err := configDigest.Validate(); err != nil { // digest.Digest.Hex() panics on failure, and could possibly result in unexpected paths, so validate explicitly. ++ return "", err ++ } ++ return configDigest.Hex() + ".json", nil + } + + // physicalLayerPath returns a path we choose for storing a layer with the specified digest + // (the actual path, i.e. a regular file, not a symlink that may be used in the legacy format). + // NOTE: This is an internal implementation detail, not a format property, and can change + // any time. +-func (w *Writer) physicalLayerPath(layerDigest digest.Digest) string { ++func (w *Writer) physicalLayerPath(layerDigest digest.Digest) (string, error) { ++ if err := layerDigest.Validate(); err != nil { // digest.Digest.Hex() panics on failure, and could possibly result in unexpected paths, so validate explicitly. ++ return "", err ++ } + // Note that this can't be e.g. filepath.Join(l.Digest.Hex(), legacyLayerFileName); due to the way + // writeLegacyMetadata constructs layer IDs differently from inputinfo.Digest values (as described + // inside it), most of the layers would end up in subdirectories alone without any metadata; (docker load) + // tries to load every subdirectory as an image and fails if the config is missing. So, keep the layers + // in the root of the tarball. +- return layerDigest.Hex() + ".tar" ++ return layerDigest.Hex() + ".tar", nil + } + + type tarFI struct { +diff --git a/vendor/github.com/containers/image/v5/ostree/ostree_dest.go b/vendor/github.com/containers/image/v5/ostree/ostree_dest.go +index 3eb2a2cb..02115a26 100644 +--- a/vendor/github.com/containers/image/v5/ostree/ostree_dest.go ++++ b/vendor/github.com/containers/image/v5/ostree/ostree_dest.go +@@ -352,6 +352,10 @@ func (d *ostreeImageDestination) TryReusingBlob(ctx context.Context, info types. + } + d.repo = repo + } ++ ++ if err := info.Digest.Validate(); err != nil { // digest.Digest.Hex() panics on failure, so validate explicitly. ++ return false, types.BlobInfo{}, err ++ } + branch := fmt.Sprintf("ociimage/%s", info.Digest.Hex()) + + found, data, err := readMetadata(d.repo, branch, "docker.uncompressed_digest") +@@ -472,12 +476,18 @@ func (d *ostreeImageDestination) Commit(context.Context, types.UnparsedImage) er + return nil + } + for _, layer := range d.schema.LayersDescriptors { ++ if err := layer.Digest.Validate(); err != nil { // digest.Digest.Encoded() panics on failure, so validate explicitly. ++ return err ++ } + hash := layer.Digest.Hex() + if err = checkLayer(hash); err != nil { + return err + } + } + for _, layer := range d.schema.FSLayers { ++ if err := layer.BlobSum.Validate(); err != nil { // digest.Digest.Encoded() panics on failure, so validate explicitly. ++ return err ++ } + hash := layer.BlobSum.Hex() + if err = checkLayer(hash); err != nil { + return err +diff --git a/vendor/github.com/containers/image/v5/ostree/ostree_src.go b/vendor/github.com/containers/image/v5/ostree/ostree_src.go +index d30c764a..f60cbcf7 100644 +--- a/vendor/github.com/containers/image/v5/ostree/ostree_src.go ++++ b/vendor/github.com/containers/image/v5/ostree/ostree_src.go +@@ -273,7 +273,9 @@ func (s *ostreeImageSource) HasThreadSafeGetBlob() bool { + // The Digest field in BlobInfo is guaranteed to be provided, Size may be -1 and MediaType may be optionally provided. + // May update BlobInfoCache, preferably after it knows for certain that a blob truly exists at a specific location. + func (s *ostreeImageSource) GetBlob(ctx context.Context, info types.BlobInfo, cache types.BlobInfoCache) (io.ReadCloser, int64, error) { +- ++ if err := info.Digest.Validate(); err != nil { // digest.Digest.Encoded() panics on failure, so validate explicitly. ++ return nil, -1, err ++ } + blob := info.Digest.Hex() + + // Ensure s.compressed is initialized. It is build by LayerInfosForCopy. +diff --git a/vendor/github.com/containers/image/v5/storage/storage_image.go b/vendor/github.com/containers/image/v5/storage/storage_image.go +index 7329ef6e..a40d7f1a 100644 +--- a/vendor/github.com/containers/image/v5/storage/storage_image.go ++++ b/vendor/github.com/containers/image/v5/storage/storage_image.go +@@ -100,14 +100,21 @@ type storageImageCloser struct { + // manifestBigDataKey returns a key suitable for recording a manifest with the specified digest using storage.Store.ImageBigData and related functions. + // If a specific manifest digest is explicitly requested by the user, the key returned by this function should be used preferably; + // for compatibility, if a manifest is not available under this key, check also storage.ImageDigestBigDataKey +-func manifestBigDataKey(digest digest.Digest) string { +- return storage.ImageDigestManifestBigDataNamePrefix + "-" + digest.String() ++func manifestBigDataKey(digest digest.Digest) (string, error) { ++ // return storage.ImageDigestManifestBigDataNamePrefix + "-" + digest.String() ++ if err := digest.Validate(); err != nil { // Make sure info.Digest.String() uses the expected format and does not collide with other BigData keys. ++ return "", err ++ } ++ return storage.ImageDigestManifestBigDataNamePrefix + "-" + digest.String(), nil + } + + // signatureBigDataKey returns a key suitable for recording the signatures associated with the manifest with the specified digest using storage.Store.ImageBigData and related functions. + // If a specific manifest digest is explicitly requested by the user, the key returned by this function should be used preferably; +-func signatureBigDataKey(digest digest.Digest) string { +- return "signature-" + digest.Encoded() ++func signatureBigDataKey(digest digest.Digest) (string, error) { ++ if err := digest.Validate(); err != nil { // digest.Digest.Encoded() panics on failure, so validate explicitly. ++ return "", err ++ } ++ return "signature-" + digest.Encoded(), nil + } + + // newImageSource sets up an image for reading. +@@ -243,8 +250,12 @@ func (s *storageImageSource) getBlobAndLayerID(info types.BlobInfo) (rc io.ReadC + + // GetManifest() reads the image's manifest. + func (s *storageImageSource) GetManifest(ctx context.Context, instanceDigest *digest.Digest) (manifestBlob []byte, MIMEType string, err error) { ++ // Custom patch for CVE-2024-3727 + if instanceDigest != nil { +- key := manifestBigDataKey(*instanceDigest) ++ key, err := manifestBigDataKey(*instanceDigest) ++ if err != nil { ++ return nil, "", errors.Wrapf(err, "generating manifest big data key for image instance %q", *instanceDigest) ++ } + blob, err := s.imageRef.transport.store.ImageBigData(s.image.ID, key) + if err != nil { + return nil, "", errors.Wrapf(err, "reading manifest for image instance %q", *instanceDigest) +@@ -256,7 +267,10 @@ func (s *storageImageSource) GetManifest(ctx context.Context, instanceDigest *di + // Prefer the manifest corresponding to the user-specified digest, if available. + if s.imageRef.named != nil { + if digested, ok := s.imageRef.named.(reference.Digested); ok { +- key := manifestBigDataKey(digested.Digest()) ++ key, err := manifestBigDataKey(digested.Digest()) ++ if err != nil { ++ return nil, "", err ++ } + blob, err := s.imageRef.transport.store.ImageBigData(s.image.ID, key) + if err != nil && !os.IsNotExist(err) { // os.IsNotExist is true if the image exists but there is no data corresponding to key + return nil, "", err +@@ -369,7 +383,10 @@ func (s *storageImageSource) GetSignatures(ctx context.Context, instanceDigest * + instance := "default instance" + if instanceDigest != nil { + signatureSizes = s.SignaturesSizes[*instanceDigest] +- key = signatureBigDataKey(*instanceDigest) ++ key, err = signatureBigDataKey(*instanceDigest) ++ if err != nil { ++ return nil, errors.Wrapf(err, "generating signature big data key for image instance %q", *instanceDigest) ++ } + instance = instanceDigest.Encoded() + } + if len(signatureSizes) > 0 { +@@ -1146,7 +1163,10 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t + if err != nil { + return errors.Wrapf(err, "digesting top-level manifest") + } +- key := manifestBigDataKey(manifestDigest) ++ key, err := manifestBigDataKey(manifestDigest) ++ if err != nil { ++ return errors.Wrapf(err, "getting manifest big data key for image %q", img.ID) ++ } + if err := s.imageRef.transport.store.SetImageBigData(img.ID, key, toplevelManifest, manifest.Digest); err != nil { + logrus.Debugf("error saving top-level manifest for image %q: %v", img.ID, err) + return errors.Wrapf(err, "saving top-level manifest for image %q", img.ID) +@@ -1155,7 +1175,10 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t + // Save the image's manifest. Allow looking it up by digest by using the key convention defined by the Store. + // Record the manifest twice: using a digest-specific key to allow references to that specific digest instance, + // and using storage.ImageDigestBigDataKey for future users that don’t specify any digest and for compatibility with older readers. +- key := manifestBigDataKey(s.manifestDigest) ++ key, err := manifestBigDataKey(s.manifestDigest) ++ if err != nil { ++ return errors.Wrapf(err, "getting manifest big data key for image %q", img.ID) ++ } + if err := s.imageRef.transport.store.SetImageBigData(img.ID, key, s.manifest, manifest.Digest); err != nil { + logrus.Debugf("error saving manifest for image %q: %v", img.ID, err) + return errors.Wrapf(err, "saving manifest for image %q", img.ID) +@@ -1173,7 +1196,10 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t + } + } + for instanceDigest, signatures := range s.signatureses { +- key := signatureBigDataKey(instanceDigest) ++ key, err := signatureBigDataKey(instanceDigest) ++ if err != nil { ++ return err ++ } + if err := s.imageRef.transport.store.SetImageBigData(img.ID, key, signatures, manifest.Digest); err != nil { + logrus.Debugf("error saving signatures for image %q: %v", img.ID, err) + return errors.Wrapf(err, "saving signatures for image %q", img.ID) +diff --git a/vendor/github.com/containers/image/v5/storage/storage_reference.go b/vendor/github.com/containers/image/v5/storage/storage_reference.go +index 7c6da112..ac1d1e42 100644 +--- a/vendor/github.com/containers/image/v5/storage/storage_reference.go ++++ b/vendor/github.com/containers/image/v5/storage/storage_reference.go +@@ -73,7 +73,10 @@ func multiArchImageMatchesSystemContext(store storage.Store, img *storage.Image, + // We don't need to care about storage.ImageDigestBigDataKey because + // manifests lists are only stored into storage by c/image versions + // that know about manifestBigDataKey, and only using that key. +- key := manifestBigDataKey(manifestDigest) ++ key, err := manifestBigDataKey(manifestDigest) ++ if err != nil { ++ return false // This should never happen, manifestDigest comes from a reference.Digested, and that validates the format. ++ } + manifestBytes, err := store.ImageBigData(img.ID, key) + if err != nil { + return false +@@ -95,7 +98,10 @@ func multiArchImageMatchesSystemContext(store storage.Store, img *storage.Image, + if err != nil { + return false + } +- key = manifestBigDataKey(chosenInstance) ++ key, err = manifestBigDataKey(chosenInstance) ++ if err != nil { ++ return false ++ } + _, err = store.ImageBigData(img.ID, key) + return err == nil // true if img.ID is based on chosenInstance. + } +-- +2.34.1 + diff --git a/SPECS/libcontainers-common/libcontainers-common.spec b/SPECS/libcontainers-common/libcontainers-common.spec index 40853cdd173..29646d86fc8 100644 --- a/SPECS/libcontainers-common/libcontainers-common.spec +++ b/SPECS/libcontainers-common/libcontainers-common.spec @@ -26,7 +26,7 @@ Summary: Configuration files common to github.com/containers Name: libcontainers-common Version: 20210626 -Release: 5%{?dist} +Release: 7%{?dist} License: ASL 2.0 AND GPLv3 Vendor: Microsoft Corporation Distribution: Mariner @@ -51,6 +51,9 @@ Patch0: CVE-2021-44716.patch #Note (mfrw): The patch for CVE-2024-37298 only applies to podman. Patch1: CVE-2024-37298.patch Patch2: CVE-2021-43565.patch +Patch3: CVE-2022-32149.patch +Patch4: CVE-2024-3727.patch +Patch5: podman-CVE-2024-3727.patch BuildRequires: go-go-md2man Requires(post): grep Requires(post): util-linux @@ -64,13 +67,19 @@ github.com/containers libraries, such as Buildah, CRI-O, Podman and Skopeo. %prep %setup -q -T -D -b 0 -n image-%{imagever} +%patch 4 -p6 + %setup -q -T -D -b 1 -n storage-%{storagever} %setup -q -T -D -b 7 -n podman-%{podmanver} +%patch 5 -p1 %patch 1 -p1 +%patch 3 -p1 %setup -q -T -D -b 9 -n common-%{commonver} %patch 0 -p1 +%patch 3 -p1 +%patch 4 -p1 # copy the LICENSE file in the build root %patch 2 -p1 -d ../podman-%{podmanver} @@ -168,6 +177,12 @@ fi %license LICENSE %changelog +* Thu Sep 12 2024 Sudipta Pandit - 20210626-7 +- Backport CVE-2024-3727 for all sources from upstream + +* Tue Aug 27 2024 Sindhu Karri - 20210626-6 +- Patch CVE-2022-32149 + * Mon Jul 29 2024 Archana Choudhary - 20210626-5 - Patch CVE-2021-43565 diff --git a/SPECS/libcontainers-common/podman-CVE-2024-3727.patch b/SPECS/libcontainers-common/podman-CVE-2024-3727.patch new file mode 100644 index 00000000000..616116a2070 --- /dev/null +++ b/SPECS/libcontainers-common/podman-CVE-2024-3727.patch @@ -0,0 +1,524 @@ +From 5a593b2736e49ab2b449a9ab6100a9d44c9fc967 Mon Sep 17 00:00:00 2001 +From: Sudipta Pandit +Date: Thu, 12 Sep 2024 19:37:38 +0530 +Subject: [PATCH] Backport upstream patch of vendored containers/image of + podman + +--- + .../image/v5/directory/directory_dest.go | 17 +++++-- + .../image/v5/directory/directory_src.go | 18 ++++++-- + .../image/v5/directory/directory_transport.go | 25 ++++++---- + .../image/v5/docker/docker_client.go | 4 ++ + .../image/v5/docker/docker_image.go | 7 ++- + .../image/v5/docker/docker_image_dest.go | 4 ++ + .../image/v5/docker/docker_image_src.go | 6 +++ + .../image/v5/docker/internal/tarfile/dest.go | 12 ++++- + .../v5/docker/internal/tarfile/writer.go | 34 +++++++++++--- + .../containers/image/v5/ostree/ostree_dest.go | 10 ++++ + .../containers/image/v5/ostree/ostree_src.go | 4 +- + .../image/v5/storage/storage_image.go | 46 +++++++++++++++---- + .../image/v5/storage/storage_reference.go | 10 +++- + 13 files changed, 160 insertions(+), 37 deletions(-) + +diff --git a/vendor/github.com/containers/image/v5/directory/directory_dest.go b/vendor/github.com/containers/image/v5/directory/directory_dest.go +index e3280aa2b..9cf88175d 100644 +--- a/vendor/github.com/containers/image/v5/directory/directory_dest.go ++++ b/vendor/github.com/containers/image/v5/directory/directory_dest.go +@@ -213,7 +213,10 @@ func (d *dirImageDestination) TryReusingBlob(ctx context.Context, info types.Blo + if info.Digest == "" { + return false, types.BlobInfo{}, errors.Errorf(`"Can not check for a blob with unknown digest`) + } +- blobPath := d.ref.layerPath(info.Digest) ++ blobPath, err := d.ref.layerPath(info.Digest) ++ if err != nil { ++ return false, types.BlobInfo{}, err ++ } + finfo, err := os.Stat(blobPath) + if err != nil && os.IsNotExist(err) { + return false, types.BlobInfo{}, nil +@@ -233,7 +236,11 @@ func (d *dirImageDestination) TryReusingBlob(ctx context.Context, info types.Blo + // If the destination is in principle available, refuses this manifest type (e.g. it does not recognize the schema), + // but may accept a different manifest type, the returned error must be an ManifestTypeRejectedError. + func (d *dirImageDestination) PutManifest(ctx context.Context, manifest []byte, instanceDigest *digest.Digest) error { +- return ioutil.WriteFile(d.ref.manifestPath(instanceDigest), manifest, 0644) ++ manifestPath, err := d.ref.manifestPath(instanceDigest) ++ if err != nil { ++ return err ++ } ++ return ioutil.WriteFile(manifestPath, manifest, 0644) + } + + // PutSignatures writes a set of signatures to the destination. +@@ -241,7 +248,11 @@ func (d *dirImageDestination) PutManifest(ctx context.Context, manifest []byte, + // (when the primary manifest is a manifest list); this should always be nil if the primary manifest is not a manifest list. + func (d *dirImageDestination) PutSignatures(ctx context.Context, signatures [][]byte, instanceDigest *digest.Digest) error { + for i, sig := range signatures { +- if err := ioutil.WriteFile(d.ref.signaturePath(i, instanceDigest), sig, 0644); err != nil { ++ signaturePath, err := d.ref.signaturePath(i, instanceDigest) ++ if err != nil { ++ return err ++ } ++ if err := ioutil.WriteFile(signaturePath, sig, 0644); err != nil { + return err + } + } +diff --git a/vendor/github.com/containers/image/v5/directory/directory_src.go b/vendor/github.com/containers/image/v5/directory/directory_src.go +index ad9129d40..420cee2fd 100644 +--- a/vendor/github.com/containers/image/v5/directory/directory_src.go ++++ b/vendor/github.com/containers/image/v5/directory/directory_src.go +@@ -37,7 +37,11 @@ func (s *dirImageSource) Close() error { + // If instanceDigest is not nil, it contains a digest of the specific manifest instance to retrieve (when the primary manifest is a manifest list); + // this never happens if the primary manifest is not a manifest list (e.g. if the source never returns manifest lists). + func (s *dirImageSource) GetManifest(ctx context.Context, instanceDigest *digest.Digest) ([]byte, string, error) { +- m, err := ioutil.ReadFile(s.ref.manifestPath(instanceDigest)) ++ path, err := s.ref.manifestPath(instanceDigest) ++ if err != nil { ++ return nil, "", err ++ } ++ m, err := ioutil.ReadFile(path) + if err != nil { + return nil, "", err + } +@@ -53,7 +57,11 @@ func (s *dirImageSource) HasThreadSafeGetBlob() bool { + // The Digest field in BlobInfo is guaranteed to be provided, Size may be -1 and MediaType may be optionally provided. + // May update BlobInfoCache, preferably after it knows for certain that a blob truly exists at a specific location. + func (s *dirImageSource) GetBlob(ctx context.Context, info types.BlobInfo, cache types.BlobInfoCache) (io.ReadCloser, int64, error) { +- r, err := os.Open(s.ref.layerPath(info.Digest)) ++ path, err := s.ref.layerPath(info.Digest) ++ if err != nil { ++ return nil, -1, err ++ } ++ r, err := os.Open(path) + if err != nil { + return nil, -1, err + } +@@ -71,7 +79,11 @@ func (s *dirImageSource) GetBlob(ctx context.Context, info types.BlobInfo, cache + func (s *dirImageSource) GetSignatures(ctx context.Context, instanceDigest *digest.Digest) ([][]byte, error) { + signatures := [][]byte{} + for i := 0; ; i++ { +- signature, err := ioutil.ReadFile(s.ref.signaturePath(i, instanceDigest)) ++ path, err := s.ref.signaturePath(i, instanceDigest) ++ if err != nil { ++ return nil, err ++ } ++ signature, err := ioutil.ReadFile(path) + if err != nil { + if os.IsNotExist(err) { + break +diff --git a/vendor/github.com/containers/image/v5/directory/directory_transport.go b/vendor/github.com/containers/image/v5/directory/directory_transport.go +index e542d888c..ea2807070 100644 +--- a/vendor/github.com/containers/image/v5/directory/directory_transport.go ++++ b/vendor/github.com/containers/image/v5/directory/directory_transport.go +@@ -162,25 +162,34 @@ func (ref dirReference) DeleteImage(ctx context.Context, sys *types.SystemContex + } + + // manifestPath returns a path for the manifest within a directory using our conventions. +-func (ref dirReference) manifestPath(instanceDigest *digest.Digest) string { ++func (ref dirReference) manifestPath(instanceDigest *digest.Digest) (string, error) { + if instanceDigest != nil { +- return filepath.Join(ref.path, instanceDigest.Encoded()+".manifest.json") ++ if err := instanceDigest.Validate(); err != nil { // digest.Digest.Encoded() panics on failure, and could possibly result in a path with ../, so validate explicitly. ++ return "", err ++ } ++ return filepath.Join(ref.path, instanceDigest.Encoded()+".manifest.json"), nil + } +- return filepath.Join(ref.path, "manifest.json") ++ return filepath.Join(ref.path, "manifest.json"), nil + } + + // layerPath returns a path for a layer tarball within a directory using our conventions. +-func (ref dirReference) layerPath(digest digest.Digest) string { ++func (ref dirReference) layerPath(digest digest.Digest) (string, error) { ++ if err := digest.Validate(); err != nil { // digest.Digest.Encoded() panics on failure, and could possibly result in a path with ../, so validate explicitly. ++ return "", err ++ } + // FIXME: Should we keep the digest identification? +- return filepath.Join(ref.path, digest.Encoded()) ++ return filepath.Join(ref.path, digest.Encoded()), nil + } + + // signaturePath returns a path for a signature within a directory using our conventions. +-func (ref dirReference) signaturePath(index int, instanceDigest *digest.Digest) string { ++func (ref dirReference) signaturePath(index int, instanceDigest *digest.Digest) (string, error) { + if instanceDigest != nil { +- return filepath.Join(ref.path, fmt.Sprintf(instanceDigest.Encoded()+".signature-%d", index+1)) ++ if err := instanceDigest.Validate(); err != nil { // digest.Digest.Encoded() panics on failure, and could possibly result in a path with ../, so validate explicitly. ++ return "", err ++ } ++ return filepath.Join(ref.path, fmt.Sprintf(instanceDigest.Encoded()+".signature-%d", index+1)), nil + } +- return filepath.Join(ref.path, fmt.Sprintf("signature-%d", index+1)) ++ return filepath.Join(ref.path, fmt.Sprintf("signature-%d", index+1)), nil + } + + // versionPath returns a path for the version file within a directory using our conventions. +diff --git a/vendor/github.com/containers/image/v5/docker/docker_client.go b/vendor/github.com/containers/image/v5/docker/docker_client.go +index 3fe9a11d0..08f5d66e4 100644 +--- a/vendor/github.com/containers/image/v5/docker/docker_client.go ++++ b/vendor/github.com/containers/image/v5/docker/docker_client.go +@@ -796,6 +796,10 @@ func (c *dockerClient) detectProperties(ctx context.Context) error { + // getExtensionsSignatures returns signatures from the X-Registry-Supports-Signatures API extension, + // using the original data structures. + func (c *dockerClient) getExtensionsSignatures(ctx context.Context, ref dockerReference, manifestDigest digest.Digest) (*extensionSignatureList, error) { ++ // Custom patch for CVE-2024-3727 ++ if err := manifestDigest.Validate(); err != nil { // Make sure manifestDigest.String() does not contain any unexpected characters ++ return nil, err ++ } + path := fmt.Sprintf(extensionsSignaturePath, reference.Path(ref.ref), manifestDigest) + res, err := c.makeRequest(ctx, http.MethodGet, path, nil, nil, v2Auth, nil) + if err != nil { +diff --git a/vendor/github.com/containers/image/v5/docker/docker_image.go b/vendor/github.com/containers/image/v5/docker/docker_image.go +index c84bb37d2..284b39f50 100644 +--- a/vendor/github.com/containers/image/v5/docker/docker_image.go ++++ b/vendor/github.com/containers/image/v5/docker/docker_image.go +@@ -83,7 +83,12 @@ func GetRepositoryTags(ctx context.Context, sys *types.SystemContext, ref types. + if err = json.NewDecoder(res.Body).Decode(&tagsHolder); err != nil { + return nil, err + } +- tags = append(tags, tagsHolder.Tags...) ++ for _, tag := range tagsHolder.Tags { ++ if _, err := reference.WithTag(dr.ref, tag); err != nil { // Ensure the tag does not contain unexpected values ++ return nil, fmt.Errorf("registry returned invalid tag %q: %w", tag, err) ++ } ++ tags = append(tags, tag) ++ } + + link := res.Header.Get("Link") + if link == "" { +diff --git a/vendor/github.com/containers/image/v5/docker/docker_image_dest.go b/vendor/github.com/containers/image/v5/docker/docker_image_dest.go +index 360a7122e..323a42a86 100644 +--- a/vendor/github.com/containers/image/v5/docker/docker_image_dest.go ++++ b/vendor/github.com/containers/image/v5/docker/docker_image_dest.go +@@ -213,6 +213,9 @@ func (d *dockerImageDestination) PutBlob(ctx context.Context, stream io.Reader, + // If the destination does not contain the blob, or it is unknown, blobExists ordinarily returns (false, -1, nil); + // it returns a non-nil error only on an unexpected failure. + func (d *dockerImageDestination) blobExists(ctx context.Context, repo reference.Named, digest digest.Digest, extraScope *authScope) (bool, int64, error) { ++ if err := digest.Validate(); err != nil { // Make sure digest.String() does not contain any unexpected characters ++ return false, -1, err ++ } + checkPath := fmt.Sprintf(blobsPath, reference.Path(repo), digest.String()) + logrus.Debugf("Checking %s", checkPath) + res, err := d.c.makeRequest(ctx, http.MethodHead, checkPath, nil, nil, v2Auth, extraScope) +@@ -639,6 +642,7 @@ sigExists: + return err + } + ++ // manifestDigest is known to be valid because it was not rejected by getExtensionsSignatures above. + path := fmt.Sprintf(extensionsSignaturePath, reference.Path(d.ref.ref), manifestDigest.String()) + res, err := d.c.makeRequest(ctx, http.MethodPut, path, nil, bytes.NewReader(body), v2Auth, nil) + if err != nil { +diff --git a/vendor/github.com/containers/image/v5/docker/docker_image_src.go b/vendor/github.com/containers/image/v5/docker/docker_image_src.go +index 5dc8e7b1f..1d79c56bd 100644 +--- a/vendor/github.com/containers/image/v5/docker/docker_image_src.go ++++ b/vendor/github.com/containers/image/v5/docker/docker_image_src.go +@@ -178,6 +178,9 @@ func simplifyContentType(contentType string) string { + // this never happens if the primary manifest is not a manifest list (e.g. if the source never returns manifest lists). + func (s *dockerImageSource) GetManifest(ctx context.Context, instanceDigest *digest.Digest) ([]byte, string, error) { + if instanceDigest != nil { ++ if err := instanceDigest.Validate(); err != nil { // Make sure instanceDigest.String() does not contain any unexpected characters ++ return nil, "", err ++ } + return s.fetchManifest(ctx, instanceDigest.String()) + } + err := s.ensureManifestIsLoaded(ctx) +@@ -362,6 +365,9 @@ func (s *dockerImageSource) GetBlob(ctx context.Context, info types.BlobInfo, ca + return s.getExternalBlob(ctx, info.URLs) + } + ++ if err := info.Digest.Validate(); err != nil { // Make sure info.Digest.String() does not contain any unexpected characters ++ return nil, 0, err ++ } + path := fmt.Sprintf(blobsPath, reference.Path(s.physicalRef.ref), info.Digest.String()) + logrus.Debugf("Downloading %s", path) + res, err := s.c.makeRequest(ctx, http.MethodGet, path, nil, nil, v2Auth, nil) +diff --git a/vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go b/vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go +index a558657b6..bb093032a 100644 +--- a/vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go ++++ b/vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go +@@ -143,11 +143,19 @@ func (d *Destination) PutBlob(ctx context.Context, stream io.Reader, inputInfo t + return types.BlobInfo{}, errors.Wrap(err, "reading Config file stream") + } + d.config = buf +- if err := d.archive.sendFileLocked(d.archive.configPath(inputInfo.Digest), inputInfo.Size, bytes.NewReader(buf)); err != nil { ++ configPath, err := d.archive.configPath(inputInfo.Digest) ++ if err != nil { ++ return types.BlobInfo{}, errors.Wrap(err, "getting config path") ++ } ++ if err := d.archive.sendFileLocked(configPath, inputInfo.Size, bytes.NewReader(buf)); err != nil { + return types.BlobInfo{}, errors.Wrap(err, "writing Config file") + } + } else { +- if err := d.archive.sendFileLocked(d.archive.physicalLayerPath(inputInfo.Digest), inputInfo.Size, stream); err != nil { ++ layerPath, err := d.archive.physicalLayerPath(inputInfo.Digest) ++ if err != nil { ++ return types.BlobInfo{}, err ++ } ++ if err := d.archive.sendFileLocked(layerPath, inputInfo.Size, stream); err != nil { + return types.BlobInfo{}, err + } + } +diff --git a/vendor/github.com/containers/image/v5/docker/internal/tarfile/writer.go b/vendor/github.com/containers/image/v5/docker/internal/tarfile/writer.go +index 255f0d354..742f977c0 100644 +--- a/vendor/github.com/containers/image/v5/docker/internal/tarfile/writer.go ++++ b/vendor/github.com/containers/image/v5/docker/internal/tarfile/writer.go +@@ -92,7 +92,10 @@ func (w *Writer) ensureSingleLegacyLayerLocked(layerID string, layerDigest diges + if _, ok := w.legacyLayers[layerID]; !ok { + // Create a symlink for the legacy format, where there is one subdirectory per layer ("image"). + // See also the comment in physicalLayerPath. +- physicalLayerPath := w.physicalLayerPath(layerDigest) ++ physicalLayerPath, err := w.physicalLayerPath(layerDigest) ++ if err != nil { ++ return err ++ } + if err := w.sendSymlinkLocked(filepath.Join(layerID, legacyLayerFileName), filepath.Join("..", physicalLayerPath)); err != nil { + return errors.Wrap(err, "creating layer symbolic link") + } +@@ -136,6 +139,9 @@ func (w *Writer) writeLegacyMetadataLocked(layerDescriptors []manifest.Schema2De + } + + // This chainID value matches the computation in docker/docker/layer.CreateChainID … ++ if err := l.Digest.Validate(); err != nil { // This should never fail on this code path, still: make sure the chainID computation is unambiguous. ++ return err ++ } + if chainID == "" { + chainID = l.Digest + } else { +@@ -206,12 +212,20 @@ func checkManifestItemsMatch(a, b *ManifestItem) error { + func (w *Writer) ensureManifestItemLocked(layerDescriptors []manifest.Schema2Descriptor, configDigest digest.Digest, repoTags []reference.NamedTagged) error { + layerPaths := []string{} + for _, l := range layerDescriptors { +- layerPaths = append(layerPaths, w.physicalLayerPath(l.Digest)) ++ p, err := w.physicalLayerPath(l.Digest) ++ if err != nil { ++ return err ++ } ++ layerPaths = append(layerPaths, p) + } + + var item *ManifestItem ++ configPath, err := w.configPath(configDigest) ++ if err != nil { ++ return err ++ } + newItem := ManifestItem{ +- Config: w.configPath(configDigest), ++ Config: configPath, + RepoTags: []string{}, + Layers: layerPaths, + Parent: "", // We don’t have this information +@@ -296,21 +310,27 @@ func (w *Writer) Close() error { + // configPath returns a path we choose for storing a config with the specified digest. + // NOTE: This is an internal implementation detail, not a format property, and can change + // any time. +-func (w *Writer) configPath(configDigest digest.Digest) string { +- return configDigest.Hex() + ".json" ++func (w *Writer) configPath(configDigest digest.Digest) (string, error) { ++ if err := configDigest.Validate(); err != nil { // digest.Digest.Hex() panics on failure, and could possibly result in unexpected paths, so validate explicitly. ++ return "", err ++ } ++ return configDigest.Hex() + ".json", nil + } + + // physicalLayerPath returns a path we choose for storing a layer with the specified digest + // (the actual path, i.e. a regular file, not a symlink that may be used in the legacy format). + // NOTE: This is an internal implementation detail, not a format property, and can change + // any time. +-func (w *Writer) physicalLayerPath(layerDigest digest.Digest) string { ++func (w *Writer) physicalLayerPath(layerDigest digest.Digest) (string, error) { ++ if err := layerDigest.Validate(); err != nil { // digest.Digest.Hex() panics on failure, and could possibly result in unexpected paths, so validate explicitly. ++ return "", err ++ } + // Note that this can't be e.g. filepath.Join(l.Digest.Hex(), legacyLayerFileName); due to the way + // writeLegacyMetadata constructs layer IDs differently from inputinfo.Digest values (as described + // inside it), most of the layers would end up in subdirectories alone without any metadata; (docker load) + // tries to load every subdirectory as an image and fails if the config is missing. So, keep the layers + // in the root of the tarball. +- return layerDigest.Hex() + ".tar" ++ return layerDigest.Hex() + ".tar", nil + } + + type tarFI struct { +diff --git a/vendor/github.com/containers/image/v5/ostree/ostree_dest.go b/vendor/github.com/containers/image/v5/ostree/ostree_dest.go +index c91a49c57..fc5d58d45 100644 +--- a/vendor/github.com/containers/image/v5/ostree/ostree_dest.go ++++ b/vendor/github.com/containers/image/v5/ostree/ostree_dest.go +@@ -352,6 +352,10 @@ func (d *ostreeImageDestination) TryReusingBlob(ctx context.Context, info types. + } + d.repo = repo + } ++ ++ if err := info.Digest.Validate(); err != nil { // digest.Digest.Hex() panics on failure, so validate explicitly. ++ return false, types.BlobInfo{}, err ++ } + branch := fmt.Sprintf("ociimage/%s", info.Digest.Hex()) + + found, data, err := readMetadata(d.repo, branch, "docker.uncompressed_digest") +@@ -472,12 +476,18 @@ func (d *ostreeImageDestination) Commit(context.Context, types.UnparsedImage) er + return nil + } + for _, layer := range d.schema.LayersDescriptors { ++ if err := layer.Digest.Validate(); err != nil { // digest.Digest.Encoded() panics on failure, so validate explicitly. ++ return err ++ } + hash := layer.Digest.Hex() + if err = checkLayer(hash); err != nil { + return err + } + } + for _, layer := range d.schema.FSLayers { ++ if err := layer.BlobSum.Validate(); err != nil { // digest.Digest.Encoded() panics on failure, so validate explicitly. ++ return err ++ } + hash := layer.BlobSum.Hex() + if err = checkLayer(hash); err != nil { + return err +diff --git a/vendor/github.com/containers/image/v5/ostree/ostree_src.go b/vendor/github.com/containers/image/v5/ostree/ostree_src.go +index 4948ec664..9c4b53968 100644 +--- a/vendor/github.com/containers/image/v5/ostree/ostree_src.go ++++ b/vendor/github.com/containers/image/v5/ostree/ostree_src.go +@@ -272,7 +272,9 @@ func (s *ostreeImageSource) HasThreadSafeGetBlob() bool { + // The Digest field in BlobInfo is guaranteed to be provided, Size may be -1 and MediaType may be optionally provided. + // May update BlobInfoCache, preferably after it knows for certain that a blob truly exists at a specific location. + func (s *ostreeImageSource) GetBlob(ctx context.Context, info types.BlobInfo, cache types.BlobInfoCache) (io.ReadCloser, int64, error) { +- ++ if err := info.Digest.Validate(); err != nil { // digest.Digest.Encoded() panics on failure, so validate explicitly. ++ return nil, -1, err ++ } + blob := info.Digest.Hex() + + // Ensure s.compressed is initialized. It is build by LayerInfosForCopy. +diff --git a/vendor/github.com/containers/image/v5/storage/storage_image.go b/vendor/github.com/containers/image/v5/storage/storage_image.go +index 6b0fea61a..433bf383d 100644 +--- a/vendor/github.com/containers/image/v5/storage/storage_image.go ++++ b/vendor/github.com/containers/image/v5/storage/storage_image.go +@@ -96,14 +96,21 @@ type storageImageCloser struct { + // manifestBigDataKey returns a key suitable for recording a manifest with the specified digest using storage.Store.ImageBigData and related functions. + // If a specific manifest digest is explicitly requested by the user, the key returned by this function should be used preferably; + // for compatibility, if a manifest is not available under this key, check also storage.ImageDigestBigDataKey +-func manifestBigDataKey(digest digest.Digest) string { +- return storage.ImageDigestManifestBigDataNamePrefix + "-" + digest.String() ++func manifestBigDataKey(digest digest.Digest) (string, error) { ++ // return storage.ImageDigestManifestBigDataNamePrefix + "-" + digest.String() ++ if err := digest.Validate(); err != nil { // Make sure info.Digest.String() uses the expected format and does not collide with other BigData keys. ++ return "", err ++ } ++ return storage.ImageDigestManifestBigDataNamePrefix + "-" + digest.String(), nil + } + + // signatureBigDataKey returns a key suitable for recording the signatures associated with the manifest with the specified digest using storage.Store.ImageBigData and related functions. + // If a specific manifest digest is explicitly requested by the user, the key returned by this function should be used preferably; +-func signatureBigDataKey(digest digest.Digest) string { +- return "signature-" + digest.Encoded() ++func signatureBigDataKey(digest digest.Digest) (string, error) { ++ if err := digest.Validate(); err != nil { // digest.Digest.Encoded() panics on failure, so validate explicitly. ++ return "", err ++ } ++ return "signature-" + digest.Encoded(), nil + } + + // newImageSource sets up an image for reading. +@@ -239,8 +246,12 @@ func (s *storageImageSource) getBlobAndLayerID(info types.BlobInfo) (rc io.ReadC + + // GetManifest() reads the image's manifest. + func (s *storageImageSource) GetManifest(ctx context.Context, instanceDigest *digest.Digest) (manifestBlob []byte, MIMEType string, err error) { ++ // Custom patch for CVE-2024-3727 + if instanceDigest != nil { +- key := manifestBigDataKey(*instanceDigest) ++ key, err := manifestBigDataKey(*instanceDigest) ++ if err != nil { ++ return nil, "", errors.Wrapf(err, "generating manifest big data key for image instance %q", *instanceDigest) ++ } + blob, err := s.imageRef.transport.store.ImageBigData(s.image.ID, key) + if err != nil { + return nil, "", errors.Wrapf(err, "reading manifest for image instance %q", *instanceDigest) +@@ -252,7 +263,10 @@ func (s *storageImageSource) GetManifest(ctx context.Context, instanceDigest *di + // Prefer the manifest corresponding to the user-specified digest, if available. + if s.imageRef.named != nil { + if digested, ok := s.imageRef.named.(reference.Digested); ok { +- key := manifestBigDataKey(digested.Digest()) ++ key, err := manifestBigDataKey(digested.Digest()) ++ if err != nil { ++ return nil, "", err ++ } + blob, err := s.imageRef.transport.store.ImageBigData(s.image.ID, key) + if err != nil && !os.IsNotExist(err) { // os.IsNotExist is true if the image exists but there is no data corresponding to key + return nil, "", err +@@ -365,7 +379,10 @@ func (s *storageImageSource) GetSignatures(ctx context.Context, instanceDigest * + instance := "default instance" + if instanceDigest != nil { + signatureSizes = s.SignaturesSizes[*instanceDigest] +- key = signatureBigDataKey(*instanceDigest) ++ key, err = signatureBigDataKey(*instanceDigest) ++ if err != nil { ++ return nil, errors.Wrapf(err, "generating signature big data key for image instance %q", *instanceDigest) ++ } + instance = instanceDigest.Encoded() + } + if len(signatureSizes) > 0 { +@@ -1140,7 +1157,10 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t + if err != nil { + return errors.Wrapf(err, "digesting top-level manifest") + } +- key := manifestBigDataKey(manifestDigest) ++ key, err := manifestBigDataKey(manifestDigest) ++ if err != nil { ++ return errors.Wrapf(err, "getting manifest big data key for image %q", img.ID) ++ } + if err := s.imageRef.transport.store.SetImageBigData(img.ID, key, toplevelManifest, manifest.Digest); err != nil { + logrus.Debugf("error saving top-level manifest for image %q: %v", img.ID, err) + return errors.Wrapf(err, "saving top-level manifest for image %q", img.ID) +@@ -1149,7 +1169,10 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t + // Save the image's manifest. Allow looking it up by digest by using the key convention defined by the Store. + // Record the manifest twice: using a digest-specific key to allow references to that specific digest instance, + // and using storage.ImageDigestBigDataKey for future users that don’t specify any digest and for compatibility with older readers. +- key := manifestBigDataKey(s.manifestDigest) ++ key, err := manifestBigDataKey(s.manifestDigest) ++ if err != nil { ++ return errors.Wrapf(err, "getting manifest big data key for image %q", img.ID) ++ } + if err := s.imageRef.transport.store.SetImageBigData(img.ID, key, s.manifest, manifest.Digest); err != nil { + logrus.Debugf("error saving manifest for image %q: %v", img.ID, err) + return errors.Wrapf(err, "saving manifest for image %q", img.ID) +@@ -1167,7 +1190,10 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t + } + } + for instanceDigest, signatures := range s.signatureses { +- key := signatureBigDataKey(instanceDigest) ++ key, err := signatureBigDataKey(instanceDigest) ++ if err != nil { ++ return err ++ } + if err := s.imageRef.transport.store.SetImageBigData(img.ID, key, signatures, manifest.Digest); err != nil { + logrus.Debugf("error saving signatures for image %q: %v", img.ID, err) + return errors.Wrapf(err, "saving signatures for image %q", img.ID) +diff --git a/vendor/github.com/containers/image/v5/storage/storage_reference.go b/vendor/github.com/containers/image/v5/storage/storage_reference.go +index 1aafe9068..ea4846346 100644 +--- a/vendor/github.com/containers/image/v5/storage/storage_reference.go ++++ b/vendor/github.com/containers/image/v5/storage/storage_reference.go +@@ -72,7 +72,10 @@ func multiArchImageMatchesSystemContext(store storage.Store, img *storage.Image, + // We don't need to care about storage.ImageDigestBigDataKey because + // manifests lists are only stored into storage by c/image versions + // that know about manifestBigDataKey, and only using that key. +- key := manifestBigDataKey(manifestDigest) ++ key, err := manifestBigDataKey(manifestDigest) ++ if err != nil { ++ return false // This should never happen, manifestDigest comes from a reference.Digested, and that validates the format. ++ } + manifestBytes, err := store.ImageBigData(img.ID, key) + if err != nil { + return false +@@ -94,7 +97,10 @@ func multiArchImageMatchesSystemContext(store storage.Store, img *storage.Image, + if err != nil { + return false + } +- key = manifestBigDataKey(chosenInstance) ++ key, err = manifestBigDataKey(chosenInstance) ++ if err != nil { ++ return false ++ } + _, err = store.ImageBigData(img.ID, key) + return err == nil // true if img.ID is based on chosenInstance. + } +-- +2.34.1 + diff --git a/SPECS/libnbd/CVE-2024-7383.patch b/SPECS/libnbd/CVE-2024-7383.patch new file mode 100644 index 00000000000..7dfb9da1fa7 --- /dev/null +++ b/SPECS/libnbd/CVE-2024-7383.patch @@ -0,0 +1,119 @@ +From c6cc19319f39c09c4ff74b47101eb217e75d3b43 Mon Sep 17 00:00:00 2001 +From: Brian Fjeldstad +Date: Mon, 19 Aug 2024 21:59:46 +0000 +Subject: [PATCH 1/3] port patch #1 + +--- + configure.ac | 6 ++---- + lib/crypto.c | 4 ---- + 2 files changed, 2 insertions(+), 8 deletions(-) + +diff --git a/configure.ac b/configure.ac +index b6e2c9f..07e417b 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -150,12 +150,12 @@ AC_ARG_WITH([gnutls], + [], + [with_gnutls=check]) + AS_IF([test "$with_gnutls" != "no"],[ +- PKG_CHECK_MODULES([GNUTLS], [gnutls >= 3.3.0], [ ++ PKG_CHECK_MODULES([GNUTLS], [gnutls >= 3.5.18], [ + AC_SUBST([GNUTLS_CFLAGS]) + AC_SUBST([GNUTLS_LIBS]) + AC_DEFINE([HAVE_GNUTLS],[1],[gnutls found at compile time.]) + ], [ +- AC_MSG_WARN([gnutls not found or < 3.3.0, TLS support will be disabled.]) ++ AC_MSG_WARN([gnutls not found or < 3.5.18, TLS support will be disabled.]) + ]) + ]) + AM_CONDITIONAL([HAVE_GNUTLS], [test "x$GNUTLS_LIBS" != "x"]) +@@ -174,8 +174,6 @@ AS_IF([test "$GNUTLS_LIBS" != ""],[ + # Check for APIs which may not be present. + old_LIBS="$LIBS" + LIBS="$GNUTLS_LIBS $LIBS" +- AC_CHECK_FUNCS([\ +- gnutls_session_set_verify_cert]) + LIBS="$old_LIBS" + ]) + +diff --git a/lib/crypto.c b/lib/crypto.c +index 340a6a0..964a871 100644 +--- a/lib/crypto.c ++++ b/lib/crypto.c +@@ -514,12 +514,8 @@ set_up_certificate_credentials (struct nbd_handle *h, + return NULL; + + found_certificates: +-#ifdef HAVE_GNUTLS_SESSION_SET_VERIFY_CERT + if (h->hostname && h->tls_verify_peer) + gnutls_session_set_verify_cert (session, h->hostname, 0); +-#else +- debug (h, "ignoring nbd_set_tls_verify_peer, this requires GnuTLS >= 3.4.6"); +-#endif + + err = gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, ret); + if (err < 0) { +-- +2.34.1 + +From 7ece17bfb16d437975ac40d63b0f20162601d3bf Mon Sep 17 00:00:00 2001 +From: Brian Fjeldstad +Date: Mon, 19 Aug 2024 22:01:17 +0000 +Subject: [PATCH 2/3] port patch #2 + +--- + lib/crypto.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/lib/crypto.c b/lib/crypto.c +index 964a871..97884b8 100644 +--- a/lib/crypto.c ++++ b/lib/crypto.c +@@ -514,9 +514,6 @@ set_up_certificate_credentials (struct nbd_handle *h, + return NULL; + + found_certificates: +- if (h->hostname && h->tls_verify_peer) +- gnutls_session_set_verify_cert (session, h->hostname, 0); +- + err = gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, ret); + if (err < 0) { + set_error (0, "gnutls_credentials_set: %s", gnutls_strerror (err)); +@@ -626,6 +623,9 @@ nbd_internal_crypto_create_session (struct nbd_handle *h, + gnutls_deinit (session); + return NULL; + } ++ ++ if (h->hostname && h->tls_verify_peer) ++ gnutls_session_set_verify_cert (session, h->hostname, 0); + } + + /* Wrap the underlying socket with GnuTLS. */ +-- +2.34.1 + +From 811a9bc9797b539dafb4423933243950b3aae3c1 Mon Sep 17 00:00:00 2001 +From: Brian Fjeldstad +Date: Mon, 19 Aug 2024 22:01:56 +0000 +Subject: [PATCH 3/3] port patch #3 + +--- + lib/crypto.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/crypto.c b/lib/crypto.c +index 97884b8..c6a21d2 100644 +--- a/lib/crypto.c ++++ b/lib/crypto.c +@@ -624,7 +624,7 @@ nbd_internal_crypto_create_session (struct nbd_handle *h, + return NULL; + } + +- if (h->hostname && h->tls_verify_peer) ++ if (h->tls_verify_peer) + gnutls_session_set_verify_cert (session, h->hostname, 0); + } + +-- +2.34.1 + diff --git a/SPECS/libnbd/libnbd.spec b/SPECS/libnbd/libnbd.spec index 06ecaaf69ed..e3d5e632256 100644 --- a/SPECS/libnbd/libnbd.spec +++ b/SPECS/libnbd/libnbd.spec @@ -3,13 +3,16 @@ Summary: NBD client library in userspace Name: libnbd Version: 1.12.1 -Release: 3%{?dist} +Release: 4%{?dist} License: LGPLv2+ Vendor: Microsoft Corporation Distribution: Mariner URL: https://gitlab.com/nbdkit/libnbd Source0: https://libguestfs.org/download/libnbd/%{source_directory}/%{name}-%{version}.tar.gz Patch0: CVE-2023-5215.patch + +Patch001: CVE-2024-7383.patch + # For the core library. BuildRequires: gcc BuildRequires: make @@ -232,6 +235,9 @@ skip_test tests/connect-tcp6 %changelog +* Mon Aug 19 2024 Brian Fjeldstad - 1.12.1-4 +- Add patch to fix CVE-2024-7383 + * Thu Oct 19 2023 Neha Agarwal - 1.12.1-3 - Add patch to fix CVE-2023-5215 diff --git a/SPECS/libnvidia-container/libnvidia-container.spec b/SPECS/libnvidia-container/libnvidia-container.spec index e3badbf146f..40b53460c90 100644 --- a/SPECS/libnvidia-container/libnvidia-container.spec +++ b/SPECS/libnvidia-container/libnvidia-container.spec @@ -4,7 +4,7 @@ Summary: NVIDIA container runtime library Name: libnvidia-container Version: 1.13.5 -Release: 6%{?dist} +Release: 7%{?dist} License: BSD AND ASL2.0 AND GPLv3+ AND LGPLv3+ AND MIT AND GPLv2 Vendor: Microsoft Corporation Distribution: Mariner @@ -132,6 +132,9 @@ This package contains command-line tools that facilitate using the library. %{_bindir}/* %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 1.13.5-7 +- Bump release to rebuild with go 1.22.7 + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 1.13.5-6 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS/libsndfile/CVE-2022-33065.patch b/SPECS/libsndfile/CVE-2022-33065.patch new file mode 100644 index 00000000000..e78c1201895 --- /dev/null +++ b/SPECS/libsndfile/CVE-2022-33065.patch @@ -0,0 +1,684 @@ +From 30a57d115d4558b2235a06de2902aec1697c75fa Mon Sep 17 00:00:00 2001 +From: Sumedh Sharma +Date: Fri, 23 Aug 2024 12:19:14 +0530 +Subject: [PATCH] Add patch to resolve CVE-2022-33065 + +Based on upstream PR: https://github.com/libsndfile/libsndfile/pull/979 +Fix various numeric overflow vulns throughout code (CVE-2022-33065) #979 + +--- + Makefile.am | 2 +- + ossfuzz/sndfile_fuzzer.cc | 5 +++ + src/aiff.c | 2 +- + src/au.c | 14 ++++--- + src/avr.c | 2 +- + src/command.c | 1 + + src/common.c | 41 ++++++++++++------- + src/common.h | 2 +- + src/ima_adpcm.c | 4 +- + src/ircam.c | 10 ++--- + src/mat4.c | 4 +- + src/mat5.c | 2 +- + src/nms_adpcm.c | 85 +++++++++++++++++++-------------------- + src/pcm.c | 2 +- + src/rf64.c | 2 +- + src/sds.c | 6 +-- + 16 files changed, 102 insertions(+), 82 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index 205c8bf..e68cf05 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -439,7 +439,7 @@ if USE_OSSFUZZ_STATIC + FUZZ_LDADD = $(LIB_FUZZING_ENGINE) + FUZZ_FLAG = + else +-FUZZ_LDADD = libstandaloneengine.la ++FUZZ_LDADD = ossfuzz/libstandaloneengine.la + FUZZ_FLAG = + endif + endif +diff --git a/ossfuzz/sndfile_fuzzer.cc b/ossfuzz/sndfile_fuzzer.cc +index 3c85073..d14c219 100644 +--- a/ossfuzz/sndfile_fuzzer.cc ++++ b/ossfuzz/sndfile_fuzzer.cc +@@ -5,6 +5,8 @@ + #include + #include + ++#include ++ + typedef struct + { + sf_count_t offset; +@@ -38,6 +40,9 @@ static sf_count_t vfseek (sf_count_t offset, int whence, void *user_data) + break; + + default: ++ // SEEK_DATA and SEEK_HOLE are not supported by this function. ++ errno = EINVAL ; ++ return -1 ; + break; + } + +diff --git a/src/aiff.c b/src/aiff.c +index d872a89..ff68de2 100644 +--- a/src/aiff.c ++++ b/src/aiff.c +@@ -1685,7 +1685,7 @@ static int + aiff_read_basc_chunk (SF_PRIVATE * psf, int datasize) + { const char * type_str ; + basc_CHUNK bc ; +- int count ; ++ sf_count_t count ; + + count = psf_binheader_readf (psf, "E442", &bc.version, &bc.numBeats, &bc.rootNote) ; + count += psf_binheader_readf (psf, "E222", &bc.scaleType, &bc.sigNumerator, &bc.sigDenominator) ; +diff --git a/src/au.c b/src/au.c +index 62bd691..22997be 100644 +--- a/src/au.c ++++ b/src/au.c +@@ -291,7 +291,8 @@ static int + au_read_header (SF_PRIVATE *psf) + { AU_FMT au_fmt ; + int marker, dword ; +- ++ sf_count_t data_end ; ++ + memset (&au_fmt, 0, sizeof (au_fmt)) ; + psf_binheader_readf (psf, "pm", 0, &marker) ; + psf_log_printf (psf, "%M\n", marker) ; +@@ -316,15 +317,16 @@ au_read_header (SF_PRIVATE *psf) + { psf_log_printf (psf, " Data Size : -1\n") ; + return SFE_AU_EMBED_BAD_LEN ; + } ; +- ++ ++ data_end = (sf_count_t) au_fmt.dataoffset + (sf_count_t) au_fmt.datasize ; + if (psf->fileoffset > 0) +- { psf->filelength = au_fmt.dataoffset + au_fmt.datasize ; ++ { psf->filelength = data_end ; + psf_log_printf (psf, " Data Size : %d\n", au_fmt.datasize) ; + } +- else if (au_fmt.datasize == -1 || au_fmt.dataoffset + au_fmt.datasize == psf->filelength) ++ else if (au_fmt.datasize == -1 || data_end == psf->filelength) + psf_log_printf (psf, " Data Size : %d\n", au_fmt.datasize) ; +- else if (au_fmt.dataoffset + au_fmt.datasize < psf->filelength) +- { psf->filelength = au_fmt.dataoffset + au_fmt.datasize ; ++ else if (data_end < psf->filelength) ++ { psf->filelength = data_end ; + psf_log_printf (psf, " Data Size : %d\n", au_fmt.datasize) ; + } + else +diff --git a/src/avr.c b/src/avr.c +index bd6b00f..ffc8323 100644 +--- a/src/avr.c ++++ b/src/avr.c +@@ -164,7 +164,7 @@ avr_read_header (SF_PRIVATE *psf) + psf->endian = SF_ENDIAN_BIG ; + + psf->dataoffset = AVR_HDR_SIZE ; +- psf->datalength = hdr.frames * (hdr.rez / 8) ; ++ psf->datalength = (sf_count_t) hdr.frames * (hdr.rez / 8) ; + + if (psf->fileoffset > 0) + psf->filelength = AVR_HDR_SIZE + psf->datalength ; +diff --git a/src/command.c b/src/command.c +index 15037ab..611f894 100644 +--- a/src/command.c ++++ b/src/command.c +@@ -18,6 +18,7 @@ + + #include "sfconfig.h" + ++#include + #include + #include + #include +diff --git a/src/common.c b/src/common.c +index c9737a9..2f7722d 100644 +--- a/src/common.c ++++ b/src/common.c +@@ -18,6 +18,7 @@ + + #include + ++#include + #include + #include + #if HAVE_UNISTD_H +@@ -962,14 +963,16 @@ psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...) + double *doubleptr ; + char c ; + int byte_count = 0, count = 0 ; +- ++ int read_bytes = 0 ; ++ + if (! format) + return psf_ftell (psf) ; + + va_start (argptr, format) ; + + while ((c = *format++)) +- { ++ { ++ read_bytes = 0 ; + if (psf->header.indx + 16 >= psf->header.len && psf_bump_header_allocation (psf, 16)) + return count ; + +@@ -986,7 +989,7 @@ psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...) + intptr = va_arg (argptr, unsigned int*) ; + *intptr = 0 ; + ucptr = (unsigned char*) intptr ; +- byte_count += header_read (psf, ucptr, sizeof (int)) ; ++ read_bytes = header_read (psf, ucptr, sizeof (int)) ; + *intptr = GET_MARKER (ucptr) ; + break ; + +@@ -994,7 +997,7 @@ psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...) + intptr = va_arg (argptr, unsigned int*) ; + *intptr = 0 ; + ucptr = (unsigned char*) intptr ; +- byte_count += header_read (psf, sixteen_bytes, sizeof (sixteen_bytes)) ; ++ read_bytes = header_read (psf, sixteen_bytes, sizeof (sixteen_bytes)) ; + { int k ; + intdata = 0 ; + for (k = 0 ; k < 16 ; k++) +@@ -1006,14 +1009,14 @@ psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...) + case '1' : + charptr = va_arg (argptr, char*) ; + *charptr = 0 ; +- byte_count += header_read (psf, charptr, sizeof (char)) ; ++ read_bytes = header_read (psf, charptr, sizeof (char)) ; + break ; + + case '2' : /* 2 byte value with the current endian-ness */ + shortptr = va_arg (argptr, unsigned short*) ; + *shortptr = 0 ; + ucptr = (unsigned char*) shortptr ; +- byte_count += header_read (psf, ucptr, sizeof (short)) ; ++ read_bytes = header_read (psf, ucptr, sizeof (short)) ; + if (psf->rwf_endian == SF_ENDIAN_BIG) + *shortptr = GET_BE_SHORT (ucptr) ; + else +@@ -1023,7 +1026,7 @@ psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...) + case '3' : /* 3 byte value with the current endian-ness */ + intptr = va_arg (argptr, unsigned int*) ; + *intptr = 0 ; +- byte_count += header_read (psf, sixteen_bytes, 3) ; ++ read_bytes = header_read (psf, sixteen_bytes, 3) ; + if (psf->rwf_endian == SF_ENDIAN_BIG) + *intptr = GET_BE_3BYTE (sixteen_bytes) ; + else +@@ -1034,7 +1037,7 @@ psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...) + intptr = va_arg (argptr, unsigned int*) ; + *intptr = 0 ; + ucptr = (unsigned char*) intptr ; +- byte_count += header_read (psf, ucptr, sizeof (int)) ; ++ read_bytes = header_read (psf, ucptr, sizeof (int)) ; + if (psf->rwf_endian == SF_ENDIAN_BIG) + *intptr = psf_get_be32 (ucptr, 0) ; + else +@@ -1044,7 +1047,7 @@ psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...) + case '8' : /* 8 byte value with the current endian-ness */ + countptr = va_arg (argptr, sf_count_t *) ; + *countptr = 0 ; +- byte_count += header_read (psf, sixteen_bytes, 8) ; ++ read_bytes = header_read (psf, sixteen_bytes, 8) ; + if (psf->rwf_endian == SF_ENDIAN_BIG) + countdata = psf_get_be64 (sixteen_bytes, 0) ; + else +@@ -1055,7 +1058,7 @@ psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...) + case 'f' : /* Float conversion */ + floatptr = va_arg (argptr, float *) ; + *floatptr = 0.0 ; +- byte_count += header_read (psf, floatptr, sizeof (float)) ; ++ read_bytes = header_read (psf, floatptr, sizeof (float)) ; + if (psf->rwf_endian == SF_ENDIAN_BIG) + *floatptr = float32_be_read ((unsigned char*) floatptr) ; + else +@@ -1065,7 +1068,7 @@ psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...) + case 'd' : /* double conversion */ + doubleptr = va_arg (argptr, double *) ; + *doubleptr = 0.0 ; +- byte_count += header_read (psf, doubleptr, sizeof (double)) ; ++ read_bytes = header_read (psf, doubleptr, sizeof (double)) ; + if (psf->rwf_endian == SF_ENDIAN_BIG) + *doubleptr = double64_be_read ((unsigned char*) doubleptr) ; + else +@@ -1089,7 +1092,7 @@ psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...) + charptr = va_arg (argptr, char*) ; + count = va_arg (argptr, size_t) ; + memset (charptr, 0, count) ; +- byte_count += header_read (psf, charptr, count) ; ++ read_bytes = header_read (psf, charptr, count) ; + break ; + + case 'G' : +@@ -1100,7 +1103,7 @@ psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...) + if (psf->header.indx + count >= psf->header.len && psf_bump_header_allocation (psf, count)) + return 0 ; + +- byte_count += header_gets (psf, charptr, count) ; ++ read_bytes = header_gets (psf, charptr, count) ; + break ; + + case 'z' : +@@ -1124,7 +1127,7 @@ psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...) + case 'j' : /* Seek to position from current position. */ + count = va_arg (argptr, size_t) ; + header_seek (psf, count, SEEK_CUR) ; +- byte_count += count ; ++ read_bytes = count ; + break ; + + default : +@@ -1132,8 +1135,18 @@ psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...) + psf->error = SFE_INTERNAL ; + break ; + } ; ++ ++ if (read_bytes > 0 && byte_count > (INT_MAX - read_bytes)) ++ { psf_log_printf (psf, "Header size exceeds INT_MAX. Aborting.", c) ; ++ psf->error = SFE_INTERNAL ; ++ break ; ++ } else ++ { byte_count += read_bytes ; + } ; + ++ } ; /*end while*/ ++ ++ + va_end (argptr) ; + + return byte_count ; +diff --git a/src/common.h b/src/common.h +index 08360d0..8e53df0 100644 +--- a/src/common.h ++++ b/src/common.h +@@ -484,7 +484,7 @@ typedef struct sf_private_tag + sf_count_t datalength ; /* Length in bytes of the audio data. */ + sf_count_t dataend ; /* Offset to file tailer. */ + +- int blockwidth ; /* Size in bytes of one set of interleaved samples. */ ++ sf_count_t blockwidth ; /* Size in bytes of one set of interleaved samples. */ + int bytewidth ; /* Size in bytes of one sample (one channel). */ + + void *dither ; +diff --git a/src/ima_adpcm.c b/src/ima_adpcm.c +index 8c9bbff..d15608b 100644 +--- a/src/ima_adpcm.c ++++ b/src/ima_adpcm.c +@@ -233,7 +233,7 @@ ima_reader_init (SF_PRIVATE *psf, int blockalign, int samplesperblock) + case SF_FORMAT_AIFF : + psf_log_printf (psf, "still need to check block count\n") ; + pima->decode_block = aiff_ima_decode_block ; +- psf->sf.frames = pima->samplesperblock * pima->blocks / pima->channels ; ++ psf->sf.frames = (sf_count_t) pima->samplesperblock * pima->blocks / pima->channels ; + break ; + + default : +@@ -386,7 +386,7 @@ aiff_ima_encode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima) + static int + wavlike_ima_decode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima) + { int chan, k, predictor, blockindx, indx, indxstart, diff ; +- short step, bytecode, stepindx [2] ; ++ short step, bytecode, stepindx [2] = { 0 } ; + + pima->blockcount ++ ; + pima->samplecount = 0 ; +diff --git a/src/ircam.c b/src/ircam.c +index 8e7cdba..3d73ba4 100644 +--- a/src/ircam.c ++++ b/src/ircam.c +@@ -171,35 +171,35 @@ ircam_read_header (SF_PRIVATE *psf) + switch (encoding) + { case IRCAM_PCM_16 : + psf->bytewidth = 2 ; +- psf->blockwidth = psf->sf.channels * psf->bytewidth ; ++ psf->blockwidth = (sf_count_t) psf->sf.channels * psf->bytewidth ; + + psf->sf.format = SF_FORMAT_IRCAM | SF_FORMAT_PCM_16 ; + break ; + + case IRCAM_PCM_32 : + psf->bytewidth = 4 ; +- psf->blockwidth = psf->sf.channels * psf->bytewidth ; ++ psf->blockwidth = (sf_count_t) psf->sf.channels * psf->bytewidth ; + + psf->sf.format = SF_FORMAT_IRCAM | SF_FORMAT_PCM_32 ; + break ; + + case IRCAM_FLOAT : + psf->bytewidth = 4 ; +- psf->blockwidth = psf->sf.channels * psf->bytewidth ; ++ psf->blockwidth = (sf_count_t) psf->sf.channels * psf->bytewidth ; + + psf->sf.format = SF_FORMAT_IRCAM | SF_FORMAT_FLOAT ; + break ; + + case IRCAM_ALAW : + psf->bytewidth = 1 ; +- psf->blockwidth = psf->sf.channels * psf->bytewidth ; ++ psf->blockwidth = (sf_count_t) psf->sf.channels * psf->bytewidth ; + + psf->sf.format = SF_FORMAT_IRCAM | SF_FORMAT_ALAW ; + break ; + + case IRCAM_ULAW : + psf->bytewidth = 1 ; +- psf->blockwidth = psf->sf.channels * psf->bytewidth ; ++ psf->blockwidth = (sf_count_t) psf->sf.channels * psf->bytewidth ; + + psf->sf.format = SF_FORMAT_IRCAM | SF_FORMAT_ULAW ; + break ; +diff --git a/src/mat4.c b/src/mat4.c +index 0b1b414..9f046f0 100644 +--- a/src/mat4.c ++++ b/src/mat4.c +@@ -104,7 +104,7 @@ mat4_open (SF_PRIVATE *psf) + + psf->container_close = mat4_close ; + +- psf->blockwidth = psf->bytewidth * psf->sf.channels ; ++ psf->blockwidth = (sf_count_t) psf->bytewidth * psf->sf.channels ; + + switch (subformat) + { case SF_FORMAT_PCM_16 : +@@ -320,7 +320,7 @@ mat4_read_header (SF_PRIVATE *psf) + psf->filelength - psf->dataoffset, psf->sf.channels * psf->sf.frames * psf->bytewidth) ; + } + else if ((psf->filelength - psf->dataoffset) > psf->sf.channels * psf->sf.frames * psf->bytewidth) +- psf->dataend = psf->dataoffset + rows * cols * psf->bytewidth ; ++ psf->dataend = psf->dataoffset + (sf_count_t) rows * (sf_count_t) cols * psf->bytewidth ; + + psf->datalength = psf->filelength - psf->dataoffset - psf->dataend ; + +diff --git a/src/mat5.c b/src/mat5.c +index da5a6ec..20f0ea6 100644 +--- a/src/mat5.c ++++ b/src/mat5.c +@@ -114,7 +114,7 @@ mat5_open (SF_PRIVATE *psf) + + psf->container_close = mat5_close ; + +- psf->blockwidth = psf->bytewidth * psf->sf.channels ; ++ psf->blockwidth = (sf_count_t) psf->bytewidth * psf->sf.channels ; + + switch (subformat) + { case SF_FORMAT_PCM_U8 : +diff --git a/src/nms_adpcm.c b/src/nms_adpcm.c +index 40f56f5..e903296 100644 +--- a/src/nms_adpcm.c ++++ b/src/nms_adpcm.c +@@ -48,36 +48,36 @@ + /* Variable names from ITU G.726 spec */ + struct nms_adpcm_state + { /* Log of the step size multiplier. Operated on by codewords. */ +- int yl ; ++ short yl ; + + /* Quantizer step size multiplier. Generated from yl. */ +- int y ; ++ short y ; + + /* Coefficents of the pole predictor */ +- int a [2] ; ++ short a [2] ; + + /* Coefficents of the zero predictor */ +- int b [6] ; ++ short b [6] ; + + /* Previous quantized deltas (multiplied by 2^14) */ +- int d_q [7] ; ++ short d_q [7] ; + + /* d_q [x] + s_ez [x], used by the pole-predictor for signs only. */ +- int p [3] ; ++ short p [3] ; + + /* Previous reconstructed signal values. */ +- int s_r [2] ; ++ short s_r [2] ; + + /* Zero predictor components of the signal estimate. */ +- int s_ez ; ++ short s_ez ; + + /* Signal estimate, (including s_ez). */ +- int s_e ; ++ short s_e ; + + /* The most recent codeword (enc:generated, dec:inputted) */ +- int Ik ; ++ char Ik ; + +- int parity ; ++ char parity ; + + /* + ** Offset into code tables for the bitrate. +@@ -109,7 +109,7 @@ typedef struct + } NMS_ADPCM_PRIVATE ; + + /* Pre-computed exponential interval used in the antilog approximation. */ +-static unsigned int table_expn [] = ++static unsigned short table_expn [] = + { 0x4000, 0x4167, 0x42d5, 0x444c, 0x45cb, 0x4752, 0x48e2, 0x4a7a, + 0x4c1b, 0x4dc7, 0x4f7a, 0x5138, 0x52ff, 0x54d1, 0x56ac, 0x5892, + 0x5a82, 0x5c7e, 0x5e84, 0x6096, 0x62b4, 0x64dd, 0x6712, 0x6954, +@@ -117,21 +117,21 @@ static unsigned int table_expn [] = + } ; + + /* Table mapping codewords to scale factor deltas. */ +-static int table_scale_factor_step [] = ++static short table_scale_factor_step [] = + { 0x0, 0x0, 0x0, 0x0, 0x4b0, 0x0, 0x0, 0x0, /* 2-bit */ + -0x3c, 0x0, 0x90, 0x0, 0x2ee, 0x0, 0x898, 0x0, /* 3-bit */ + -0x30, 0x12, 0x6b, 0xc8, 0x188, 0x2e0, 0x551, 0x1150, /* 4-bit */ + } ; + + /* Table mapping codewords to quantized delta interval steps. */ +-static unsigned int table_step [] = ++static unsigned short table_step [] = + { 0x73F, 0, 0, 0, 0x1829, 0, 0, 0, /* 2-bit */ + 0x3EB, 0, 0xC18, 0, 0x1581, 0, 0x226E, 0, /* 3-bit */ + 0x20C, 0x635, 0xA83, 0xF12, 0x1418, 0x19E3, 0x211A, 0x2BBA, /* 4-bit */ + } ; + + /* Binary search lookup table for quantizing using table_step. */ +-static int table_step_search [] = ++static short table_step_search [] = + { 0, 0x1F6D, 0, -0x1F6D, 0, 0, 0, 0, /* 2-bit */ + 0x1008, 0x1192, 0, -0x219A, 0x1656, -0x1656, 0, 0, /* 3-bit */ + 0x872, 0x1277, -0x8E6, -0x232B, 0xD06, -0x17D7, -0x11D3, 0, /* 4-bit */ +@@ -179,23 +179,23 @@ static sf_count_t nms_adpcm_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) + ** Maps [1,20480] to [1,1024] in an exponential relationship. This is + ** approximately ret = b^exp where b = e^(ln(1024)/ln(20480)) ~= 1.0003385 + */ +-static inline int +-nms_adpcm_antilog (int exp) +-{ int ret ; ++static inline short ++nms_adpcm_antilog (short exp) ++{ int_fast32_t r ; + +- ret = 0x1000 ; +- ret += (((exp & 0x3f) * 0x166b) >> 12) ; +- ret *= table_expn [(exp & 0x7c0) >> 6] ; +- ret >>= (26 - (exp >> 11)) ; ++ r = 0x1000 ; ++ r += (((int_fast32_t) (exp & 0x3f) * 0x166b) >> 12) ; ++ r *= table_expn [(exp & 0x7c0) >> 6] ; ++ r >>= (26 - (exp >> 11)) ; + +- return ret ; ++ return (short) r ; + } /* nms_adpcm_antilog */ + + static void + nms_adpcm_update (struct nms_adpcm_state *s) + { /* Variable names from ITU G.726 spec */ +- int a1ul ; +- int fa1 ; ++ short a1ul, fa1 ; ++ int_fast32_t se ; + int i ; + + /* Decay and Modify the scale factor in the log domain based on the codeword. */ +@@ -222,7 +222,7 @@ nms_adpcm_update (struct nms_adpcm_state *s) + else if (fa1 > 256) + fa1 = 256 ; + +- s->a [0] = (0xff * s->a [0]) >> 8 ; ++ s->a [0] = (s->a [0] * 0xff) >> 8 ; + if (s->p [0] != 0 && s->p [1] != 0 && ((s->p [0] ^ s->p [1]) < 0)) + s->a [0] -= 192 ; + else +@@ -230,7 +230,7 @@ nms_adpcm_update (struct nms_adpcm_state *s) + fa1 = -fa1 ; + } + +- s->a [1] = fa1 + ((0xfe * s->a [1]) >> 8) ; ++ s->a [1] = fa1 + ((s->a [1] * 0xfe) >> 8) ; + if (s->p [0] != 0 && s->p [2] != 0 && ((s->p [0] ^ s->p [2]) < 0)) + s->a [1] -= 128 ; + else +@@ -250,19 +250,18 @@ nms_adpcm_update (struct nms_adpcm_state *s) + s->a [0] = a1ul ; + } ; + +- /* Compute the zero predictor estimate. Rotate past deltas too. */ +- s->s_ez = 0 ; ++ /* Compute the zero predictor estimate and rotate past deltas. */ ++ se = 0 ; + for (i = 5 ; i >= 0 ; i--) +- { s->s_ez += s->d_q [i] * s->b [i] ; ++ { se += (int_fast32_t) s->d_q [i] * s->b [i] ; + s->d_q [i + 1] = s->d_q [i] ; + } ; +- +- /* Compute the signal estimate. */ +- s->s_e = s->a [0] * s->s_r [0] + s->a [1] * s->s_r [1] + s->s_ez ; +- +- /* Return to scale */ +- s->s_ez >>= 14 ; +- s->s_e >>= 14 ; ++ s->s_ez = se >> 14 ; ++ ++ /* Complete the signal estimate. */ ++ se += (int_fast32_t) s->a [0] * s->s_r [0] ; ++ se += (int_fast32_t) s->a [1] * s->s_r [1] ; ++ s->s_e = se >> 14 ; + + /* Rotate members to prepare for next iteration. */ + s->s_r [1] = s->s_r [0] ; +@@ -274,7 +273,7 @@ nms_adpcm_update (struct nms_adpcm_state *s) + static int16_t + nms_adpcm_reconstruct_sample (struct nms_adpcm_state *s, uint8_t I) + { /* Variable names from ITU G.726 spec */ +- int dqx ; ++ int_fast32_t dqx ; + + /* + ** The ordering of the 12-bit right-shift is a precision loss. It agrees +@@ -308,17 +307,17 @@ nms_adpcm_codec_init (struct nms_adpcm_state *s, enum nms_enc_type type) + /* + ** nms_adpcm_encode_sample() + ** +-** Encode a linear 16-bit pcm sample into a 2,3, or 4 bit NMS-ADPCM codeword ++** Encode a linear 16-bit pcm sample into a 2, 3, or 4 bit NMS-ADPCM codeword + ** using and updating the predictor state. + */ + static uint8_t + nms_adpcm_encode_sample (struct nms_adpcm_state *s, int16_t sl) + { /* Variable names from ITU G.726 spec */ +- int d ; ++ int_fast32_t d ; + uint8_t I ; + + /* Down scale the sample from 16 => ~14 bits. */ +- sl = (sl * 0x1fdf) / 0x7fff ; ++ sl = ((int_fast32_t) sl * 0x1fdf) / 0x7fff ; + + /* Compute estimate, and delta from actual value */ + nms_adpcm_update (s) ; +@@ -407,7 +406,7 @@ nms_adpcm_encode_sample (struct nms_adpcm_state *s, int16_t sl) + */ + static int16_t + nms_adpcm_decode_sample (struct nms_adpcm_state *s, uint8_t I) +-{ int sl ; ++{ int_fast32_t sl ; + + nms_adpcm_update (s) ; + sl = nms_adpcm_reconstruct_sample (s, I) ; +@@ -1091,7 +1090,7 @@ nms_adpcm_init (SF_PRIVATE *psf) + else + pnms->blocks_total = psf->datalength / (pnms->shortsperblock * sizeof (short)) ; + +- psf->sf.frames = pnms->blocks_total * NMS_SAMPLES_PER_BLOCK ; ++ psf->sf.frames = (sf_count_t) pnms->blocks_total * NMS_SAMPLES_PER_BLOCK ; + psf->codec_close = nms_adpcm_close ; + psf->seek = nms_adpcm_seek ; + +diff --git a/src/pcm.c b/src/pcm.c +index 3ea0d09..159c7ef 100644 +--- a/src/pcm.c ++++ b/src/pcm.c +@@ -127,7 +127,7 @@ pcm_init (SF_PRIVATE *psf) + return SFE_INTERNAL ; + } ; + +- psf->blockwidth = psf->bytewidth * psf->sf.channels ; ++ psf->blockwidth = (sf_count_t) psf->bytewidth * psf->sf.channels ; + + if ((SF_CODEC (psf->sf.format)) == SF_FORMAT_PCM_S8) + chars = SF_CHARS_SIGNED ; +diff --git a/src/rf64.c b/src/rf64.c +index 0059382..f853b56 100644 +--- a/src/rf64.c ++++ b/src/rf64.c +@@ -242,7 +242,7 @@ rf64_read_header (SF_PRIVATE *psf, int *blockalign, int *framesperblock) + } ; + } ; + +- if (psf->filelength != riff_size + 8) ++ if (psf->filelength - 8 != riff_size) + psf_log_printf (psf, " Riff size : %D (should be %D)\n", riff_size, psf->filelength - 8) ; + else + psf_log_printf (psf, " Riff size : %D\n", riff_size) ; +diff --git a/src/sds.c b/src/sds.c +index 85c8c11..2f14ce2 100644 +--- a/src/sds.c ++++ b/src/sds.c +@@ -454,7 +454,7 @@ sds_2byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds) + + ucptr = psds->read_data + 5 ; + for (k = 0 ; k < 120 ; k += 2) +- { sample = arith_shift_left (ucptr [k], 25) + arith_shift_left (ucptr [k + 1], 18) ; ++ { sample = arith_shift_left (ucptr [k], 25) | arith_shift_left (ucptr [k + 1], 18) ; + psds->read_samples [k / 2] = (int) (sample - 0x80000000) ; + } ; + +@@ -498,7 +498,7 @@ sds_3byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds) + + ucptr = psds->read_data + 5 ; + for (k = 0 ; k < 120 ; k += 3) +- { sample = (((uint32_t) ucptr [k]) << 25) + (ucptr [k + 1] << 18) + (ucptr [k + 2] << 11) ; ++ { sample = (((uint32_t) ucptr [k]) << 25) | (ucptr [k + 1] << 18) | (ucptr [k + 2] << 11) ; + psds->read_samples [k / 3] = (int) (sample - 0x80000000) ; + } ; + +@@ -542,7 +542,7 @@ sds_4byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds) + + ucptr = psds->read_data + 5 ; + for (k = 0 ; k < 120 ; k += 4) +- { sample = (((uint32_t) ucptr [k]) << 25) + (ucptr [k + 1] << 18) + (ucptr [k + 2] << 11) + (ucptr [k + 3] << 4) ; ++ { sample = (((uint32_t) ucptr [k]) << 25) | (ucptr [k + 1] << 18) | (ucptr [k + 2] << 11) | (ucptr [k + 3] << 4) ; + psds->read_samples [k / 4] = (int) (sample - 0x80000000) ; + } ; + +-- +2.25.1 + diff --git a/SPECS/libsndfile/libsndfile.spec b/SPECS/libsndfile/libsndfile.spec index 0a1287f967e..591dfdd4727 100644 --- a/SPECS/libsndfile/libsndfile.spec +++ b/SPECS/libsndfile/libsndfile.spec @@ -1,7 +1,7 @@ Summary: Library for reading and writing sound files Name: libsndfile Version: 1.0.31 -Release: 2%{?dist} +Release: 3%{?dist} License: BSD AND GPLv2+ AND LGPLv2+ AND MIT Vendor: Microsoft Corporation Distribution: Mariner @@ -16,6 +16,7 @@ Patch2: revert.patch # CVE disputed by project's owner, no repro. # See here for more details: https://github.com/libsndfile/libsndfile/issues/398. Patch100: CVE-2018-13419.nopatch +Patch101: CVE-2022-33065.patch BuildRequires: alsa-lib-devel BuildRequires: autogen @@ -139,6 +140,9 @@ LD_LIBRARY_PATH=$PWD/src/.libs make check %{_libdir}/pkgconfig/sndfile.pc %changelog +* Fri Aug 22 2024 Sumedh Sharma - 1.0.31-3 +- Add patch to resolve CVE-2022-33065 + * Fri Apr 22 2022 Olivia Crain - 1.0.31-2 - Remove explicit pkgconfig provides that are now automatically generated by RPM diff --git a/SPECS/libtracecmd/libtracecmd.signatures.json b/SPECS/libtracecmd/libtracecmd.signatures.json new file mode 100644 index 00000000000..aef1a7d69fa --- /dev/null +++ b/SPECS/libtracecmd/libtracecmd.signatures.json @@ -0,0 +1,5 @@ +{ + "Signatures": { + "libtracecmd-1.5.1.tar.gz": "0d444c8c6365ccde46733a7512fb8f6a7744a16b7b73c4b23d8ff041f3321320" + } +} diff --git a/SPECS/libtracecmd/libtracecmd.spec b/SPECS/libtracecmd/libtracecmd.spec new file mode 100644 index 00000000000..2947348999c --- /dev/null +++ b/SPECS/libtracecmd/libtracecmd.spec @@ -0,0 +1,79 @@ +Name: libtracecmd +Version: 1.5.1 +Release: 2%{?dist} +License: LGPL-2.1-only AND LGPL-2.1-or-later AND GPL-2.0-only AND GPL-2.0-or-later +Vendor: Microsoft Corporation +Distribution: Mariner +Summary: A library for reading tracing instances stored in a trace file + +URL: https://git.kernel.org/pub/scm/utils/trace-cmd/trace-cmd.git/ +Source0: https://git.kernel.org/pub/scm/utils/trace-cmd/trace-cmd.git/snapshot/trace-cmd-libtracecmd-%{version}.tar.gz#/%{name}-%{version}.tar.gz + +ExcludeArch: %{ix86} %{arm} + +BuildRequires: make +BuildRequires: gcc +BuildRequires: xmlto +BuildRequires: asciidoc +BuildRequires: mlocate +BuildRequires: graphviz doxygen +BuildRequires: libxml2-devel +BuildRequires: gcc-c++ +BuildRequires: json-c-devel +BuildRequires: libtraceevent-devel >= 1.8.0 +BuildRequires: libtracefs-devel >= 1.8.0 +BuildRequires: chrpath +BuildRequires: libzstd-devel + +%description +A library containing functions for getting information and reading +tracing instances stored in a trace file that can be used without the +trace-cmd application. + +%package -n libtracecmd-devel +Summary: Development files for libtracecmd +Requires: libtracecmd%{_isa} = %{version}-%{release} + +%description -n libtracecmd-devel +Development files of the libtracecmd library + +%prep +%autosetup -n trace-cmd-libtracecmd-%{version} + +%build +# MANPAGE_DOCBOOK_XSL define is hack to avoid using locate +MANPAGE_DOCBOOK_XSL=`rpm -ql docbook-style-xsl | grep manpages/docbook.xsl` +CFLAGS="%{optflags} -D_GNU_SOURCE" LDFLAGS="%{build_ldflags}" BUILD_TYPE=Release \ + make V=9999999999 MANPAGE_DOCBOOK_XSL=$MANPAGE_DOCBOOK_XSL \ + prefix=%{_prefix} libdir=%{_libdir} %{?_smp_mflags}\ + PYTHON_VERS=python3 libs doc + +%install +make libdir=%{_libdir} prefix=%{_prefix} V=1 DESTDIR=%{buildroot}/ CFLAGS="%{optflags} -D_GNU_SOURCE" LDFLAGS="%{build_ldflags} -z muldefs " BUILD_TYPE=Release install_libs install_doc +# Remove trace-cmd man pages and docs, leaving only the libtracecmd ones, as there are no separate makefile target for libtracecmd documents +find %{buildroot}%{_mandir} -iname trace-cmd\* -exec rm -rf {} \; +rm -rf %{buildroot}/%{_docdir}/trace-cmd +chrpath --delete %{buildroot}/%{_libdir}/libtracecmd.so* + +%files +%license COPYING COPYING.LIB +%doc README +%{_libdir}/libtracecmd.so.1 +%{_libdir}/libtracecmd.so.1.5.1 +%{_docdir}/libtracecmd-doc +%{_mandir}/man3/libtracecmd* +%{_mandir}/man3/tracecmd* + +%files -n libtracecmd-devel +%{_libdir}/pkgconfig/libtracecmd.pc +%{_libdir}/libtracecmd.so +%{_includedir}/trace-cmd + +%changelog +* Thu Aug 29 2024 Henry Beberman - 1.5.1-2 +- Backport from Azure Linux 3.0 +- Remove freeglut-devel dependency because we dont ship the gui tool + +* Thu Feb 15 2024 Aadhar Agarwal - 1.5.1-1 +- Initial CBL-Mariner import from Fedora 40 (license: MIT) +- License Verified diff --git a/SPECS/libtraceevent/libtraceevent.signatures.json b/SPECS/libtraceevent/libtraceevent.signatures.json index 9b43b9574dd..70c4b457494 100644 --- a/SPECS/libtraceevent/libtraceevent.signatures.json +++ b/SPECS/libtraceevent/libtraceevent.signatures.json @@ -1,5 +1,5 @@ { - "Signatures": { - "libtraceevent-1.7.2.tar.gz": "a8b4bf8f05c06d1d6405f6d0038467a87e7ab218f0d8b0608d08bca5d1fc112a" - } + "Signatures": { + "libtraceevent-1.8.2.tar.gz": "919f0c024c7b5059eace52d854d4df00ae7e361a4033e1b4d6fe01d97064a1b9" + } } diff --git a/SPECS/libtraceevent/libtraceevent.spec b/SPECS/libtraceevent/libtraceevent.spec index 6b6ac27a674..2a719f7a95b 100644 --- a/SPECS/libtraceevent/libtraceevent.spec +++ b/SPECS/libtraceevent/libtraceevent.spec @@ -4,7 +4,7 @@ Summary: Library to parse raw trace event formats #%%global commitdate 20201009 #%%global shortcommit %%(c=%%{commit}; echo ${c:0:7}) Name: libtraceevent -Version: 1.7.2 +Version: 1.8.2 Release: 1%{?dist} License: MIT Vendor: Microsoft Corporation @@ -62,6 +62,9 @@ rm -rf %{buildroot}/%{_libdir}/libtraceevent.a %{_libdir}/pkgconfig/libtraceevent.pc %changelog +* Thu Aug 29 2024 Henry Beberman - 1.8.2-1 +- Update to 1.8.2 + * Tue Jul 18 2023 Saranya R - 1.7.2-1 - Initial CBL-Mariner import from Fedora 38 (license: MIT). - License verified diff --git a/SPECS/libtracefs/libtracefs.signatures.json b/SPECS/libtracefs/libtracefs.signatures.json new file mode 100644 index 00000000000..d9b8f663a26 --- /dev/null +++ b/SPECS/libtracefs/libtracefs.signatures.json @@ -0,0 +1,5 @@ +{ + "Signatures": { + "libtracefs-1.8.0.tar.gz": "f92475d5c4cb509983697fb359ee615bef4f08ed8bdc9c690f6118ba68886de0" + } +} diff --git a/SPECS/libtracefs/libtracefs.spec b/SPECS/libtracefs/libtracefs.spec new file mode 100644 index 00000000000..af5bdd58d88 --- /dev/null +++ b/SPECS/libtracefs/libtracefs.spec @@ -0,0 +1,72 @@ +# git tag +#%%global commit 4f24f98960c223e56329519bb90a90f0b2ad813f +#%%global commitdate 20201120 +#%%global shortcommit %%(c=%%{commit}; echo ${c:0:7}) + +# LTO causes linking issues randomly like +# lto1: internal compiler error: resolution sub id 0x7136344381f3059f not in object file +# So disabling LTO at this moment. + +%global _lto_cflags %nil + +Name: libtracefs +Version: 1.8.0 +Release: 2%{?dist} +License: LGPL-2.1-or-later AND GPL-2.0-or-later AND GPL-2.0-only +Vendor: Microsoft Corporation +Distribution: Mariner +Summary: Library for access kernel tracefs + +# If upstream does not provide tarballs, to generate: +# git clone git://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git +# cd libtracefs +# git archive --prefix=libtracefs-%%{version}/ -o libtracefs-%%{version}.tar.gz %%{git_commit} +URL: https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/ +Source0: https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/snapshot/libtracefs-%{version}.tar.gz#/%{name}-%{version}.tar.gz +BuildRequires: gcc +BuildRequires: make +BuildRequires: pkgconfig(libtraceevent) >= 1.8.0 + +# The libtracefs is meant to be used by perf, trace-cmd etc. in the future, before it's ready in perf, let's add a conflict +Conflicts: trace-cmd < 2.9.1-6 + +%description +libtracefs is a library for accessing kernel tracefs + +%package devel +Summary: Development headers of %{name} +Requires: %{name}%{_isa} = %{version}-%{release} + +%description devel +Development headers of %{name} + +%prep +%autosetup -p1 + +%build +%set_build_flags +# parallel compiling don't always work +make -O -j1 V=1 VERBOSE=1 prefix=%{_prefix} libdir=%{_libdir} all + +%install +%make_install prefix=%{_prefix} libdir=%{_libdir} +rm -rf %{buildroot}/%{_libdir}/libtracefs.a + +%files +%license LICENSES/LGPL-2.1 +%license LICENSES/GPL-2.0 +%{_libdir}/%{name}.so.1 +%{_libdir}/%{name}.so.1.8.0 + +%files devel +%{_includedir}/tracefs/tracefs.h +%{_libdir}/pkgconfig/%{name}.pc +%{_libdir}/%{name}.so + +%changelog +* Thu Aug 29 2024 Henry Beberman - 1.8.0-2 +- Backport from Azure Linux 3.0 + +* Thu Feb 15 2024 Aadhar Agarwal - 1.8.0-1 +- Initial CBL-Mariner import from Fedora 40 (license: MIT) +- License Verified diff --git a/SPECS/libxml2/CVE-2024-25062.patch b/SPECS/libxml2/CVE-2024-25062.patch new file mode 100755 index 00000000000..88e3e356d25 --- /dev/null +++ b/SPECS/libxml2/CVE-2024-25062.patch @@ -0,0 +1,29 @@ +From 2b0aac140d739905c7848a42efc60bfe783a39b7 Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +Date: Sat, 14 Oct 2023 22:45:54 +0200 +Subject: [PATCH] [CVE-2024-25062] xmlreader: Don't expand XIncludes when + backtracking + +Fixes a use-after-free if XML Reader if used with DTD validation and +XInclude expansion. + +Fixes #604. +--- + xmlreader.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/xmlreader.c b/xmlreader.c +index 979385a13..fefd68e0b 100644 +--- a/xmlreader.c ++++ b/xmlreader.c +@@ -1443,6 +1443,7 @@ node_found: + * Handle XInclude if asked for + */ + if ((reader->xinclude) && (reader->in_xinclude == 0) && ++ (reader->state != XML_TEXTREADER_BACKTRACK) && + (reader->node != NULL) && + (reader->node->type == XML_ELEMENT_NODE) && + (reader->node->ns != NULL) && +-- +GitLab + diff --git a/SPECS/libxml2/libxml2.spec b/SPECS/libxml2/libxml2.spec index 72bd5b3dcfc..c783eab65ed 100644 --- a/SPECS/libxml2/libxml2.spec +++ b/SPECS/libxml2/libxml2.spec @@ -1,7 +1,7 @@ Summary: Libxml2 Name: libxml2 Version: 2.10.4 -Release: 3%{?dist} +Release: 4%{?dist} License: MIT Vendor: Microsoft Corporation Distribution: Mariner @@ -10,6 +10,7 @@ URL: https://gitlab.gnome.org/GNOME/libxml2/-/wikis/home Source0: https://gitlab.gnome.org/GNOME/%{name}/-/archive/v%{version}/%{name}-v%{version}.tar.gz Patch0: CVE-2023-45322.patch Patch1: CVE-2024-34459.patch +Patch2: CVE-2024-25062.patch BuildRequires: python3-devel BuildRequires: python3-xml Provides: %{name}-tools = %{version}-%{release} @@ -80,6 +81,9 @@ find %{buildroot} -type f -name "*.la" -delete -print %{_libdir}/cmake/libxml2/libxml2-config.cmake %changelog +* Tue Sep 17 2024 Sumedh Sharma - 2.10.4-4 +- Add patch to resolve CVE-2024-25062 + * Mon May 20 2024 Sudipta Pandit - 2.10.4-3 - Apply patch for CVE-2024-34459 diff --git a/SPECS/local-path-provisioner/local-path-provisioner.spec b/SPECS/local-path-provisioner/local-path-provisioner.spec index 432993e6a01..3812452bfc7 100644 --- a/SPECS/local-path-provisioner/local-path-provisioner.spec +++ b/SPECS/local-path-provisioner/local-path-provisioner.spec @@ -1,7 +1,7 @@ Summary: Provides a way for the Kubernetes users to utilize the local storage in each node Name: local-path-provisioner Version: 0.0.21 -Release: 17%{?dist} +Release: 18%{?dist} License: ASL 2.0 URL: https://github.com/rancher/local-path-provisioner Group: Applications/Text @@ -34,6 +34,9 @@ install local-path-provisioner %{buildroot}%{_bindir}/local-path-provisioner %{_bindir}/local-path-provisioner %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 0.0.21-18 +- Bump release to rebuild with go 1.22.7 + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 0.0.21-17 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS/mariner-release/mariner-release.spec b/SPECS/mariner-release/mariner-release.spec index 39847ca39fa..ec28b276c7a 100644 --- a/SPECS/mariner-release/mariner-release.spec +++ b/SPECS/mariner-release/mariner-release.spec @@ -1,7 +1,7 @@ Summary: CBL-Mariner release files Name: mariner-release Version: 2.0 -Release: 66%{?dist} +Release: 67%{?dist} License: MIT Vendor: Microsoft Corporation Distribution: Mariner @@ -62,6 +62,9 @@ EOF %config(noreplace) %{_sysconfdir}/issue.net %changelog +* Wed Sep 25 2024 CBL-Mariner Servicing Account - 2.0-67 +- Bump release for October 2024 Update + * Sat Aug 24 2024 Jon Slobodzian - 2.0-66 - Bump release for September 2024 Update diff --git a/SPECS/moby-buildx/CVE-2021-41092.patch b/SPECS/moby-buildx/CVE-2021-41092.patch new file mode 100644 index 00000000000..93131084275 --- /dev/null +++ b/SPECS/moby-buildx/CVE-2021-41092.patch @@ -0,0 +1,64 @@ +From 42d1c02750b3631402da3973e5f36b76c8c934f4 Mon Sep 17 00:00:00 2001 +From: Samuel Karp +Date: Wed, 21 Jul 2021 17:59:42 -0700 +Subject: [PATCH] registry: ensure default auth config has address + +Signed-off-by: Samuel Karp +--- + .../github.com/docker/cli/cli/command/registry.go | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +diff --git a/vendor/github.com/docker/cli/cli/command/registry.go b/vendor/github.com/docker/cli/cli/command/registry.go +index e6311c8..68e3dd3 100644 +--- a/vendor/github.com/docker/cli/cli/command/registry.go ++++ b/vendor/github.com/docker/cli/cli/command/registry.go +@@ -63,17 +63,14 @@ func RegistryAuthenticationPrivilegedFunc(cli Cli, index *registrytypes.IndexInf + indexServer := registry.GetAuthConfigKey(index) + isDefaultRegistry := indexServer == ElectAuthServer(context.Background(), cli) + authConfig, err := GetDefaultAuthConfig(cli, true, indexServer, isDefaultRegistry) +- if authConfig == nil { +- authConfig = &types.AuthConfig{} +- } + if err != nil { + fmt.Fprintf(cli.Err(), "Unable to retrieve stored credentials for %s, error: %s.\n", indexServer, err) + } +- err = ConfigureAuth(cli, "", "", authConfig, isDefaultRegistry) ++ err = ConfigureAuth(cli, "", "", &authConfig, isDefaultRegistry) + if err != nil { + return "", err + } +- return EncodeAuthToBase64(*authConfig) ++ return EncodeAuthToBase64(authConfig) + } + } + +@@ -92,7 +89,7 @@ func ResolveAuthConfig(ctx context.Context, cli Cli, index *registrytypes.IndexI + + // GetDefaultAuthConfig gets the default auth config given a serverAddress + // If credentials for given serverAddress exists in the credential store, the configuration will be populated with values in it +-func GetDefaultAuthConfig(cli Cli, checkCredStore bool, serverAddress string, isDefaultRegistry bool) (*types.AuthConfig, error) { ++func GetDefaultAuthConfig(cli Cli, checkCredStore bool, serverAddress string, isDefaultRegistry bool) (types.AuthConfig, error) { + if !isDefaultRegistry { + serverAddress = registry.ConvertToHostname(serverAddress) + } +@@ -101,13 +98,15 @@ func GetDefaultAuthConfig(cli Cli, checkCredStore bool, serverAddress string, is + if checkCredStore { + authconfig, err = cli.ConfigFile().GetAuthConfig(serverAddress) + if err != nil { +- return nil, err ++ return types.AuthConfig{ ++ ServerAddress: serverAddress, ++ }, err + } + } + authconfig.ServerAddress = serverAddress + authconfig.IdentityToken = "" + res := types.AuthConfig(authconfig) +- return &res, nil ++ return res, nil + } + + // ConfigureAuth handles prompting of user's username and password if needed +-- +2.33.8 + diff --git a/SPECS/moby-buildx/CVE-2022-41717.patch b/SPECS/moby-buildx/CVE-2022-41717.patch new file mode 100644 index 00000000000..96165357773 --- /dev/null +++ b/SPECS/moby-buildx/CVE-2022-41717.patch @@ -0,0 +1,75 @@ +From 1e63c2f08a10a150fa02c50ece89b340ae64efe4 Mon Sep 17 00:00:00 2001 +From: Damien Neil +Date: Tue, 6 Dec 2022 11:57:53 -0800 +Subject: [PATCH] http2: limit canonical header cache by bytes, not entries + +The canonical header cache is a per-connection cache mapping header +keys to their canonicalized form. (For example, "foo-bar" => "Foo-Bar"). +We limit the number of entries in the cache to prevent an attacker +from consuming unbounded amounts of memory by sending many unique +keys, but a small number of very large keys can still consume an +unreasonable amount of memory. + +Track the amount of memory consumed by the cache and limit it based +on memory rather than number of entries. + +Thanks to Josselin Costanzi for reporting this issue. + +For golang/go#56350 + +Change-Id: I41db4c9823ed5bf371a9881accddff1268489b16 +Reviewed-on: https://go-review.googlesource.com/c/net/+/455635 +Reviewed-by: Jenny Rakoczy +Run-TryBot: Damien Neil +TryBot-Result: Gopher Robot +--- + vendor/golang.org/x/net/http2/server.go | 18 +++++++++++------- + 1 file changed, 11 insertions(+), 7 deletions(-) + +diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go +index 52afaa6..f26f665 100644 +--- a/vendor/golang.org/x/net/http2/server.go ++++ b/vendor/golang.org/x/net/http2/server.go +@@ -525,6 +525,7 @@ type serverConn struct { + headerTableSize uint32 + peerMaxHeaderListSize uint32 // zero means unknown (default) + canonHeader map[string]string // http2-lower-case -> Go-Canonical-Case ++ canonHeaderKeysSize int // canonHeader keys size in bytes + writingFrame bool // started writing a frame (on serve goroutine or separate) + writingFrameAsync bool // started a frame on its own goroutine but haven't heard back on wroteFrameCh + needsFrameFlush bool // last frame write wasn't a flush +@@ -701,6 +702,13 @@ func (sc *serverConn) condlogf(err error, format string, args ...interface{}) { + } + } + ++// maxCachedCanonicalHeadersKeysSize is an arbitrarily-chosen limit on the size ++// of the entries in the canonHeader cache. ++// This should be larger than the size of unique, uncommon header keys likely to ++// be sent by the peer, while not so high as to permit unreasonable memory usage ++// if the peer sends an unbounded number of unique header keys. ++const maxCachedCanonicalHeadersKeysSize = 2048 ++ + func (sc *serverConn) canonicalHeader(v string) string { + sc.serveG.check() + buildCommonHeaderMapsOnce() +@@ -716,14 +724,10 @@ func (sc *serverConn) canonicalHeader(v string) string { + sc.canonHeader = make(map[string]string) + } + cv = http.CanonicalHeaderKey(v) +- // maxCachedCanonicalHeaders is an arbitrarily-chosen limit on the number of +- // entries in the canonHeader cache. This should be larger than the number +- // of unique, uncommon header keys likely to be sent by the peer, while not +- // so high as to permit unreaasonable memory usage if the peer sends an unbounded +- // number of unique header keys. +- const maxCachedCanonicalHeaders = 32 +- if len(sc.canonHeader) < maxCachedCanonicalHeaders { ++ size := 100 + len(v)*2 // 100 bytes of map overhead + key + value ++ if sc.canonHeaderKeysSize+size <= maxCachedCanonicalHeadersKeysSize { + sc.canonHeader[v] = cv ++ sc.canonHeaderKeysSize += size + } + return cv + } +-- +2.33.8 + diff --git a/SPECS/moby-buildx/CVE-2023-45288.patch b/SPECS/moby-buildx/CVE-2023-45288.patch new file mode 100644 index 00000000000..5c5891aaf78 --- /dev/null +++ b/SPECS/moby-buildx/CVE-2023-45288.patch @@ -0,0 +1,90 @@ +Parent: ebc8168a (all: fix some typos) +Author: Damien Neil +AuthorDate: 2024-01-10 13:41:39 -0800 +Commit: Gopher Robot +CommitDate: 2024-04-03 16:01:29 +0000 + +http2: close connections when receiving too many headers + +Maintaining HPACK state requires that we parse and process +all HEADERS and CONTINUATION frames on a connection. +When a request's headers exceed MaxHeaderBytes, we don't +allocate memory to store the excess headers but we do +parse them. This permits an attacker to cause an HTTP/2 +endpoint to read arbitrary amounts of data, all associated +with a request which is going to be rejected. + +Set a limit on the amount of excess header frames we +will process before closing a connection. + +Thanks to Bartek Nowotarski for reporting this issue. + +Fixes CVE-2023-45288 +Fixes golang/go#65051 + +Change-Id: I15df097268df13bb5a9e9d3a5c04a8a141d850f6 +Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/2130527 +Reviewed-by: Roland Shoemaker +Reviewed-by: Tatiana Bradley +Reviewed-on: https://go-review.googlesource.com/c/net/+/576155 +Reviewed-by: Dmitri Shuralyov +Auto-Submit: Dmitri Shuralyov +Reviewed-by: Than McIntosh +LUCI-TryBot-Result: Go LUCI + +--- + vendor/golang.org/x/net/http2/frame.go | 31 ++++++++++++++++++++++++++ + 1 file changed, 31 insertions(+) + +diff --git a/vendor/golang.org/x/net/http2/frame.go b/vendor/golang.org/x/net/http2/frame.go +index 514c126..37f3e0e 100644 +--- a/vendor/golang.org/x/net/http2/frame.go ++++ b/vendor/golang.org/x/net/http2/frame.go +@@ -1521,6 +1521,7 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) { + if size > remainSize { + hdec.SetEmitEnabled(false) + mh.Truncated = true ++ remainSize = 0 + return + } + remainSize -= size +@@ -1533,6 +1534,36 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) { + var hc headersOrContinuation = hf + for { + frag := hc.HeaderBlockFragment() ++ ++ // Avoid parsing large amounts of headers that we will then discard. ++ // If the sender exceeds the max header list size by too much, ++ // skip parsing the fragment and close the connection. ++ // ++ // "Too much" is either any CONTINUATION frame after we've already ++ // exceeded the max header list size (in which case remainSize is 0), ++ // or a frame whose encoded size is more than twice the remaining ++ // header list bytes we're willing to accept. ++ if int64(len(frag)) > int64(2*remainSize) { ++ if VerboseLogs { ++ log.Printf("http2: header list too large") ++ } ++ // It would be nice to send a RST_STREAM before sending the GOAWAY, ++ // but the struture of the server's frame writer makes this difficult. ++ return nil, ConnectionError(ErrCodeProtocol) ++ } ++ ++ // Also close the connection after any CONTINUATION frame following an ++ // invalid header, since we stop tracking the size of the headers after ++ // an invalid one. ++ if invalid != nil { ++ if VerboseLogs { ++ log.Printf("http2: invalid header: %v", invalid) ++ } ++ // It would be nice to send a RST_STREAM before sending the GOAWAY, ++ // but the struture of the server's frame writer makes this difficult. ++ return nil, ConnectionError(ErrCodeProtocol) ++ } ++ + if _, err := hdec.Write(frag); err != nil { + return nil, ConnectionError(ErrCodeCompression) + } +-- +2.33.8 + diff --git a/SPECS/moby-buildx/CVE-2023-48795.patch b/SPECS/moby-buildx/CVE-2023-48795.patch new file mode 100644 index 00000000000..9ebe599a80c --- /dev/null +++ b/SPECS/moby-buildx/CVE-2023-48795.patch @@ -0,0 +1,259 @@ +From 9d2ee975ef9fe627bf0a6f01c1f69e8ef1d4f05d Mon Sep 17 00:00:00 2001 +From: Roland Shoemaker +Date: Mon, 20 Nov 2023 12:06:18 -0800 +Subject: [PATCH] ssh: implement strict KEX protocol changes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Implement the "strict KEX" protocol changes, as described in section +1.9 of the OpenSSH PROTOCOL file (as of OpenSSH version 9.6/9.6p1). + +Namely this makes the following changes: + * Both the server and the client add an additional algorithm to the + initial KEXINIT message, indicating support for the strict KEX mode. + * When one side of the connection sees the strict KEX extension + algorithm, the strict KEX mode is enabled for messages originating + from the other side of the connection. If the sequence number for + the side which requested the extension is not 1 (indicating that it + has already received non-KEXINIT packets), the connection is + terminated. + * When strict kex mode is enabled, unexpected messages during the + handshake are considered fatal. Additionally when a key change + occurs (on the receipt of the NEWKEYS message) the message sequence + numbers are reset. + +Thanks to Fabian Bäumer, Marcus Brinkmann, and Jörg Schwenk from Ruhr +University Bochum for reporting this issue. + +Fixes CVE-2023-48795 +Fixes golang/go#64784 + +Change-Id: I96b53afd2bd2fb94d2b6f2a46a5dacf325357604 +Reviewed-on: https://go-review.googlesource.com/c/crypto/+/550715 +Reviewed-by: Nicola Murino +Reviewed-by: Tatiana Bradley +TryBot-Result: Gopher Robot +Run-TryBot: Roland Shoemaker +Reviewed-by: Damien Neil +LUCI-TryBot-Result: Go LUCI +--- + vendor/golang.org/x/crypto/ssh/handshake.go | 55 ++++++++++++++++++++- + vendor/golang.org/x/crypto/ssh/transport.go | 32 ++++++++++-- + 2 files changed, 80 insertions(+), 7 deletions(-) + +diff --git a/vendor/golang.org/x/crypto/ssh/handshake.go b/vendor/golang.org/x/crypto/ssh/handshake.go +index 2b10b05..a813425 100644 +--- a/vendor/golang.org/x/crypto/ssh/handshake.go ++++ b/vendor/golang.org/x/crypto/ssh/handshake.go +@@ -34,6 +34,16 @@ type keyingTransport interface { + // direction will be effected if a msgNewKeys message is sent + // or received. + prepareKeyChange(*algorithms, *kexResult) error ++ ++ // setStrictMode sets the strict KEX mode, notably triggering ++ // sequence number resets on sending or receiving msgNewKeys. ++ // If the sequence number is already > 1 when setStrictMode ++ // is called, an error is returned. ++ setStrictMode() error ++ ++ // setInitialKEXDone indicates to the transport that the initial key exchange ++ // was completed ++ setInitialKEXDone() + } + + // handshakeTransport implements rekeying on top of a keyingTransport +@@ -94,6 +104,10 @@ type handshakeTransport struct { + + // The session ID or nil if first kex did not complete yet. + sessionID []byte ++ ++ // strictMode indicates if the other side of the handshake indicated ++ // that we should be following the strict KEX protocol restrictions. ++ strictMode bool + } + + type pendingKex struct { +@@ -201,7 +215,10 @@ func (t *handshakeTransport) readLoop() { + close(t.incoming) + break + } +- if p[0] == msgIgnore || p[0] == msgDebug { ++ // If this is the first kex, and strict KEX mode is enabled, ++ // we don't ignore any messages, as they may be used to manipulate ++ // the packet sequence numbers. ++ if !(t.sessionID == nil && t.strictMode) && (p[0] == msgIgnore || p[0] == msgDebug) { + continue + } + t.incoming <- p +@@ -432,6 +449,11 @@ func (t *handshakeTransport) readOnePacket(first bool) ([]byte, error) { + return successPacket, nil + } + ++const ( ++ kexStrictClient = "kex-strict-c-v00@openssh.com" ++ kexStrictServer = "kex-strict-s-v00@openssh.com" ++) ++ + // sendKexInit sends a key change message. + func (t *handshakeTransport) sendKexInit() error { + t.mu.Lock() +@@ -445,7 +467,6 @@ func (t *handshakeTransport) sendKexInit() error { + } + + msg := &kexInitMsg{ +- KexAlgos: t.config.KeyExchanges, + CiphersClientServer: t.config.Ciphers, + CiphersServerClient: t.config.Ciphers, + MACsClientServer: t.config.MACs, +@@ -455,13 +476,30 @@ func (t *handshakeTransport) sendKexInit() error { + } + io.ReadFull(rand.Reader, msg.Cookie[:]) + ++ // We mutate the KexAlgos slice, in order to add the kex-strict extension algorithm, ++ // and possibly to add the ext-info extension algorithm. Since the slice may be the ++ // user owned KeyExchanges, we create our own slice in order to avoid using user ++ // owned memory by mistake. ++ msg.KexAlgos = make([]string, 0, len(t.config.KeyExchanges)+2) // room for kex-strict and ext-info ++ msg.KexAlgos = append(msg.KexAlgos, t.config.KeyExchanges...) ++ + if len(t.hostKeys) > 0 { + for _, k := range t.hostKeys { + msg.ServerHostKeyAlgos = append( + msg.ServerHostKeyAlgos, k.PublicKey().Type()) + } ++ ++ if t.sessionID == nil { ++ msg.KexAlgos = append(msg.KexAlgos, kexStrictServer) ++ } + } else { + msg.ServerHostKeyAlgos = t.hostKeyAlgorithms ++ // We also send the strict KEX mode extension algorithm, in order to opt ++ // into the strict KEX mode. ++ if t.sessionID == nil { ++ msg.KexAlgos = append(msg.KexAlgos, kexStrictClient) ++ } ++ + } + packet := Marshal(msg) + +@@ -557,6 +595,13 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error { + return err + } + ++ if t.sessionID == nil && ((isClient && contains(serverInit.KexAlgos, kexStrictServer)) || (!isClient && contains(clientInit.KexAlgos, kexStrictClient))) { ++ t.strictMode = true ++ if err := t.conn.setStrictMode(); err != nil { ++ return err ++ } ++ } ++ + // We don't send FirstKexFollows, but we handle receiving it. + // + // RFC 4253 section 7 defines the kex and the agreement method for +@@ -608,6 +653,12 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error { + return unexpectedMessageError(msgNewKeys, packet[0]) + } + ++ if t.sessionID == nil { ++ // Indicates to the transport that the first key exchange is completed ++ // after receiving SSH_MSG_NEWKEYS. ++ t.conn.setInitialKEXDone() ++ } ++ + return nil + } + +diff --git a/vendor/golang.org/x/crypto/ssh/transport.go b/vendor/golang.org/x/crypto/ssh/transport.go +index 49ddc2e..379e4a8 100644 +--- a/vendor/golang.org/x/crypto/ssh/transport.go ++++ b/vendor/golang.org/x/crypto/ssh/transport.go +@@ -48,6 +48,9 @@ type transport struct { + rand io.Reader + isClient bool + io.Closer ++ ++ strictMode bool ++ initialKEXDone bool + } + + // packetCipher represents a combination of SSH encryption/MAC +@@ -73,6 +76,18 @@ type connectionState struct { + pendingKeyChange chan packetCipher + } + ++func (t *transport) setStrictMode() error { ++ if t.reader.seqNum != 1 { ++ return errors.New("ssh: sequence number != 1 when strict KEX mode requested") ++ } ++ t.strictMode = true ++ return nil ++} ++ ++func (t *transport) setInitialKEXDone() { ++ t.initialKEXDone = true ++} ++ + // prepareKeyChange sets up key material for a keychange. The key changes in + // both directions are triggered by reading and writing a msgNewKey packet + // respectively. +@@ -111,11 +126,12 @@ func (t *transport) printPacket(p []byte, write bool) { + // Read and decrypt next packet. + func (t *transport) readPacket() (p []byte, err error) { + for { +- p, err = t.reader.readPacket(t.bufReader) ++ p, err = t.reader.readPacket(t.bufReader, t.strictMode) + if err != nil { + break + } +- if len(p) == 0 || (p[0] != msgIgnore && p[0] != msgDebug) { ++ // in strict mode we pass through DEBUG and IGNORE packets only during the initial KEX ++ if len(p) == 0 || (t.strictMode && !t.initialKEXDone) || (p[0] != msgIgnore && p[0] != msgDebug) { + break + } + } +@@ -126,7 +142,7 @@ func (t *transport) readPacket() (p []byte, err error) { + return p, err + } + +-func (s *connectionState) readPacket(r *bufio.Reader) ([]byte, error) { ++func (s *connectionState) readPacket(r *bufio.Reader, strictMode bool) ([]byte, error) { + packet, err := s.packetCipher.readCipherPacket(s.seqNum, r) + s.seqNum++ + if err == nil && len(packet) == 0 { +@@ -139,6 +155,9 @@ func (s *connectionState) readPacket(r *bufio.Reader) ([]byte, error) { + select { + case cipher := <-s.pendingKeyChange: + s.packetCipher = cipher ++ if strictMode { ++ s.seqNum = 0 ++ } + default: + return nil, errors.New("ssh: got bogus newkeys message") + } +@@ -169,10 +188,10 @@ func (t *transport) writePacket(packet []byte) error { + if debugTransport { + t.printPacket(packet, true) + } +- return t.writer.writePacket(t.bufWriter, t.rand, packet) ++ return t.writer.writePacket(t.bufWriter, t.rand, packet, t.strictMode) + } + +-func (s *connectionState) writePacket(w *bufio.Writer, rand io.Reader, packet []byte) error { ++func (s *connectionState) writePacket(w *bufio.Writer, rand io.Reader, packet []byte, strictMode bool) error { + changeKeys := len(packet) > 0 && packet[0] == msgNewKeys + + err := s.packetCipher.writeCipherPacket(s.seqNum, w, rand, packet) +@@ -187,6 +206,9 @@ func (s *connectionState) writePacket(w *bufio.Writer, rand io.Reader, packet [] + select { + case cipher := <-s.pendingKeyChange: + s.packetCipher = cipher ++ if strictMode { ++ s.seqNum = 0 ++ } + default: + panic("ssh: no key material for msgNewKeys") + } +-- +2.33.8 + diff --git a/SPECS/moby-buildx/moby-buildx.spec b/SPECS/moby-buildx/moby-buildx.spec index c4d485816aa..c0625052a2b 100644 --- a/SPECS/moby-buildx/moby-buildx.spec +++ b/SPECS/moby-buildx/moby-buildx.spec @@ -5,7 +5,7 @@ Summary: A Docker CLI plugin for extended build capabilities with BuildKi Name: moby-%{upstream_name} # update "commit_hash" above when upgrading version Version: 0.7.1 -Release: 21%{?dist} +Release: 23%{?dist} License: ASL 2.0 Group: Tools/Container Vendor: Microsoft Corporation @@ -19,6 +19,10 @@ Patch2: CVE-2021-44716.patch Patch3: CVE-2021-43565.patch Patch4: CVE-2022-28948.patch Patch5: CVE-2022-41723.patch +Patch6: CVE-2021-41092.patch +Patch7: CVE-2022-41717.patch +Patch8: CVE-2023-45288.patch +Patch9: CVE-2023-48795.patch BuildRequires: bash BuildRequires: golang @@ -49,6 +53,12 @@ cp -aT buildx "%{buildroot}/%{_libexecdir}/docker/cli-plugins/docker-buildx" %{_libexecdir}/docker/cli-plugins/docker-buildx %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 0.7.1-23 +- Bump release to rebuild with go 1.22.7 + +* Thu Sep 05 2024 Bala - 0.7.1-21 +- Patch CVE-2021-41092, CVE-2022-41717, CVE-2023-45288, CVE-2023-48795 + * Wed Jul 17 2024 Muhammad Falak R Wani - 0.7.1-21 - Drop requirement on a specific version of golang diff --git a/SPECS/moby-cli/moby-cli.spec b/SPECS/moby-cli/moby-cli.spec index 6c9de9ca5c6..907a6865021 100644 --- a/SPECS/moby-cli/moby-cli.spec +++ b/SPECS/moby-cli/moby-cli.spec @@ -3,7 +3,7 @@ Summary: The open-source application container engine client. Name: moby-cli Version: 24.0.9 -Release: 3%{?dist} +Release: 4%{?dist} License: ASL 2.0 Vendor: Microsoft Corporation Distribution: Azure Linux @@ -78,6 +78,9 @@ install -p -m 644 contrib/completion/fish/docker.fish %{buildroot}%{_datadir}/fi %{_datadir}/fish/vendor_completions.d/docker.fish %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 24.0.9-4 +- Bump release to rebuild with go 1.22.7 + * Thu Aug 22 2024 Sumedh Sharma - 24.0.9-3 - Add patch to resolve CVE-2023-45288 diff --git a/SPECS/moby-compose/moby-compose.spec b/SPECS/moby-compose/moby-compose.spec index f4c35b38708..2189e51a0f3 100644 --- a/SPECS/moby-compose/moby-compose.spec +++ b/SPECS/moby-compose/moby-compose.spec @@ -1,7 +1,7 @@ Summary: Define and run multi-container applications with Docker Name: moby-compose Version: 2.17.3 -Release: 6%{?dist} +Release: 7%{?dist} License: ASL 2.0 Vendor: Microsoft Corporation Distribution: Mariner @@ -72,6 +72,9 @@ install -D -m0755 bin/build/docker-compose %{buildroot}/%{_libexecdir}/docker/cl %{_libexecdir}/docker/cli-plugins/docker-compose %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 2.17.3-7 +- Bump release to rebuild with go 1.22.7 + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 2.17.3-6 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS/moby-containerd-cc/moby-containerd-cc.spec b/SPECS/moby-containerd-cc/moby-containerd-cc.spec index 5614c14ff83..e131c33b3e0 100644 --- a/SPECS/moby-containerd-cc/moby-containerd-cc.spec +++ b/SPECS/moby-containerd-cc/moby-containerd-cc.spec @@ -6,7 +6,7 @@ Summary: Industry-standard container runtime for confidential containers Name: moby-%{upstream_name} Version: 1.7.7 -Release: 6%{?dist} +Release: 7%{?dist} License: ASL 2.0 Group: Tools/Container URL: https://www.containerd.io @@ -80,6 +80,9 @@ fi %config(noreplace) %{_sysconfdir}/containerd/config.toml %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 1.7.7-7 +- Bump release to rebuild with go 1.22.7 + * Wed Jul 17 2024 Muhammad Falak R Wani - 1.7.7-6 - Drop requirement on a specific version of golang diff --git a/SPECS/moby-containerd/moby-containerd.spec b/SPECS/moby-containerd/moby-containerd.spec index 6296148f747..3f9961e5159 100644 --- a/SPECS/moby-containerd/moby-containerd.spec +++ b/SPECS/moby-containerd/moby-containerd.spec @@ -5,7 +5,7 @@ Summary: Industry-standard container runtime Name: moby-%{upstream_name} Version: 1.6.26 -Release: 6%{?dist} +Release: 7%{?dist} License: ASL 2.0 Group: Tools/Container URL: https://www.containerd.io @@ -92,6 +92,9 @@ fi %dir /opt/containerd/lib %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 1.6.26-7 +- Bump release to rebuild with go 1.22.7 + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 1.6.26-6 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS/moby-engine/CVE-2024-29018.patch b/SPECS/moby-engine/CVE-2024-29018.patch new file mode 100644 index 00000000000..8737eaa9eaf --- /dev/null +++ b/SPECS/moby-engine/CVE-2024-29018.patch @@ -0,0 +1,131 @@ +From cee35111232493a088715d1b5179d2df38db0e86 Mon Sep 17 00:00:00 2001 +From: Albin Kerouanton +Date: Tue, 10 Oct 2023 01:13:25 +0200 +Subject: [PATCH] libnet: Don't forward to upstream resolvers on internal nw + +Following are the details of upstream patch +https://patch-diff.githubusercontent.com/raw/moby/moby/pull/46609 + +Commit cbc2a71c2 makes `connect` syscall fail fast when a container is +only attached to an internal network. Thanks to that, if such a +container tries to resolve an "external" doamin, the embedded resolver +returns an error immediately instead of waiting for a timeout. + +This commit makes sure the embedded resolver doesn't even try to forward +to upstream servers. + +Signed-off-by: Albin Kerouanton +--- + libnetwork/endpoint.go | 9 ++++++++- + libnetwork/resolver.go | 19 +++++++++++++++---- + libnetwork/sandbox_dns_unix.go | 2 +- + 3 files changed, 24 insertions(+), 6 deletions(-) + +diff --git a/libnetwork/endpoint.go b/libnetwork/endpoint.go +index b9903bb..45933a3 100644 +--- a/libnetwork/endpoint.go ++++ b/libnetwork/endpoint.go +@@ -520,7 +520,11 @@ func (ep *Endpoint) sbJoin(sb *Sandbox, options ...EndpointOption) (err error) { + return sb.setupDefaultGW() + } + +- moveExtConn := sb.getGatewayEndpoint() != extEp ++ currentExtEp := sb.getGatewayEndpoint() ++ // Enable upstream forwarding if the sandbox gained external connectivity. ++ sb.resolver.SetForwardingPolicy(currentExtEp != nil) ++ ++ moveExtConn := currentExtEp != extEp + + if moveExtConn { + if extEp != nil { +@@ -751,6 +755,9 @@ func (ep *Endpoint) sbLeave(sb *Sandbox, force bool, options ...EndpointOption) + + // New endpoint providing external connectivity for the sandbox + extEp = sb.getGatewayEndpoint() ++ // Disable upstream forwarding if the sandbox lost external connectivity. ++ sb.resolver.SetForwardingPolicy(extEp != nil) ++ + if moveExtConn && extEp != nil { + logrus.Debugf("Programming external connectivity on endpoint %s (%s)", extEp.Name(), extEp.ID()) + extN, err := extEp.getNetworkFromStore() +diff --git a/libnetwork/resolver.go b/libnetwork/resolver.go +index ab19b7b..b8e1698 100644 +--- a/libnetwork/resolver.go ++++ b/libnetwork/resolver.go +@@ -7,6 +7,7 @@ import ( + "net" + "strings" + "sync" ++ "sync/atomic" + "time" + + "github.com/docker/docker/libnetwork/types" +@@ -69,7 +70,7 @@ type Resolver struct { + tcpListen *net.TCPListener + err error + listenAddress string +- proxyDNS bool ++ proxyDNS atomic.Bool + startCh chan struct{} + logger *logrus.Logger + +@@ -79,15 +80,17 @@ type Resolver struct { + + // NewResolver creates a new instance of the Resolver + func NewResolver(address string, proxyDNS bool, backend DNSBackend) *Resolver { +- return &Resolver{ ++ r := &Resolver{ + backend: backend, +- proxyDNS: proxyDNS, + listenAddress: address, + err: fmt.Errorf("setup not done yet"), + startCh: make(chan struct{}, 1), + fwdSem: semaphore.NewWeighted(maxConcurrent), + logInverval: rate.Sometimes{Interval: logInterval}, + } ++ r.proxyDNS.Store(proxyDNS) ++ ++ return r + } + + func (r *Resolver) log() *logrus.Logger { +@@ -192,6 +195,14 @@ func (r *Resolver) SetExtServers(extDNS []extDNSEntry) { + } + } + ++// SetForwardingPolicy re-configures the embedded DNS resolver to either enable or disable forwarding DNS queries to ++// external servers. ++func (r *Resolver) SetForwardingPolicy(policy bool) { ++ if r != nil { ++ r.proxyDNS.Store(policy) ++ } ++} ++ + // NameServer returns the IP of the DNS resolver for the containers. + func (r *Resolver) NameServer() string { + return r.listenAddress +@@ -407,7 +418,7 @@ func (r *Resolver) serveDNS(w dns.ResponseWriter, query *dns.Msg) { + return + } + +- if r.proxyDNS { ++ if r.proxyDNS.Load() { + // If the user sets ndots > 0 explicitly and the query is + // in the root domain don't forward it out. We will return + // failure and let the client retry with the search domain +diff --git a/libnetwork/sandbox_dns_unix.go b/libnetwork/sandbox_dns_unix.go +index 2218c69..7d46ca6 100644 +--- a/libnetwork/sandbox_dns_unix.go ++++ b/libnetwork/sandbox_dns_unix.go +@@ -28,7 +28,7 @@ const ( + func (sb *Sandbox) startResolver(restore bool) { + sb.resolverOnce.Do(func() { + var err error +- sb.resolver = NewResolver(resolverIPSandbox, true, sb) ++ sb.resolver = NewResolver(resolverIPSandbox, sb.getGatewayEndpoint() != nil, sb) + defer func() { + if err != nil { + sb.resolver = nil +-- +2.34.1 + diff --git a/SPECS/moby-engine/moby-engine.spec b/SPECS/moby-engine/moby-engine.spec index 68e4eb4aa01..d674cab505b 100644 --- a/SPECS/moby-engine/moby-engine.spec +++ b/SPECS/moby-engine/moby-engine.spec @@ -3,7 +3,7 @@ Summary: The open-source application container engine Name: moby-engine Version: 24.0.9 -Release: 8%{?dist} +Release: 10%{?dist} License: ASL 2.0 Group: Tools/Container URL: https://mobyproject.org @@ -23,6 +23,7 @@ Patch3: CVE-2023-45288.patch Patch4: CVE-2023-44487.patch Patch5: enable-docker-proxy-libexec-search.patch Patch6: CVE-2024-41110.patch +Patch7: CVE-2024-29018.patch %{?systemd_requires} @@ -123,6 +124,12 @@ fi %{_unitdir}/* %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 24.0.9-10 +- Bump release to rebuild with go 1.22.7 + +* Mon Aug 19 2024 Suresh Thelkar - 24.0.9-9 +- Patch CVE-2024-29018 + * Mon Aug 05 2024 Muhammad Falak R Wani - 24.0.9-8 - Drop requirement on a specific version of golang diff --git a/SPECS/moby-runc/moby-runc.spec b/SPECS/moby-runc/moby-runc.spec index 7e0b63ecf9b..487328c3274 100644 --- a/SPECS/moby-runc/moby-runc.spec +++ b/SPECS/moby-runc/moby-runc.spec @@ -5,7 +5,7 @@ Summary: CLI tool for spawning and running containers per OCI spec. Name: moby-%{upstream_name} # update "commit_hash" above when upgrading version Version: 1.1.9 -Release: 6%{?dist} +Release: 7%{?dist} License: ASL 2.0 URL: https://github.com/opencontainers/runc Group: Virtualization/Libraries @@ -58,6 +58,9 @@ make install-man DESTDIR="%{buildroot}" PREFIX="%{_prefix}" %{_mandir}/* %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 1.1.9-7 +- Bump release to rebuild with go 1.22.7 + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 1.1.9-6 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS/msft-golang/msft-golang.signatures.json b/SPECS/msft-golang/msft-golang.signatures.json index f493800314a..dcd94f32e1e 100644 --- a/SPECS/msft-golang/msft-golang.signatures.json +++ b/SPECS/msft-golang/msft-golang.signatures.json @@ -2,7 +2,7 @@ "Signatures": { "go.20230802.5.src.tar.gz": "56b9e0e0c3c13ca95d5efa6de4e7d49a9d190eca77919beff99d33cd3fa74e95", "go.20240206.2.src.tar.gz": "7982e0011aa9ab95fd0530404060410af4ba57326d26818690f334fdcb6451cd", - "go1.22.5-20240702.3.src.tar.gz": "c0247d253ef882d00536c289af6f1329430870d1ae8b05b3288c536974644e24", + "go1.22.7-20240905.3.src.tar.gz": "4c2601d9fe6b4692b6bb4487751dec149c30bd76ad9383331a84971a66bdd0bc", "go1.4-bootstrap-20171003.tar.gz": "f4ff5b5eb3a3cae1c993723f3eab519c5bae18866b5e5f96fe1102f0cb5c3e52" } } \ No newline at end of file diff --git a/SPECS/msft-golang/msft-golang.spec b/SPECS/msft-golang/msft-golang.spec index cf0cf874e14..1c1058198b5 100644 --- a/SPECS/msft-golang/msft-golang.spec +++ b/SPECS/msft-golang/msft-golang.spec @@ -1,6 +1,6 @@ %global goroot %{_libdir}/golang %global gopath %{_datadir}/gocode -%global ms_go_filename go1.22.5-20240702.3.src.tar.gz +%global ms_go_filename go1.22.7-20240905.3.src.tar.gz %global ms_go_revision 1 %ifarch aarch64 %global gohostarch arm64 @@ -14,7 +14,7 @@ %define __find_requires %{nil} Summary: Go Name: msft-golang -Version: 1.22.5 +Version: 1.22.7 Release: 1%{?dist} License: BSD Vendor: Microsoft Corporation @@ -153,6 +153,9 @@ fi %{_bindir}/* %changelog +* Mon Sep 09 2024 Henry Beberman - 1.22.7-1 +- Bump version to 1.22.7 to address CVE-2024-34158, CVE-2024-34156, CVE-2024-34155 + * Thu Jul 04 2024 Muhammad Falak - 1.22.5-1 - Bump version to 1.22.4 diff --git a/SPECS/multus/CVE-2023-3978.patch b/SPECS/multus/CVE-2023-3978.patch new file mode 100755 index 00000000000..9b04a4f1b00 --- /dev/null +++ b/SPECS/multus/CVE-2023-3978.patch @@ -0,0 +1,78 @@ +From 8ffa475fbdb33da97e8bf79cc5791ee8751fca5e Mon Sep 17 00:00:00 2001 +From: Roland Shoemaker +Date: Thu, 06 Jul 2023 10:25:47 -0700 +Subject: [PATCH] html: only render content literally in the HTML namespace + +Per the WHATWG HTML specification, section 13.3, only append the literal +content of a text node if we are in the HTML namespace. + +Thanks to Mohammad Thoriq Aziz for reporting this issue. + +Fixes golang/go#61615 +Fixes CVE-2023-3978 + +Change-Id: I332152904d4e7646bd2441602bcbe591fc655fa4 +Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1942896 +Reviewed-by: Tatiana Bradley +Run-TryBot: Roland Shoemaker +Reviewed-by: Damien Neil +TryBot-Result: Security TryBots +Reviewed-on: https://go-review.googlesource.com/c/net/+/514896 +Reviewed-by: Roland Shoemaker +TryBot-Result: Gopher Robot +Run-TryBot: Damien Neil +--- + +diff --git a/vendor/golang.org/x/net/html/render.go b/vendor/golang.org/x/net/html/render.go +index 8b28031..e8c1233 100644 +--- a/vendor/golang.org/x/net/html/render.go ++++ b/vendor/golang.org/x/net/html/render.go +@@ -194,9 +194,8 @@ + } + } + +- // Render any child nodes. +- switch n.Data { +- case "iframe", "noembed", "noframes", "noscript", "plaintext", "script", "style", "xmp": ++ // Render any child nodes ++ if childTextNodesAreLiteral(n) { + for c := n.FirstChild; c != nil; c = c.NextSibling { + if c.Type == TextNode { + if _, err := w.WriteString(c.Data); err != nil { +@@ -213,7 +212,7 @@ + // last element in the file, with no closing tag. + return plaintextAbort + } +- default: ++ } else { + for c := n.FirstChild; c != nil; c = c.NextSibling { + if err := render1(w, c); err != nil { + return err +@@ -231,6 +230,27 @@ + return w.WriteByte('>') + } + ++func childTextNodesAreLiteral(n *Node) bool { ++ // Per WHATWG HTML 13.3, if the parent of the current node is a style, ++ // script, xmp, iframe, noembed, noframes, or plaintext element, and the ++ // current node is a text node, append the value of the node's data ++ // literally. The specification is not explicit about it, but we only ++ // enforce this if we are in the HTML namespace (i.e. when the namespace is ++ // ""). ++ // NOTE: we also always include noscript elements, although the ++ // specification states that they should only be rendered as such if ++ // scripting is enabled for the node (which is not something we track). ++ if n.Namespace != "" { ++ return false ++ } ++ switch n.Data { ++ case "iframe", "noembed", "noframes", "noscript", "plaintext", "script", "style", "xmp": ++ return true ++ default: ++ return false ++ } ++} ++ + // writeQuoted writes s to w surrounded by quotes. Normally it will use double + // quotes, but if s contains a double quote, it will use single quotes. + // It is used for writing the identifiers in a doctype declaration. diff --git a/SPECS/multus/multus.spec b/SPECS/multus/multus.spec index 68f03b9cebe..9b74a9e77bd 100644 --- a/SPECS/multus/multus.spec +++ b/SPECS/multus/multus.spec @@ -19,7 +19,7 @@ Summary: CNI plugin providing multiple interfaces in containers Name: multus Version: 4.0.2 -Release: 4%{?dist} +Release: 6%{?dist} License: ASL 2.0 Vendor: Microsoft Corporation Distribution: Mariner @@ -28,6 +28,7 @@ URL: https://github.com/intel/multus-cni Source0: https://github.com/k8snetworkplumbingwg/multus-cni/archive/refs/tags/v%{version}.tar.gz#/%{name}-%{version}.tar.gz %define commit efdc0a5c7d1ea4bb236d638403420448b48782b3 Patch0: CVE-2023-45288.patch +Patch1: CVE-2023-3978.patch BuildRequires: golang BuildRequires: golang-packaging @@ -73,6 +74,12 @@ install -D -m0644 deployments/multus-daemonset.yml %{buildroot}%{_datadir}/k8s-y %{_datarootdir}/k8s-yaml/multus/multus.yaml %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 4.0.2-6 +- Bump release to rebuild with go 1.22.7 + +* Wed Aug 21 2024 Sumedh Sharma - 4.0.2-5 +- Add patch to resolve CVE-2023-3978 + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 4.0.2-4 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS/nfs-utils/nfs-utils.spec b/SPECS/nfs-utils/nfs-utils.spec index bc6bf63b62c..51f5fdd2c3d 100755 --- a/SPECS/nfs-utils/nfs-utils.spec +++ b/SPECS/nfs-utils/nfs-utils.spec @@ -1,7 +1,7 @@ Summary: NFS client utils Name: nfs-utils Version: 2.5.4 -Release: 4%{?dist} +Release: 5%{?dist} License: MIT and GPLv2 and GPLv2+ and BSD URL: https://linux-nfs.org/ Group: Applications/Nfs-utils-client @@ -82,6 +82,7 @@ sed -i 's/RPCGEN_PATH" =/rpcgen_path" =/' configure --enable-libmount-mount \ --without-tcp-wrappers \ --enable-gss \ + --enable-svcgss \ --enable-nfsv4 \ --with-rpcgen=internal \ --disable-static @@ -112,6 +113,8 @@ install -m644 systemd/nfs-idmapd.service %{buildroot}/lib/systemd/system/ install -m644 systemd/rpc_pipefs.target %{buildroot}/lib/systemd/system/ install -m644 systemd/var-lib-nfs-rpc_pipefs.mount %{buildroot}/lib/systemd/system/ install -m644 systemd/rpc-svcgssd.service %{buildroot}/lib/systemd/system/ +install -m644 systemd/rpc-gssd.service %{buildroot}/lib/systemd/system/ + find %{buildroot}/%{_libdir} -name '*.la' -delete install -vdm755 %{buildroot}/usr/lib/systemd/system-preset @@ -167,6 +170,10 @@ fi %{_libdir}/libnfsidmap.so %changelog +* Wed Sep 11 2024 Suresh Thelkar - 2.5.4-5 +- Build nfs-utils to provide rsc.svcgssd service +- Add rsc-gssd.service file to nfs-utils package + * Wed Nov 01 2023 Andy Zaugg - 2.5.4-4 - Fix post-install script to create nobody user instead of named user diff --git a/SPECS/node-problem-detector/node-problem-detector.spec b/SPECS/node-problem-detector/node-problem-detector.spec index 4c8b01c9a30..c7af314f813 100644 --- a/SPECS/node-problem-detector/node-problem-detector.spec +++ b/SPECS/node-problem-detector/node-problem-detector.spec @@ -1,7 +1,7 @@ Summary: Kubernetes daemon to detect and report node issues Name: node-problem-detector Version: 0.8.17 -Release: 4%{?dist} +Release: 5%{?dist} License: ASL 2.0 Vendor: Microsoft Corporation Distribution: Mariner @@ -66,6 +66,9 @@ make test %config(noreplace) %{_sysconfdir}/node-problem-detector.d/* %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 0.8.17-5 +- Bump release to rebuild with go 1.22.7 + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 0.8.17-4 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS/nvidia-container-toolkit/nvidia-container-toolkit.spec b/SPECS/nvidia-container-toolkit/nvidia-container-toolkit.spec index ce91a843f23..a7d89e65b54 100644 --- a/SPECS/nvidia-container-toolkit/nvidia-container-toolkit.spec +++ b/SPECS/nvidia-container-toolkit/nvidia-container-toolkit.spec @@ -2,7 +2,7 @@ Summary: NVIDIA container runtime hook Name: nvidia-container-toolkit Version: 1.13.5 -Release: 6%{?dist} +Release: 7%{?dist} License: ALS2.0 Vendor: Microsoft Corporation Distribution: Mariner @@ -94,6 +94,9 @@ rm -f %{_bindir}/nvidia-container-toolkit %{_bindir}/nvidia-ctk %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 1.13.5-7 +- Bump release to rebuild with go 1.22.7 + * Wed Jul 17 2024 Muhammad Falak R Wani - 1.13.5-6 - Drop requirement on a specific version of golang diff --git a/SPECS/opa/opa.spec b/SPECS/opa/opa.spec index cbe6a56948a..6e955b29e10 100644 --- a/SPECS/opa/opa.spec +++ b/SPECS/opa/opa.spec @@ -5,7 +5,7 @@ Summary: Open source, general-purpose policy engine Name: opa Version: 0.63.0 -Release: 3%{?dist} +Release: 4%{?dist} # Upstream license specification: MIT and Apache-2.0 # Main package: ASL 2.0 # internal/jwx: MIT @@ -54,6 +54,9 @@ install -D -p -m 0644 man/* %{buildroot}%{_mandir}/man1/ %{_bindir}/* %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 0.63.0-4 +- Bump release to rebuild with go 1.22.7 + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 0.63.0-3 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS/packer/packer.spec b/SPECS/packer/packer.spec index f7b55124995..e1a27346ee8 100644 --- a/SPECS/packer/packer.spec +++ b/SPECS/packer/packer.spec @@ -5,7 +5,7 @@ Summary: Tool for creating identical machine images for multiple platform Name: packer Epoch: 1 Version: 1.9.5 -Release: 2%{?dist} +Release: 3%{?dist} License: MPLv2.0 Vendor: Microsoft Corporation Distribution: Mariner @@ -69,6 +69,9 @@ go test -mod=vendor %{_bindir}/packer %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 1.9.5-3 +- Bump release to rebuild with go 1.22.7 + * Thu Aug 01 2024 Bala - 1:1.9.5-2 - Patch for CVE-2024-6104 diff --git a/SPECS/prometheus-adapter/CVE-2022-32149.patch b/SPECS/prometheus-adapter/CVE-2022-32149.patch new file mode 100644 index 00000000000..cf9ed3f1975 --- /dev/null +++ b/SPECS/prometheus-adapter/CVE-2022-32149.patch @@ -0,0 +1,35 @@ +From 7ee36713a66401f828dfe476196ca290f7c23ffe Mon Sep 17 00:00:00 2001 +From: Sindhu Karri +Date: Wed, 28 Aug 2024 05:01:17 +0000 +Subject: [PATCH] Fix CVE-2022-32149 + +--- + vendor/golang.org/x/text/language/parse.go | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/vendor/golang.org/x/text/language/parse.go b/vendor/golang.org/x/text/language/parse.go +index 11acfd8..11d11f4 100644 +--- a/vendor/golang.org/x/text/language/parse.go ++++ b/vendor/golang.org/x/text/language/parse.go +@@ -133,6 +133,7 @@ func update(b *language.Builder, part ...interface{}) (err error) { + } + + var errInvalidWeight = errors.New("ParseAcceptLanguage: invalid weight") ++var errTagListTooLarge = errors.New("tag list exceeds max length") + + // ParseAcceptLanguage parses the contents of an Accept-Language header as + // defined in http://www.ietf.org/rfc/rfc2616.txt and returns a list of Tags and +@@ -150,6 +151,10 @@ func ParseAcceptLanguage(s string) (tag []Tag, q []float32, err error) { + + entry, weight := split(entry, ';') + ++ if strings.Count(s, "-") > 1000 { ++ return nil, nil, errTagListTooLarge ++ } ++ + // Scan the language. + t, err := Parse(entry) + if err != nil { +-- +2.33.8 + diff --git a/SPECS/prometheus-adapter/prometheus-adapter.spec b/SPECS/prometheus-adapter/prometheus-adapter.spec index ae30d168c7f..f7240640d82 100644 --- a/SPECS/prometheus-adapter/prometheus-adapter.spec +++ b/SPECS/prometheus-adapter/prometheus-adapter.spec @@ -1,13 +1,14 @@ Summary: Kubernetes Custom, Resource, and External Metric APIs implemented to work with Prometheus. Name: prometheus-adapter Version: 0.10.0 -Release: 13%{?dist} +Release: 15%{?dist} License: Apache-2.0 Vendor: Microsoft Corporation Distribution: Mariner URL: https://github.com/kubernetes-sigs/prometheus-adapter Source0: https://github.com/kubernetes-sigs/%{name}/archive/refs/tags/v%{version}.tar.gz#/%{name}-%{version}.tar.gz Patch0: CVE-2024-24786.patch +Patch1: CVE-2022-32149.patch BuildRequires: golang %description @@ -42,6 +43,12 @@ make test %doc README.md RELEASE.md %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 0.10.0-15 +- Bump release to rebuild with go 1.22.7 + +* Fri Aug 30 2024 Sindhu Karri - 0.10.0-14 +- Fix CVE-2022-32149 in golang.org/x/text + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 0.10.0-13 - Bump release to rebuild with go 1.21.11 @@ -81,4 +88,4 @@ make test * Wed Feb 15 2023 Osama Esmail - 0.10.0-1 - Original version for CBL-Mariner -- License verified. \ No newline at end of file +- License verified. diff --git a/SPECS/prometheus-node-exporter/prometheus-node-exporter.spec b/SPECS/prometheus-node-exporter/prometheus-node-exporter.spec index aa43a70b770..b9df1bbb2e3 100644 --- a/SPECS/prometheus-node-exporter/prometheus-node-exporter.spec +++ b/SPECS/prometheus-node-exporter/prometheus-node-exporter.spec @@ -5,7 +5,7 @@ Summary: Exporter for machine metrics Name: prometheus-node-exporter Version: 1.3.1 -Release: 25%{?dist} +Release: 26%{?dist} # Upstream license specification: Apache-2.0 License: ASL 2.0 AND MIT Vendor: Microsoft Corporation @@ -113,6 +113,9 @@ getent passwd 'prometheus' >/dev/null || useradd -r -g 'prometheus' -d '%{_share %dir %attr(0755,prometheus,prometheus) %{_sharedstatedir}/prometheus/node-exporter %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 1.3.1-26 +- Bump release to rebuild with go 1.22.7 + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 1.3.1-25 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS/prometheus-process-exporter/prometheus-process-exporter.spec b/SPECS/prometheus-process-exporter/prometheus-process-exporter.spec index fa0ed7f2511..e9233da39b0 100644 --- a/SPECS/prometheus-process-exporter/prometheus-process-exporter.spec +++ b/SPECS/prometheus-process-exporter/prometheus-process-exporter.spec @@ -5,7 +5,7 @@ Summary: Prometheus exporter exposing process metrics from procfs Name: prometheus-process-exporter Version: 0.7.10 -Release: 20%{?dist} +Release: 21%{?dist} License: MIT Vendor: Microsoft Corporation Distribution: Mariner @@ -102,6 +102,9 @@ getent passwd 'prometheus' >/dev/null || useradd -r -g 'prometheus' -d '%{_share %dir %attr(0755,prometheus,prometheus) %{_sharedstatedir}/prometheus %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 0.7.10-21 +- Bump release to rebuild with go 1.22.7 + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 0.7.10-20 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS/prometheus/prometheus.spec b/SPECS/prometheus/prometheus.spec index 4a25863381b..103e57a290a 100644 --- a/SPECS/prometheus/prometheus.spec +++ b/SPECS/prometheus/prometheus.spec @@ -4,7 +4,7 @@ Summary: Prometheus monitoring system and time series database Name: prometheus Version: 2.37.0 -Release: 14%{?dist} +Release: 15%{?dist} License: Apache-2.0 Vendor: Microsoft Corporation Distribution: Mariner @@ -132,6 +132,9 @@ fi %doc README.md RELEASE.md documentation %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 2.37.0-15 +- Bump release to rebuild with go 1.22.7 + * Thu Aug 01 2024 Bala - 2.37.0-14 - Patch for CVE-2024-6104 diff --git a/SPECS/python-webob/python-webob.signatures.json b/SPECS/python-webob/python-webob.signatures.json index 6ea2972724b..4594d4f541a 100644 --- a/SPECS/python-webob/python-webob.signatures.json +++ b/SPECS/python-webob/python-webob.signatures.json @@ -1,5 +1,5 @@ { - "Signatures": { - "webob-1.8.7.tar.gz": "2bc9a81fddc02170d7e8de600d843e0d9247110594590056d5a2336740364248" - } + "Signatures": { + "webob-1.8.8.tar.gz": "4864af526db23ddd9a396b0ee1785ffab55185e4d428febd391d4644fe68f23a" + } } diff --git a/SPECS/python-webob/python-webob.spec b/SPECS/python-webob/python-webob.spec index 96dd7e4aac2..f6079ddda97 100644 --- a/SPECS/python-webob/python-webob.spec +++ b/SPECS/python-webob/python-webob.spec @@ -1,6 +1,6 @@ Summary: WebOb provides objects for HTTP requests and responses. Name: python-webob -Version: 1.8.7 +Version: 1.8.8 Release: 1%{?dist} License: MIT Vendor: Microsoft Corporation @@ -46,6 +46,9 @@ rm -f tests/performance_test.py %{python3_sitelib}/* %changelog +* Tue Aug 20 2024 CBL-Mariner Servicing Account - 1.8.8-1 +- Auto-upgrade to 1.8.8 - Fix CVE-2024-42353 + * Mon Feb 07 2022 Thomas Crain - 1.8.7-1 - Upgrade to latest upstream version - Use github source tarball diff --git a/SPECS/python-wheel/CVE-2022-40898.patch b/SPECS/python-wheel/CVE-2022-40898.patch new file mode 100644 index 00000000000..c87cf4feb4a --- /dev/null +++ b/SPECS/python-wheel/CVE-2022-40898.patch @@ -0,0 +1,31 @@ +From 56341b35080dfa25d28039ff7f0e774a6f56876d Mon Sep 17 00:00:00 2001 +From: Sudipta Pandit +Date: Fri, 6 Sep 2024 15:31:24 +0530 +Subject: [PATCH] [PATCH] Backport upstream patch for CVE-2022-40898 + +Backported from https://github.com/pypa/wheel/commit/88f02bc335d5404991e532e7f3b0fc80437bf4e0 +--- + wheel/wheelfile.py | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/wheel/wheelfile.py b/wheel/wheelfile.py +index ddf8509..ddb753c 100644 +--- a/wheel/wheelfile.py ++++ b/wheel/wheelfile.py +@@ -16,9 +16,10 @@ from wheel.util import urlsafe_b64decode, as_unicode, native, urlsafe_b64encode, + # Non-greedy matching of an optional build number may be too clever (more + # invalid wheel filenames will match). Separate regex for .dist-info? + WHEEL_INFO_RE = re.compile( +- r"""^(?P(?P.+?)-(?P.+?))(-(?P\d[^-]*))? +- -(?P.+?)-(?P.+?)-(?P.+?)\.whl$""", +- re.VERBOSE) ++ r"""^(?P(?P[^-]+?)-(?P[^-]+?))(-(?P\d[^-]*))? ++ -(?P[^-]+?)-(?P[^-]+?)-(?P[^.]+?)\.whl$""", ++ re.VERBOSE, ++) + + + def get_zipinfo_datetime(timestamp=None): +-- +2.34.1 + diff --git a/SPECS/python-wheel/python-wheel.spec b/SPECS/python-wheel/python-wheel.spec index 4fc306c3fd9..e9e9efbbfa9 100644 --- a/SPECS/python-wheel/python-wheel.spec +++ b/SPECS/python-wheel/python-wheel.spec @@ -3,12 +3,13 @@ Summary: Built-package format for Python Name: python-%{pypi_name} Version: 0.33.6 -Release: 7%{?dist} +Release: 8%{?dist} License: MIT Vendor: Microsoft Corporation Distribution: Mariner URL: https://github.com/pypa/wheel Source0: %{url}/archive/%{version}/%{pypi_name}-%{version}.tar.gz +Patch0: CVE-2022-40898.patch %global pypi_name wheel %global python_wheelname %{pypi_name}-%{version}-py2.py3-none-any.whl %global python_wheeldir %{_datadir}/python-wheels @@ -102,6 +103,9 @@ PYTHONPATH=%{buildroot}%{python3_sitelib} py.test3 -v --ignore build %endif %changelog +* Fri Sep 09 2024 Sudipta Pandit - 0.33.6-8 +- Backport CVE-2022-40898 fix from upstream + * Thu Mar 03 2022 Bala - 0.33.6-7 - BR multiple python3 modules for PTest - pip3 install additional modules which not available as RPM diff --git a/SPECS/python3/CVE-2024-6232.patch b/SPECS/python3/CVE-2024-6232.patch new file mode 100644 index 00000000000..aef0c381168 --- /dev/null +++ b/SPECS/python3/CVE-2024-6232.patch @@ -0,0 +1,221 @@ +diff --git a/Lib/tarfile.py b/Lib/tarfile.py +index 7a6158c2eb9..bc5ec8bd582 100755 +--- a/Lib/tarfile.py ++++ b/Lib/tarfile.py +@@ -840,6 +840,9 @@ _NAMED_FILTERS = { + # Sentinel for replace() defaults, meaning "don't change the attribute" + _KEEP = object() + ++# Header length is digits followed by a space. ++_header_length_prefix_re = re.compile(br"([0-9]{1,20}) ") ++ + class TarInfo(object): + """Informational class which holds the details about an + archive member given by a tar header block. +@@ -1399,41 +1402,59 @@ class TarInfo(object): + else: + pax_headers = tarfile.pax_headers.copy() + +- # Check if the pax header contains a hdrcharset field. This tells us +- # the encoding of the path, linkpath, uname and gname fields. Normally, +- # these fields are UTF-8 encoded but since POSIX.1-2008 tar +- # implementations are allowed to store them as raw binary strings if +- # the translation to UTF-8 fails. +- match = re.search(br"\d+ hdrcharset=([^\n]+)\n", buf) +- if match is not None: +- pax_headers["hdrcharset"] = match.group(1).decode("utf-8") +- +- # For the time being, we don't care about anything other than "BINARY". +- # The only other value that is currently allowed by the standard is +- # "ISO-IR 10646 2000 UTF-8" in other words UTF-8. +- hdrcharset = pax_headers.get("hdrcharset") +- if hdrcharset == "BINARY": +- encoding = tarfile.encoding +- else: +- encoding = "utf-8" +- + # Parse pax header information. A record looks like that: + # "%d %s=%s\n" % (length, keyword, value). length is the size + # of the complete record including the length field itself and +- # the newline. keyword and value are both UTF-8 encoded strings. +- regex = re.compile(br"(\d+) ([^=]+)=") ++ # the newline. + pos = 0 +- while True: +- match = regex.match(buf, pos) +- if not match: +- break ++ encoding = None ++ raw_headers = [] ++ while len(buf) > pos and buf[pos] != 0x00: ++ if not (match := _header_length_prefix_re.match(buf, pos)): ++ raise InvalidHeaderError("invalid header") ++ try: ++ length = int(match.group(1)) ++ except ValueError: ++ raise InvalidHeaderError("invalid header") ++ # Headers must be at least 5 bytes, shortest being '5 x=\n'. ++ # Value is allowed to be empty. ++ if length < 5: ++ raise InvalidHeaderError("invalid header") ++ if pos + length > len(buf): ++ raise InvalidHeaderError("invalid header") + +- length, keyword = match.groups() +- length = int(length) +- if length == 0: ++ header_value_end_offset = match.start(1) + length - 1 # Last byte of the header ++ keyword_and_value = buf[match.end(1) + 1:header_value_end_offset] ++ raw_keyword, equals, raw_value = keyword_and_value.partition(b"=") ++ ++ # Check the framing of the header. The last character must be '\n' (0x0A) ++ if not raw_keyword or equals != b"=" or buf[header_value_end_offset] != 0x0A: + raise InvalidHeaderError("invalid header") +- value = buf[match.end(2) + 1:match.start(1) + length - 1] ++ raw_headers.append((length, raw_keyword, raw_value)) ++ ++ # Check if the pax header contains a hdrcharset field. This tells us ++ # the encoding of the path, linkpath, uname and gname fields. Normally, ++ # these fields are UTF-8 encoded but since POSIX.1-2008 tar ++ # implementations are allowed to store them as raw binary strings if ++ # the translation to UTF-8 fails. For the time being, we don't care about ++ # anything other than "BINARY". The only other value that is currently ++ # allowed by the standard is "ISO-IR 10646 2000 UTF-8" in other words UTF-8. ++ # Note that we only follow the initial 'hdrcharset' setting to preserve ++ # the initial behavior of the 'tarfile' module. ++ if raw_keyword == b"hdrcharset" and encoding is None: ++ if raw_value == b"BINARY": ++ encoding = tarfile.encoding ++ else: # This branch ensures only the first 'hdrcharset' header is used. ++ encoding = "utf-8" ++ ++ pos += length + ++ # If no explicit hdrcharset is set, we use UTF-8 as a default. ++ if encoding is None: ++ encoding = "utf-8" ++ ++ # After parsing the raw headers we can decode them to text. ++ for length, raw_keyword, raw_value in raw_headers: + # Normally, we could just use "utf-8" as the encoding and "strict" + # as the error handler, but we better not take the risk. For + # example, GNU tar <= 1.23 is known to store filenames it cannot +@@ -1441,17 +1462,16 @@ class TarInfo(object): + # hdrcharset=BINARY header). + # We first try the strict standard encoding, and if that fails we + # fall back on the user's encoding and error handler. +- keyword = self._decode_pax_field(keyword, "utf-8", "utf-8", ++ keyword = self._decode_pax_field(raw_keyword, "utf-8", "utf-8", + tarfile.errors) + if keyword in PAX_NAME_FIELDS: +- value = self._decode_pax_field(value, encoding, tarfile.encoding, ++ value = self._decode_pax_field(raw_value, encoding, tarfile.encoding, + tarfile.errors) + else: +- value = self._decode_pax_field(value, "utf-8", "utf-8", ++ value = self._decode_pax_field(raw_value, "utf-8", "utf-8", + tarfile.errors) + + pax_headers[keyword] = value +- pos += length + + # Fetch the next header. + try: +@@ -1466,7 +1486,7 @@ class TarInfo(object): + + elif "GNU.sparse.size" in pax_headers: + # GNU extended sparse format version 0.0. +- self._proc_gnusparse_00(next, pax_headers, buf) ++ self._proc_gnusparse_00(next, raw_headers) + + elif pax_headers.get("GNU.sparse.major") == "1" and pax_headers.get("GNU.sparse.minor") == "0": + # GNU extended sparse format version 1.0. +@@ -1488,15 +1508,24 @@ class TarInfo(object): + + return next + +- def _proc_gnusparse_00(self, next, pax_headers, buf): ++ def _proc_gnusparse_00(self, next, raw_headers): + """Process a GNU tar extended sparse header, version 0.0. + """ + offsets = [] +- for match in re.finditer(br"\d+ GNU.sparse.offset=(\d+)\n", buf): +- offsets.append(int(match.group(1))) + numbytes = [] +- for match in re.finditer(br"\d+ GNU.sparse.numbytes=(\d+)\n", buf): +- numbytes.append(int(match.group(1))) ++ for _, keyword, value in raw_headers: ++ if keyword == b"GNU.sparse.offset": ++ try: ++ offsets.append(int(value.decode())) ++ except ValueError: ++ raise InvalidHeaderError("invalid header") ++ ++ elif keyword == b"GNU.sparse.numbytes": ++ try: ++ numbytes.append(int(value.decode())) ++ except ValueError: ++ raise InvalidHeaderError("invalid header") ++ + next.sparse = list(zip(offsets, numbytes)) + + def _proc_gnusparse_01(self, next, pax_headers): +@@ -2875,4 +2904,4 @@ def main(): + print('{!r} file created.'.format(tar_name)) + + if __name__ == '__main__': +- main() ++ main() +\ No newline at end of file +diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py +index 3df64c78032..cadd3f35808 100644 +--- a/Lib/test/test_tarfile.py ++++ b/Lib/test/test_tarfile.py +@@ -1113,6 +1113,47 @@ class PaxReadTest(LongnameTest, ReadTest, unittest.TestCase): + finally: + tar.close() + ++ def test_pax_header_bad_formats(self): ++ # The fields from the pax header have priority over the ++ # TarInfo. ++ pax_header_replacements = ( ++ b" foo=bar\n", ++ b"0 \n", ++ b"1 \n", ++ b"2 \n", ++ b"3 =\n", ++ b"4 =a\n", ++ b"1000000 foo=bar\n", ++ b"0 foo=bar\n", ++ b"-12 foo=bar\n", ++ b"000000000000000000000000036 foo=bar\n", ++ ) ++ pax_headers = {"foo": "bar"} ++ ++ for replacement in pax_header_replacements: ++ with self.subTest(header=replacement): ++ tar = tarfile.open(tmpname, "w", format=tarfile.PAX_FORMAT, ++ encoding="iso8859-1") ++ try: ++ t = tarfile.TarInfo() ++ t.name = "pax" # non-ASCII ++ t.uid = 1 ++ t.pax_headers = pax_headers ++ tar.addfile(t) ++ finally: ++ tar.close() ++ ++ with open(tmpname, "rb") as f: ++ data = f.read() ++ self.assertIn(b"11 foo=bar\n", data) ++ data = data.replace(b"11 foo=bar\n", replacement) ++ ++ with open(tmpname, "wb") as f: ++ f.truncate() ++ f.write(data) ++ ++ with self.assertRaisesRegex(tarfile.ReadError, r"file could not be opened successfully"): ++ tarfile.open(tmpname, encoding="iso8859-1") + + class WriteTestBase(TarTest): + # Put all write tests in here that are supposed to be tested diff --git a/SPECS/python3/CVE-2024-8088.patch b/SPECS/python3/CVE-2024-8088.patch new file mode 100644 index 00000000000..923323f5467 --- /dev/null +++ b/SPECS/python3/CVE-2024-8088.patch @@ -0,0 +1,126 @@ +diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py +index 17e95eb8623..31e9fef4355 100644 +--- a/Lib/test/test_zipfile.py ++++ b/Lib/test/test_zipfile.py +@@ -3054,6 +3054,83 @@ class TestPath(unittest.TestCase): + data = ['/'.join(string.ascii_lowercase + str(n)) for n in range(10000)] + zipfile.CompleteDirs._implied_dirs(data) + ++ def test_malformed_paths(self): ++ """ ++ Path should handle malformed paths gracefully. ++ ++ Paths with leading slashes are not visible. ++ ++ Paths with dots are treated like regular files. ++ """ ++ data = io.BytesIO() ++ zf = zipfile.ZipFile(data, "w") ++ zf.writestr("/one-slash.txt", b"content") ++ zf.writestr("//two-slash.txt", b"content") ++ zf.writestr("../parent.txt", b"content") ++ zf.filename = '' ++ root = zipfile.Path(zf) ++ assert list(map(str, root.iterdir())) == ['../'] ++ assert root.joinpath('..').joinpath('parent.txt').read_bytes() == b'content' ++ ++ def test_unsupported_names(self): ++ """ ++ Path segments with special characters are readable. ++ ++ On some platforms or file systems, characters like ++ ``:`` and ``?`` are not allowed, but they are valid ++ in the zip file. ++ """ ++ data = io.BytesIO() ++ zf = zipfile.ZipFile(data, "w") ++ zf.writestr("path?", b"content") ++ zf.writestr("V: NMS.flac", b"fLaC...") ++ zf.filename = '' ++ root = zipfile.Path(zf) ++ contents = root.iterdir() ++ assert next(contents).name == 'path?' ++ assert next(contents).name == 'V: NMS.flac' ++ assert root.joinpath('V: NMS.flac').read_bytes() == b"fLaC..." ++ ++ def test_backslash_not_separator(self): ++ """ ++ In a zip file, backslashes are not separators. ++ """ ++ data = io.BytesIO() ++ zf = zipfile.ZipFile(data, "w") ++ zf.writestr(DirtyZipInfo.for_name("foo\\bar", zf), b"content") ++ zf.filename = '' ++ root = zipfile.Path(zf) ++ (first,) = root.iterdir() ++ assert not first.is_dir() ++ assert first.name == 'foo\\bar' ++ ++ ++class DirtyZipInfo(zipfile.ZipInfo): ++ """ ++ Bypass name sanitization. ++ """ ++ ++ def __init__(self, filename, *args, **kwargs): ++ super().__init__(filename, *args, **kwargs) ++ self.filename = filename ++ ++ @classmethod ++ def for_name(cls, name, archive): ++ """ ++ Construct the same way that ZipFile.writestr does. ++ ++ TODO: extract this functionality and re-use ++ """ ++ self = cls(filename=name, date_time=time.localtime(time.time())[:6]) ++ self.compress_type = archive.compression ++ self.compress_level = archive.compresslevel ++ if self.filename.endswith('/'): # pragma: no cover ++ self.external_attr = 0o40775 << 16 # drwxrwxr-x ++ self.external_attr |= 0x10 # MS-DOS directory flag ++ else: ++ self.external_attr = 0o600 << 16 # ?rw------- ++ return self ++ + + if __name__ == "__main__": +- unittest.main() ++ unittest.main() +\ No newline at end of file +diff --git a/Lib/zipfile.py b/Lib/zipfile.py +index 95f95ee1126..dd48a6a87ba 100644 +--- a/Lib/zipfile.py ++++ b/Lib/zipfile.py +@@ -2146,7 +2146,7 @@ def _parents(path): + def _ancestry(path): + """ + Given a path with elements separated by +- posixpath.sep, generate all elements of that path ++ posixpath.sep, generate all elements of that path. + + >>> list(_ancestry('b/d')) + ['b/d', 'b'] +@@ -2158,9 +2158,14 @@ def _ancestry(path): + ['b'] + >>> list(_ancestry('')) + [] ++ ++ Multiple separators are treated like a single. ++ ++ >>> list(_ancestry('//b//d///f//')) ++ ['//b//d///f', '//b//d', '//b'] + """ + path = path.rstrip(posixpath.sep) +- while path and path != posixpath.sep: ++ while path.rstrip(posixpath.sep): + yield path + path, tail = posixpath.split(path) + +@@ -2446,4 +2451,4 @@ def main(args=None): + + + if __name__ == "__main__": +- main() ++ main() +\ No newline at end of file diff --git a/SPECS/python3/python3.spec b/SPECS/python3/python3.spec index 7402c06bf7e..82603b247fb 100644 --- a/SPECS/python3/python3.spec +++ b/SPECS/python3/python3.spec @@ -12,7 +12,7 @@ Summary: A high-level scripting language Name: python3 Version: 3.9.19 -Release: 4%{?dist} +Release: 5%{?dist} License: PSF Vendor: Microsoft Corporation Distribution: Mariner @@ -24,6 +24,8 @@ Patch0: cgi3.patch Patch1: 0001-gh-95231-Disable-md5-crypt-modules-if-FIPS-is-enable.patch Patch2: CVE-2024-0397.patch Patch3: CVE-2024-7592.patch +Patch4: CVE-2024-6232.patch +Patch5: CVE-2024-8088.patch # Patch for setuptools, resolved in 65.5.1 Patch1000: CVE-2022-40897.patch Patch1001: CVE-2024-6345.patch @@ -165,6 +167,8 @@ The test package contains all regression tests for Python as well as the modules %patch1 -p1 %patch2 -p1 %patch3 -p1 +%patch4 -p1 +%patch5 -p1 %build # Remove GCC specs and build environment linker scripts @@ -320,6 +324,9 @@ rm -rf %{buildroot}%{_bindir}/__pycache__ %{_libdir}/python%{majmin}/test/* %changelog +* Fri Sep 20 2024 Himaja Kesari - 3.9.19-5 +- Patch CVE-2024-6232 and CVE-2024-8088 + * Wed Aug 21 2024 Brian Fjeldstad - 3.9.19-4 - Patch for CVE-2024-7592 diff --git a/SPECS/qemu/CVE-2024-24474.patch b/SPECS/qemu/CVE-2024-24474.patch new file mode 100644 index 00000000000..b8ca3c8a2f7 --- /dev/null +++ b/SPECS/qemu/CVE-2024-24474.patch @@ -0,0 +1,40 @@ +From 77668e4b9bca03a856c27ba899a2513ddf52bb52 Mon Sep 17 00:00:00 2001 +From: Mark Cave-Ayland +Date: Wed, 13 Sep 2023 21:44:09 +0100 +Subject: [PATCH] esp: restrict non-DMA transfer length to that of available + data + +In the case where a SCSI layer transfer is incorrectly terminated, it is +possible for a TI command to cause a SCSI buffer overflow due to the +expected transfer data length being less than the available data in the +FIFO. When this occurs the unsigned async_len variable underflows and +becomes a large offset which writes past the end of the allocated SCSI +buffer. + +Restrict the non-DMA transfer length to be the smallest of the expected +transfer length and the available FIFO data to ensure that it is no longer +possible for the SCSI buffer overflow to occur. + +Signed-off-by: Mark Cave-Ayland +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1810 +Reviewed-by: Thomas Huth +Message-ID: <20230913204410.65650-3-mark.cave-ayland@ilande.co.uk> +Signed-off-by: Paolo Bonzini +--- + hw/scsi/esp.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c +index 4218a6a96054..9b11d8c5738a 100644 +--- a/hw/scsi/esp.c ++++ b/hw/scsi/esp.c +@@ -759,7 +759,8 @@ static void esp_do_nodma(ESPState *s) + } + + if (to_device) { +- len = MIN(fifo8_num_used(&s->fifo), ESP_FIFO_SZ); ++ len = MIN(s->async_len, ESP_FIFO_SZ); ++ len = MIN(len, fifo8_num_used(&s->fifo)); + esp_fifo_pop_buf(&s->fifo, s->async_buf, len); + s->async_buf += len; + s->async_len -= len; diff --git a/SPECS/qemu/qemu.spec b/SPECS/qemu/qemu.spec index 3fb48cc50cc..0a81e62b2c7 100644 --- a/SPECS/qemu/qemu.spec +++ b/SPECS/qemu/qemu.spec @@ -217,7 +217,7 @@ Obsoletes: %{name}-system-unicore32-core <= %{version}-%{release} Summary: QEMU is a FAST! processor emulator Name: qemu Version: 6.2.0 -Release: 19%{?dist} +Release: 20%{?dist} License: BSD AND CC-BY AND GPLv2+ AND LGPLv2+ AND MIT Vendor: Microsoft Corporation Distribution: Mariner @@ -275,6 +275,7 @@ Patch1013: CVE-2022-3165.patch Patch1014: CVE-2021-3750.patch Patch1015: CVE-2022-36648.patch Patch1016: CVE-2023-3354.patch +Patch1017: CVE-2024-24474.patch # alsa audio output BuildRequires: alsa-lib-devel @@ -2309,6 +2310,9 @@ useradd -r -u 107 -g qemu -G kvm -d / -s %{_sbindir}/nologin \ %changelog +* Mon Aug 19 2024 Brian Fjeldstad - 6.2.0-20 +- Address CVE-2024-24474 + * Mon Oct 30 2023 Jonathan Behrens - 6.2.0-19 - Address CVE-2023-3354 diff --git a/SPECS/reaper/CVE-2024-43796.patch b/SPECS/reaper/CVE-2024-43796.patch new file mode 100644 index 00000000000..471955a0cb8 --- /dev/null +++ b/SPECS/reaper/CVE-2024-43796.patch @@ -0,0 +1,25 @@ +From 77615000b4152081d05d16befd636c6e4274c9a4 Mon Sep 17 00:00:00 2001 +From: Rohit Rawat +Date: Wed, 25 Sep 2024 08:21:08 +0000 +Subject: [PATCH] CVE-2024-43796: don't render redirect values in anchor href + +--- + src/ui/node_modules/express/lib/response.js | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/ui/node_modules/express/lib/response.js b/src/ui/node_modules/express/lib/response.js +index dd7b3c82..54c0c8fa 100644 +--- a/src/ui/node_modules/express/lib/response.js ++++ b/src/ui/node_modules/express/lib/response.js +@@ -969,7 +969,7 @@ res.redirect = function redirect(url) { + + html: function(){ + var u = escapeHtml(address); +- body = '

' + statuses.message[status] + '. Redirecting to ' + u + '

' ++ body = '

' + statuses.message[status] + '. Redirecting to ' + u + '

' + }, + + default: function(){ +-- +2.39.4 + diff --git a/SPECS/reaper/reaper.spec b/SPECS/reaper/reaper.spec index 78e15dadc3d..021a9b5b716 100755 --- a/SPECS/reaper/reaper.spec +++ b/SPECS/reaper/reaper.spec @@ -6,7 +6,7 @@ Summary: Reaper for cassandra is a tool for running Apache Cassandra repairs against single or multi-site clusters. Name: reaper Version: 3.1.1 -Release: 11%{?dist} +Release: 12%{?dist} License: ASL 2.0 Vendor: Microsoft Corporation Distribution: Mariner @@ -36,6 +36,7 @@ Patch0: CVE-2024-37890.patch Patch1: CVE-2023-42282.patch Patch2: CVE-2017-18214.patch Patch3: CVE-2024-42459.patch +Patch4: CVE-2024-43796.patch BuildRequires: git BuildRequires: javapackages-tools BuildRequires: maven @@ -172,6 +173,9 @@ fi %{_unitdir}/cassandra-%{name}.service %changelog +* Wed Sep 25 2024 Rohit Rawat - 3.1.1-12 +- Patch CVE-2024-43796 in express module + * Tue Aug 20 2024 Cameron Baird - 3.1.1-11 - Introduce DER-signature-decoding-correction.patch to address CVE-2024-42459, - CVE-2024-42460, CVE-2024-42461 diff --git a/SPECS/rook/rook.spec b/SPECS/rook/rook.spec index 59e43e6c39a..dda49a504fc 100644 --- a/SPECS/rook/rook.spec +++ b/SPECS/rook/rook.spec @@ -19,7 +19,7 @@ Summary: Orchestrator for distributed storage systems in cloud-native environments Name: rook Version: 1.6.2 -Release: 21%{?dist} +Release: 22%{?dist} License: Apache-2.0 Vendor: Microsoft Corporation Distribution: Mariner @@ -256,6 +256,9 @@ sed -i -e "s|\(.*tag: \)VERSION|\1%{helm_appVersion}|" %{values_yaml} # bother adding docs or changelog or anything %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 1.6.2-22 +- Bump release to rebuild with go 1.22.7 + * Thu Aug 01 2024 Bala - 1.6.2-21 - Patch CVE-2024-6104 diff --git a/SPECS/ruby/CVE-2024-41946.patch b/SPECS/ruby/CVE-2024-41946.patch new file mode 100644 index 00000000000..1f7488a904d --- /dev/null +++ b/SPECS/ruby/CVE-2024-41946.patch @@ -0,0 +1,111 @@ +From c5565ff926fde19da10b7b4b1b9768d5dadb67e1 Mon Sep 17 00:00:00 2001 +From: Harshit Gupta +Date: Thu, 19 Sep 2024 06:30:45 -0700 +Subject: [PATCH] Apply patch for CVE-2024-41946 + +--- + .../lib/rexml/parsers/baseparser.rb | 19 ++++++++++++++++++- + .../lib/rexml/parsers/pullparser.rb | 4 ++++ + .../lib/rexml/parsers/sax2parser.rb | 4 ++++ + 3 files changed, 26 insertions(+), 1 deletion(-) + +Based on upstream commit +https://github.com/ruby/rexml/commit/033d1909a8f259d5a7c53681bcaf14f13bcf0368 + +diff --git a/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/baseparser.rb b/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/baseparser.rb +index ee30e17..30e8d65 100644 +--- a/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/baseparser.rb ++++ b/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/baseparser.rb +@@ -115,6 +115,7 @@ module REXML + def initialize( source ) + self.stream = source + @listeners = [] ++ @entity_expansion_count = 0 + end + + def add_listener( listener ) +@@ -122,6 +123,7 @@ module REXML + end + + attr_reader :source ++ attr_reader :entity_expansion_count + + def stream=( source ) + @source = SourceFactory.create_from( source ) +@@ -438,7 +440,9 @@ module REXML + def entity( reference, entities ) + value = nil + value = entities[ reference ] if entities +- if not value ++ if value ++ record_entity_expansion ++ else + value = DEFAULT_ENTITIES[ reference ] + value = value[2] if value + end +@@ -474,12 +478,17 @@ module REXML + } + matches.collect!{|x|x[0]}.compact! + if matches.size > 0 ++ sum = 0 + matches.each do |entity_reference| + unless filter and filter.include?(entity_reference) + entity_value = entity( entity_reference, entities ) + if entity_value + re = /&#{entity_reference};/ + rv.gsub!( re, entity_value ) ++ sum += rv.bytesize ++ if sum > Security.entity_expansion_text_limit ++ raise "entity expansion has grown too large" ++ end + else + er = DEFAULT_ENTITIES[entity_reference] + rv.gsub!( er[0], er[2] ) if er +@@ -492,6 +501,14 @@ module REXML + end + + private ++ ++ def record_entity_expansion ++ @entity_expansion_count += 1 ++ if @entity_expansion_count > Security.entity_expansion_limit ++ raise "number of entity expansions exceeded, processing aborted." ++ end ++ end ++ + def need_source_encoding_update?(xml_declaration_encoding) + return false if xml_declaration_encoding.nil? + return false if /\AUTF-16\z/i =~ xml_declaration_encoding +diff --git a/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/pullparser.rb b/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/pullparser.rb +index f8b232a..36b4595 100644 +--- a/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/pullparser.rb ++++ b/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/pullparser.rb +@@ -47,6 +47,10 @@ module REXML + @listeners << listener + end + ++ def entity_expansion_count ++ @parser.entity_expansion_count ++ end ++ + def each + while has_next? + yield self.pull +diff --git a/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/sax2parser.rb b/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/sax2parser.rb +index 6a24ce2..01cb469 100644 +--- a/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/sax2parser.rb ++++ b/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/sax2parser.rb +@@ -22,6 +22,10 @@ module REXML + @parser.source + end + ++ def entity_expansion_count ++ @parser.entity_expansion_count ++ end ++ + def add_listener( listener ) + @parser.add_listener( listener ) + end +-- +2.34.1 + diff --git a/SPECS/ruby/ruby.spec b/SPECS/ruby/ruby.spec index bdc67c8561b..ba84ca4d9c2 100644 --- a/SPECS/ruby/ruby.spec +++ b/SPECS/ruby/ruby.spec @@ -83,7 +83,7 @@ Name: ruby # provides should be versioned according to the ruby version. # More info: https://stdgems.org/ Version: 3.1.4 -Release: 6%{?dist} +Release: 7%{?dist} License: (Ruby OR BSD) AND Public Domain AND MIT AND CC0 AND zlib AND UCD Vendor: Microsoft Corporation Distribution: Mariner @@ -104,6 +104,8 @@ Patch2: CVE-2024-27281.patch Patch3: CVE-2024-27282.patch # Patch no longer needed if REXML gem is 3.2.7 or later. Now is 3.2.5 Patch4: CVE-2024-35176.patch +# Patch no longer needed if REXML gem is 3.3.3 or later. Now is 3.2.5 +Patch5: CVE-2024-41946.patch BuildRequires: openssl-devel BuildRequires: readline BuildRequires: readline-devel @@ -406,6 +408,9 @@ sudo -u test make test TESTS="-v" %{_rpmconfigdir}/rubygems.con %changelog +* Thu Sep 19 2024 Harshit Gupta - 3.1.4-7 +- Patch CVE-2024-41946 + * Thu May 30 2024 Minghe Ren - 3.1.4-6 - Patch CVE-2024-35176 diff --git a/SPECS/rubygem-rexml/CVE-2024-41946.patch b/SPECS/rubygem-rexml/CVE-2024-41946.patch new file mode 100644 index 00000000000..36474f1c4ab --- /dev/null +++ b/SPECS/rubygem-rexml/CVE-2024-41946.patch @@ -0,0 +1,111 @@ +From f91985dc627c487b3d03b0f83b1087515dd92f7c Mon Sep 17 00:00:00 2001 +From: Harshit Gupta +Date: Thu, 19 Sep 2024 07:30:21 -0700 +Subject: [PATCH] Apply CVE-2024-41946.patch + +--- + lib/rexml/parsers/baseparser.rb | 19 ++++++++++++++++++- + lib/rexml/parsers/pullparser.rb | 4 ++++ + lib/rexml/parsers/sax2parser.rb | 4 ++++ + 3 files changed, 26 insertions(+), 1 deletion(-) + +Based on upstream commit +https://github.com/ruby/rexml/commit/033d1909a8f259d5a7c53681bcaf14f13bcf0368 + +diff --git a/lib/rexml/parsers/baseparser.rb b/lib/rexml/parsers/baseparser.rb +index d09237c..61f6787 100644 +--- a/lib/rexml/parsers/baseparser.rb ++++ b/lib/rexml/parsers/baseparser.rb +@@ -128,6 +128,7 @@ module REXML + def initialize( source ) + self.stream = source + @listeners = [] ++ @entity_expansion_count = 0 + end + + def add_listener( listener ) +@@ -135,6 +136,7 @@ module REXML + end + + attr_reader :source ++ attr_reader :entity_expansion_count + + def stream=( source ) + @source = SourceFactory.create_from( source ) +@@ -446,7 +448,9 @@ module REXML + def entity( reference, entities ) + value = nil + value = entities[ reference ] if entities +- if not value ++ if value ++ record_entity_expansion ++ else + value = DEFAULT_ENTITIES[ reference ] + value = value[2] if value + end +@@ -481,12 +485,17 @@ module REXML + } + matches.collect!{|x|x[0]}.compact! + if matches.size > 0 ++ sum = 0 + matches.each do |entity_reference| + unless filter and filter.include?(entity_reference) + entity_value = entity( entity_reference, entities ) + if entity_value + re = /&#{entity_reference};/ + rv.gsub!( re, entity_value ) ++ sum += rv.bytesize ++ if sum > Security.entity_expansion_text_limit ++ raise "entity expansion has grown too large" ++ end + else + er = DEFAULT_ENTITIES[entity_reference] + rv.gsub!( er[0], er[2] ) if er +@@ -499,6 +508,14 @@ module REXML + end + + private ++ ++ def record_entity_expansion ++ @entity_expansion_count += 1 ++ if @entity_expansion_count > Security.entity_expansion_limit ++ raise "number of entity expansions exceeded, processing aborted." ++ end ++ end ++ + def need_source_encoding_update?(xml_declaration_encoding) + return false if xml_declaration_encoding.nil? + return false if /\AUTF-16\z/i =~ xml_declaration_encoding +diff --git a/lib/rexml/parsers/pullparser.rb b/lib/rexml/parsers/pullparser.rb +index f8b232a..36b4595 100644 +--- a/lib/rexml/parsers/pullparser.rb ++++ b/lib/rexml/parsers/pullparser.rb +@@ -47,6 +47,10 @@ module REXML + @listeners << listener + end + ++ def entity_expansion_count ++ @parser.entity_expansion_count ++ end ++ + def each + while has_next? + yield self.pull +diff --git a/lib/rexml/parsers/sax2parser.rb b/lib/rexml/parsers/sax2parser.rb +index 6a24ce2..01cb469 100644 +--- a/lib/rexml/parsers/sax2parser.rb ++++ b/lib/rexml/parsers/sax2parser.rb +@@ -22,6 +22,10 @@ module REXML + @parser.source + end + ++ def entity_expansion_count ++ @parser.entity_expansion_count ++ end ++ + def add_listener( listener ) + @parser.add_listener( listener ) + end +-- +2.34.1 + diff --git a/SPECS/rubygem-rexml/rubygem-rexml.spec b/SPECS/rubygem-rexml/rubygem-rexml.spec index 226351689ef..b9bfdb3b1c3 100644 --- a/SPECS/rubygem-rexml/rubygem-rexml.spec +++ b/SPECS/rubygem-rexml/rubygem-rexml.spec @@ -3,13 +3,14 @@ Summary: REXML is an XML toolkit for Ruby Name: rubygem-%{gem_name} Version: 3.2.7 -Release: 1%{?dist} +Release: 2%{?dist} License: BSD Vendor: Microsoft Corporation Distribution: Mariner Group: Development/Languages URL: https://github.com/ruby/rexml Source0: https://github.com/ruby/rexml/archive/refs/tags/v%{version}.tar.gz#/%{gem_name}-%{version}.tar.gz +Patch0: CVE-2024-41946.patch BuildRequires: git BuildRequires: ruby Requires: ruby(release) @@ -34,6 +35,9 @@ gem install -V --local --force --install-dir %{buildroot}/%{gemdir} %{gem_name}- %{gemdir} %changelog +* Thu Sep 19 2024 Harshit Gupta - 3.2.7-2 +- Add patch for CVE-2024-41946 + * Fri May 31 2024 Minghe Ren - 3.2.7-1 - Upgrade to 3.2.7 to resolve CVE-2024-35176 - Remove CVE-2024-35176.patch as it is no longer needed diff --git a/SPECS/skopeo/skopeo.spec b/SPECS/skopeo/skopeo.spec index 3d4cab36676..9ff633442fd 100644 --- a/SPECS/skopeo/skopeo.spec +++ b/SPECS/skopeo/skopeo.spec @@ -1,7 +1,7 @@ Summary: Inspect container images and repositories on registries Name: skopeo Version: 1.14.2 -Release: 7%{?dist} +Release: 8%{?dist} License: Apache-2.0 Vendor: Microsoft Corporation Distribution: Mariner @@ -48,6 +48,9 @@ make test-unit-local %{_mandir}/man1/%%{name}* %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 1.14.2-8 +- Bump release to rebuild with go 1.22.7 + * Wed Jul 17 2024 Sindhu Karri - 1.14.2-7 - Fix CVE-2024-6104 in github.com/hashicorp/go-retryablehttp diff --git a/SPECS/sriov-network-device-plugin/sriov-network-device-plugin.spec b/SPECS/sriov-network-device-plugin/sriov-network-device-plugin.spec index 85c3cea5a6b..d6f209556a1 100644 --- a/SPECS/sriov-network-device-plugin/sriov-network-device-plugin.spec +++ b/SPECS/sriov-network-device-plugin/sriov-network-device-plugin.spec @@ -1,7 +1,7 @@ Summary: Plugin for discovering and advertising networking resources Name: sriov-network-device-plugin Version: 3.6.2 -Release: 4%{?dist} +Release: 5%{?dist} License: MIT Vendor: Microsoft Corporation Distribution: Mariner @@ -35,6 +35,9 @@ install -D -m0755 images/ddptool-1.0.1.12.tar.gz %{buildroot}%{_datadir}/%{name} %{_datadir}/%{name}/ddptool-1.0.1.12.tar.gz %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 3.6.2-5 +- Bump release to rebuild with go 1.22.7 + * Thu Jun 06 2024 CBL-Mariner Servicing Account - 3.6.2-4 - Bump release to rebuild with go 1.21.11 diff --git a/SPECS/sysstat/CVE-2023-33204.patch b/SPECS/sysstat/CVE-2023-33204.patch deleted file mode 100644 index a68cd60725d..00000000000 --- a/SPECS/sysstat/CVE-2023-33204.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 129e0d6154eadd1ace56896897f69c18b396fa7f Mon Sep 17 00:00:00 2001 -From: Rachel Menge -Date: Fri, 26 May 2023 11:28:28 -0700 -Subject: [PATCH] Patch to address CVE-2023-33204 Rachel Menge - (rachelmenge@microsoft.com) - -From 954ff2e2673cef48f0ed44668c466eab041db387 Mon Sep 17 00:00:00 2001 -From: Pavel Kopylov -Date: Wed, 17 May 2023 11:33:45 +0200 -Subject: [PATCH] Fix an overflow which is still possible for some values. ---- - common.c | 16 +++++++++------- - 1 file changed, 9 insertions(+), 7 deletions(-) - -diff --git a/common.c b/common.c -index 3b7fdcd..f02d34a 100644 ---- a/common.c -+++ b/common.c -@@ -428,15 +428,17 @@ int check_dir(char *dirname) - void check_overflow(unsigned int val1, unsigned int val2, - unsigned int val3) - { -- if ((unsigned long long) val1 * (unsigned long long) val2 * -- (unsigned long long) val3 > UINT_MAX) { -+ if ((val1 != 0) && (val2 != 0) && (val3 != 0) && -+ (((unsigned long long) UINT_MAX / (unsigned long long) val1 < -+ (unsigned long long) val2) || -+ ((unsigned long long) UINT_MAX / ((unsigned long long) val1 * (unsigned long long) val2) < -+ (unsigned long long) val3))) { - #ifdef DEBUG -- fprintf(stderr, "%s: Overflow detected (%llu). Aborting...\n", -- __FUNCTION__, (unsigned long long) val1 * (unsigned long long) val2 * -- (unsigned long long) val3); -+ fprintf(stderr, "%s: Overflow detected (%u,%u,%u). Aborting...\n", -+ __FUNCTION__, val1, val2, val3); - #endif -- exit(4); -- } -+ exit(4); -+ } - } - - #ifndef SOURCE_SADC --- -2.17.1 - diff --git a/SPECS/sysstat/sysstat.signatures.json b/SPECS/sysstat/sysstat.signatures.json index c0dcf9fe917..eb0b6ad76f0 100644 --- a/SPECS/sysstat/sysstat.signatures.json +++ b/SPECS/sysstat/sysstat.signatures.json @@ -1,5 +1,5 @@ { "Signatures": { - "sysstat-12.7.1.tar.gz": "d53698c7a15c307a3debb84607891c2be21e3bcfcb31f0fdab78394b689b2bdf" + "sysstat-12.7.6.tar.gz": "dc77a08871f8e8813448ea31048833d4acbab7276dd9a456cd2526c008bd5301" } } \ No newline at end of file diff --git a/SPECS/sysstat/sysstat.spec b/SPECS/sysstat/sysstat.spec index 3fb29f15e30..896cda371ef 100644 --- a/SPECS/sysstat/sysstat.spec +++ b/SPECS/sysstat/sysstat.spec @@ -1,14 +1,13 @@ Summary: The Sysstat package contains utilities to monitor system performance and usage activity Name: sysstat -Version: 12.7.1 -Release: 3%{?dist} +Version: 12.7.6 +Release: 1%{?dist} License: GPL-2.0-only URL: http://sebastien.godard.pagesperso-orange.fr/ Group: Development/Debuggers Vendor: Microsoft Corporation Distribution: Mariner Source0: https://github.com/%{name}/%{name}/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz -Patch0: CVE-2023-33204.patch BuildRequires: cronie-anacron @@ -54,6 +53,10 @@ install -D -m 0644 %{_builddir}/%{name}-%{version}/cron/sysstat-collect.service %changelog +* Fri Aug 23 2024 Muhammad Falak - 12.7.6-1 +- Bump version to 12.7.6 to address CVE-2018-19416 +- Drop patches already present in the source + * Wed Sep 20 2023 Jon Slobodzian - 12.7.1-3 - Recompile with stack-protection fixed gcc version (CVE-2023-4039) diff --git a/SPECS/telegraf/CVE-2024-24786.patch b/SPECS/telegraf/CVE-2024-24786.patch new file mode 100644 index 00000000000..e1a521ef33c --- /dev/null +++ b/SPECS/telegraf/CVE-2024-24786.patch @@ -0,0 +1,53 @@ +From f01a588e5810b90996452eec4a28f22a0afae023 Mon Sep 17 00:00:00 2001 +From: Damien Neil +Date: Tue, 05 Mar 2024 08:54:24 -0800 +Subject: [PATCH] encoding/protojson, internal/encoding/json: handle missing object values + +In internal/encoding/json, report an error when encountering a } +when we are expecting an object field value. For example, the input +`{"":}` now correctly results in an error at the closing } token. + +In encoding/protojson, check for an unexpected EOF token in +skipJSONValue. This is redundant with the check in internal/encoding/json, +but adds a bit more defense against any other similar bugs that +might exist. + +Fixes CVE-2024-24786 + +Change-Id: I03d52512acb5091c8549e31ca74541d57e56c99d +Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/569356 +TryBot-Bypass: Damien Neil +Reviewed-by: Roland Shoemaker +Commit-Queue: Damien Neil +Signed-off-by: Henry Beberman +Signed-off-by: Muhammad Falak R Wani +--- + +diff --git a/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go b/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go +index 25329b7..4b177c8 100644 +--- a/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go ++++ b/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go +@@ -322,6 +322,10 @@ + if open > d.opts.RecursionLimit { + return errors.New("exceeded max recursion depth") + } ++ case json.EOF: ++ // This can only happen if there's a bug in Decoder.Read. ++ // Avoid an infinite loop if this does happen. ++ return errors.New("unexpected EOF") + } + if open == 0 { + return nil +diff --git a/vendor/google.golang.org/protobuf/internal/encoding/json/decode.go b/vendor/google.golang.org/protobuf/internal/encoding/json/decode.go +index d043a6e..d2b3ac0 100644 +--- a/vendor/google.golang.org/protobuf/internal/encoding/json/decode.go ++++ b/vendor/google.golang.org/protobuf/internal/encoding/json/decode.go +@@ -121,7 +121,7 @@ + + case ObjectClose: + if len(d.openStack) == 0 || +- d.lastToken.kind == comma || ++ d.lastToken.kind&(Name|comma) != 0 || + d.openStack[len(d.openStack)-1] != ObjectOpen { + return Token{}, d.newSyntaxError(tok.pos, unexpectedFmt, tok.RawString()) + } diff --git a/SPECS/telegraf/CVE-2024-28180.patch b/SPECS/telegraf/CVE-2024-28180.patch new file mode 100644 index 00000000000..740072c364c --- /dev/null +++ b/SPECS/telegraf/CVE-2024-28180.patch @@ -0,0 +1,76 @@ +diff --git a/vendor/gopkg.in/square/go-jose.v2/crypter.go b/vendor/gopkg.in/square/go-jose.v2/crypter.go +index d24cabf..a628386 100644 +--- a/vendor/gopkg.in/square/go-jose.v2/crypter.go ++++ b/vendor/gopkg.in/square/go-jose.v2/crypter.go +@@ -405,6 +405,9 @@ func (ctx *genericEncrypter) Options() EncrypterOptions { + // Decrypt and validate the object and return the plaintext. Note that this + // function does not support multi-recipient, if you desire multi-recipient + // decryption use DecryptMulti instead. ++// ++// Automatically decompresses plaintext, but returns an error if the decompressed ++// data would be >250kB or >10x the size of the compressed data, whichever is larger. + func (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error) { + headers := obj.mergedHeaders(nil) + +@@ -469,6 +472,9 @@ func (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error) + // with support for multiple recipients. It returns the index of the recipient + // for which the decryption was successful, the merged headers for that recipient, + // and the plaintext. ++// ++// Automatically decompresses plaintext, but returns an error if the decompressed ++// data would be >250kB or >3x the size of the compressed data, whichever is larger. + func (obj JSONWebEncryption) DecryptMulti(decryptionKey interface{}) (int, Header, []byte, error) { + globalHeaders := obj.mergedHeaders(nil) + +diff --git a/vendor/gopkg.in/square/go-jose.v2/encoding.go b/vendor/gopkg.in/square/go-jose.v2/encoding.go +index 70f7385..ab9e086 100644 +--- a/vendor/gopkg.in/square/go-jose.v2/encoding.go ++++ b/vendor/gopkg.in/square/go-jose.v2/encoding.go +@@ -21,6 +21,7 @@ import ( + "compress/flate" + "encoding/base64" + "encoding/binary" ++ "fmt" + "io" + "math/big" + "strings" +@@ -85,7 +86,7 @@ func decompress(algorithm CompressionAlgorithm, input []byte) ([]byte, error) { + } + } + +-// Compress with DEFLATE ++// deflate compresses the input. + func deflate(input []byte) ([]byte, error) { + output := new(bytes.Buffer) + +@@ -97,15 +98,27 @@ func deflate(input []byte) ([]byte, error) { + return output.Bytes(), err + } + +-// Decompress with DEFLATE ++// inflate decompresses the input. ++// ++// Errors if the decompressed data would be >250kB or >10x the size of the ++// compressed data, whichever is larger. + func inflate(input []byte) ([]byte, error) { + output := new(bytes.Buffer) + reader := flate.NewReader(bytes.NewBuffer(input)) + +- _, err := io.Copy(output, reader) +- if err != nil { ++ maxCompressedSize := 10 * int64(len(input)) ++ if maxCompressedSize < 250000 { ++ maxCompressedSize = 250000 ++ } ++ ++ limit := maxCompressedSize + 1 ++ n, err := io.CopyN(output, reader, limit) ++ if err != nil && err != io.EOF { + return nil, err + } ++ if n == limit { ++ return nil, fmt.Errorf("uncompressed data would be too large (>%d bytes)", maxCompressedSize) ++ } + + err = reader.Close() + return output.Bytes(), err diff --git a/SPECS/telegraf/telegraf.spec b/SPECS/telegraf/telegraf.spec index 416fb8b1954..2a71676daa0 100644 --- a/SPECS/telegraf/telegraf.spec +++ b/SPECS/telegraf/telegraf.spec @@ -1,20 +1,22 @@ Summary: agent for collecting, processing, aggregating, and writing metrics. Name: telegraf Version: 1.29.4 -Release: 7%{?dist} +Release: 9%{?dist} License: MIT Vendor: Microsoft Corporation Distribution: Mariner Group: Development/Tools URL: https://github.com/influxdata/telegraf Source0: %{url}/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz -# Use the generate_source_tarbbal.sh script to get the vendored sources. +# Use the generate_source_tarball.sh script to get the vendored sources. Source1: %{name}-%{version}-vendor.tar.gz Patch0: CVE-2023-45288.patch Patch1: CVE-2024-28110.patch Patch2: CVE-2024-27289.patch Patch3: CVE-2024-35255.patch Patch4: CVE-2024-37298.patch +Patch5: CVE-2024-24786.patch +Patch6: CVE-2024-28180.patch BuildRequires: golang BuildRequires: iana-etc BuildRequires: systemd-devel @@ -85,6 +87,12 @@ fi %dir %{_sysconfdir}/%{name}/telegraf.d %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 1.29.4-9 +- Bump release to rebuild with go 1.22.7 + +* Wed Aug 21 2024 Muhammad Falak - 1.29.4-8 +- Address CVE-2024-24786 & CVE-2024-28180 + * Thu Jul 11 2024 Sumedh Sharma - 1.29.4-7 - Add patch for CVE-2024-37298 diff --git a/SPECS/terraform/terraform.spec b/SPECS/terraform/terraform.spec index d347de8d122..6f227491d64 100644 --- a/SPECS/terraform/terraform.spec +++ b/SPECS/terraform/terraform.spec @@ -1,7 +1,7 @@ Summary: Infrastructure as code deployment management tool Name: terraform Version: 1.3.2 -Release: 17%{?dist} +Release: 18%{?dist} License: MPLv2.0 Vendor: Microsoft Corporation Distribution: Mariner @@ -65,6 +65,9 @@ install -p -m 755 -t %{buildroot}%{_bindir} ./terraform %{_bindir}/terraform %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 1.3.2-18 +- Bump release to rebuild with go 1.22.7 + * Thu Jul 25 2024 Sumedh Sharma - 1.3.2-17 - Patch CVE-2024-6257 in vendored hashicorp/go-getter diff --git a/SPECS/tpm2-tss/CVE-2024-29040.patch b/SPECS/tpm2-tss/CVE-2024-29040.patch new file mode 100644 index 00000000000..e079b5c6e38 --- /dev/null +++ b/SPECS/tpm2-tss/CVE-2024-29040.patch @@ -0,0 +1,109 @@ +From 710cd0b6adf3a063f34a8e92da46df7a107d9a99 Mon Sep 17 00:00:00 2001 +From: Juergen Repp +Date: Tue, 31 Oct 2023 11:08:41 +0100 +Subject: [PATCH] FAPI: Fix check of magic number in verify quote. + +After deserializing the quote info it was not checked whether +the magic number in the attest is equal TPM2_GENERATED_VALUE. +So an malicious attacker could generate arbitrary quote data +which was not detected by Fapi_VerifyQuote. +Now the number magic number is checket in verify quote and also +in the deserialization of TPM2_GENERATED. +The check is also added to the Unmarshal function for TPMS_ATTEST. + +Fixes: CVE-2024-29040 + +Signed-off-by: Juergen Repp +Signed-off-by: Andreas Fuchs +--- + src/tss2-fapi/api/Fapi_VerifyQuote.c | 5 +++++ + src/tss2-fapi/tpm_json_deserialize.c | 11 +++++++++-- + src/tss2-mu/tpms-types.c | 23 ++++++++++++++++++++++- + 3 files changed, 36 insertions(+), 3 deletions(-) + +diff --git a/src/tss2-fapi/api/Fapi_VerifyQuote.c b/src/tss2-fapi/api/Fapi_VerifyQuote.c +index 8a0e119cc..50474c6bb 100644 +--- a/src/tss2-fapi/api/Fapi_VerifyQuote.c ++++ b/src/tss2-fapi/api/Fapi_VerifyQuote.c +@@ -289,6 +289,11 @@ Fapi_VerifyQuote_Finish( + &command->fapi_quote_info); + goto_if_error(r, "Get quote info.", error_cleanup); + ++ if (command->fapi_quote_info.attest.magic != TPM2_GENERATED_VALUE) { ++ goto_error(r, TSS2_FAPI_RC_SIGNATURE_VERIFICATION_FAILED, ++ "Attest without TPM2 generated value", error_cleanup); ++ } ++ + /* Verify the signature over the attest2b structure. */ + r = ifapi_verify_signature_quote(&key_object, + command->signature, +diff --git a/src/tss2-fapi/tpm_json_deserialize.c b/src/tss2-fapi/tpm_json_deserialize.c +index 4c45458a6..1b27a83fd 100644 +--- a/src/tss2-fapi/tpm_json_deserialize.c ++++ b/src/tss2-fapi/tpm_json_deserialize.c +@@ -698,6 +698,7 @@ ifapi_json_TPM2_GENERATED_deserialize(json_object *jso, TPM2_GENERATED *out) + const char *s = json_object_get_string(jso); + const char *str = strip_prefix(s, "TPM_", "TPM2_", "GENERATED_", NULL); + LOG_TRACE("called for %s parsing %s", s, str); ++ TSS2_RC r; + + if (str) { + for (size_t i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) { +@@ -707,8 +708,14 @@ ifapi_json_TPM2_GENERATED_deserialize(json_object *jso, TPM2_GENERATED *out) + } + } + } +- +- return ifapi_json_UINT32_deserialize(jso, out); ++ r = ifapi_json_UINT32_deserialize(jso, out); ++ return_if_error(r, "Could not deserialize UINT32"); ++ if (*out != TPM2_GENERATED_VALUE) { ++ return_error2(TSS2_FAPI_RC_BAD_VALUE, ++ "Value %x not equal TPM self generated value %x", ++ *out, TPM2_GENERATED_VALUE); ++ } ++ return TSS2_RC_SUCCESS; + } + + /** Deserialize a TPM2_ALG_ID json object. +diff --git a/src/tss2-mu/tpms-types.c b/src/tss2-mu/tpms-types.c +index 3ad725203..56aca0c33 100644 +--- a/src/tss2-mu/tpms-types.c ++++ b/src/tss2-mu/tpms-types.c +@@ -22,6 +22,27 @@ + #define VAL + #define TAB_SIZE(tab) (sizeof(tab) / sizeof(tab[0])) + ++static TSS2_RC ++TPM2_GENERATED_Unmarshal( ++ uint8_t const buffer[], ++ size_t buffer_size, ++ size_t *offset, ++ TPM2_GENERATED *magic) ++{ ++ TPM2_GENERATED mymagic = 0; ++ TSS2_RC rc = Tss2_MU_UINT32_Unmarshal(buffer, buffer_size, offset, &mymagic); ++ if (rc != TSS2_RC_SUCCESS) { ++ return rc; ++ } ++ if (mymagic != TPM2_GENERATED_VALUE) { ++ LOG_ERROR("Bad magic in tpms_attest"); ++ return TSS2_SYS_RC_BAD_VALUE; ++ } ++ if (magic != NULL) ++ *magic = mymagic; ++ return TSS2_RC_SUCCESS; ++} ++ + #define TPMS_PCR_MARSHAL(type, firstFieldMarshal) \ + TSS2_RC \ + Tss2_MU_##type##_Marshal(const type *src, uint8_t buffer[], \ +@@ -1219,7 +1240,7 @@ TPMS_MARSHAL_7_U(TPMS_ATTEST, + attested, ADDR, Tss2_MU_TPMU_ATTEST_Marshal) + + TPMS_UNMARSHAL_7_U(TPMS_ATTEST, +- magic, Tss2_MU_UINT32_Unmarshal, ++ magic, TPM2_GENERATED_Unmarshal, + type, Tss2_MU_TPM2_ST_Unmarshal, + qualifiedSigner, Tss2_MU_TPM2B_NAME_Unmarshal, + extraData, Tss2_MU_TPM2B_DATA_Unmarshal, diff --git a/SPECS/tpm2-tss/tpm2-tss.spec b/SPECS/tpm2-tss/tpm2-tss.spec index 5fd9a2e0e68..da628a9c267 100644 --- a/SPECS/tpm2-tss/tpm2-tss.spec +++ b/SPECS/tpm2-tss/tpm2-tss.spec @@ -1,7 +1,7 @@ Summary: OSS implementation of the TCG TPM2 Software Stack (TSS2) Name: tpm2-tss Version: 2.4.6 -Release: 3%{?dist} +Release: 4%{?dist} License: BSD Vendor: Microsoft Corporation Distribution: Mariner @@ -9,6 +9,8 @@ Group: System Environment/Security URL: https://github.com/tpm2-software/tpm2-tss Source0: https://github.com/tpm2-software/tpm2-tss/releases/download/%{version}/%{name}-%{version}.tar.gz Patch0: CVE-2023-22745.patch +Patch1: CVE-2024-29040.patch + BuildRequires: json-c-devel BuildRequires: openssl-devel Requires: json-c @@ -89,6 +91,9 @@ fi %{_mandir}/man7/* %changelog +* Fri Aug 09 2024 Sumedh Sharma - 2.4.6-4 +- Add patch to resolve CVE-2024-29040 + * Wed Sep 20 2023 Jon Slobodzian - 2.4.6-3 - Recompile with stack-protection fixed gcc version (CVE-2023-4039) diff --git a/SPECS/trace-cmd/98-trace-cmd.rules b/SPECS/trace-cmd/98-trace-cmd.rules new file mode 100644 index 00000000000..9575bd819a8 --- /dev/null +++ b/SPECS/trace-cmd/98-trace-cmd.rules @@ -0,0 +1 @@ +SUBSYSTEM=="module", ACTION=="add", PROGRAM="/usr/bin/systemctl is-active trace-cmd.service", PROGRAM="/usr/bin/systemctl reload trace-cmd.service" diff --git a/SPECS/trace-cmd/trace-cmd.conf b/SPECS/trace-cmd/trace-cmd.conf new file mode 100644 index 00000000000..85c4fbee3c1 --- /dev/null +++ b/SPECS/trace-cmd/trace-cmd.conf @@ -0,0 +1,4 @@ +# ftrace based flightrecorder configuration file. + +# trace-cmd options +OPTS="-b 2048 -i -e block -e irq -e mce -e module -e power -e sched -e signal -e timer -e workqueue -e kvm -e net" diff --git a/SPECS/trace-cmd/trace-cmd.service b/SPECS/trace-cmd/trace-cmd.service new file mode 100644 index 00000000000..27b07f5e4f8 --- /dev/null +++ b/SPECS/trace-cmd/trace-cmd.service @@ -0,0 +1,15 @@ +[Unit] +Description=trace-cmd Flightrecorder +DefaultDependencies=no +Before=sysinit.target + +[Service] +Type=oneshot +RemainAfterExit=yes +EnvironmentFile=/etc/sysconfig/trace-cmd.conf +ExecStart=/usr/bin/trace-cmd start $OPTS +ExecStop=/usr/bin/trace-cmd reset +ExecReload=/usr/bin/trace-cmd start $OPTS + +[Install] +WantedBy=multi-user.target diff --git a/SPECS/trace-cmd/trace-cmd.signatures.json b/SPECS/trace-cmd/trace-cmd.signatures.json new file mode 100644 index 00000000000..38b398cb6ad --- /dev/null +++ b/SPECS/trace-cmd/trace-cmd.signatures.json @@ -0,0 +1,8 @@ +{ + "Signatures": { + "trace-cmd-3.2.tar.gz": "62af2c6062eeb434925921bb5936774b0a0e17a5f86671fa2ea2f40704a080cd", + "98-trace-cmd.rules": "dfbcbe2a339715217d2777ccc74261a55417f87fe2aca849ed1c25f8d4a0f624", + "trace-cmd.conf": "c0b3d569dc5bb1095400f591747060cbdd7ef72a1abc0c0770b1fa308636e4f6", + "trace-cmd.service": "e72fe5edaf40e8a89e2912ca2b4da3b0b30a2078dabcc8d8e75604a0c3969bac" + } +} diff --git a/SPECS/trace-cmd/trace-cmd.spec b/SPECS/trace-cmd/trace-cmd.spec new file mode 100644 index 00000000000..af82ac15fab --- /dev/null +++ b/SPECS/trace-cmd/trace-cmd.spec @@ -0,0 +1,111 @@ +# git tag +#%%global git_commit trace-cmd-v2.6.2 +#%%global git_commit 57371aaa2f469d0ba15fd85276deca7bfdd7ce36 + +Name: trace-cmd +Version: 3.2 +Release: 2%{?dist} +License: LGPL-2.1-only AND LGPL-2.1-or-later AND GPL-2.0-only AND GPL-2.0-or-later +Vendor: Microsoft Corporation +Distribution: Mariner +Summary: A user interface to Ftrace + +ExcludeArch: %{ix86} %{arm} + +# If upstream does not provide tarballs, to generate: +# git clone https://git.kernel.org/pub/scm/utils/trace-cmd/trace-cmd.git +# cd trace-cmd +# git archive --prefix=trace-cmd-%%{version}/ -o trace-cmd-v%%{version}.tar.gz %%{git_commit} +URL: http://git.kernel.org/?p=linux/kernel/git/rostedt/trace-cmd.git;a=summary +Source0: https://git.kernel.org/pub/scm/utils/trace-cmd/trace-cmd.git/snapshot/trace-cmd-v%{version}.tar.gz#/%{name}-%{version}.tar.gz +Source1: trace-cmd.conf +Source2: trace-cmd.service +Source3: 98-trace-cmd.rules + +BuildRequires: make +BuildRequires: gcc +BuildRequires: xmlto +BuildRequires: asciidoc +BuildRequires: mlocate +BuildRequires: graphviz doxygen +BuildRequires: gcc-c++ +BuildRequires: cmake +BuildRequires: libtraceevent-devel >= 1.8.0 +BuildRequires: libtracefs-devel >= 1.8.0 +BuildRequires: audit-libs-devel +BuildRequires: chrpath +BuildRequires: swig +BuildRequires: systemd-rpm-macros +BuildRequires: libtracecmd-devel +BuildRequires: libzstd-devel + +%description +trace-cmd is a user interface to Ftrace. Instead of needing to use the +debugfs directly, trace-cmd will handle of setting of options and +tracers and will record into a data file. + +%package python3 +Summary: Python plugin support for trace-cmd +Requires: trace-cmd%{_isa} = %{version}-%{release} +BuildRequires: python3-devel + +%description python3 +Python plugin support for trace-cmd + +%prep +%autosetup -n %{name}-v%{version} +cp %{SOURCE1} . +cp %{SOURCE2} . +cp %{SOURCE3} . + +%build +# MANPAGE_DOCBOOK_XSL define is hack to avoid using locate +MANPAGE_DOCBOOK_XSL=`rpm -ql docbook-style-xsl | grep manpages/docbook.xsl` +CFLAGS="%{optflags} -D_GNU_SOURCE" LDFLAGS="%{build_ldflags}" BUILD_TYPE=Release \ + make V=9999999999 MANPAGE_DOCBOOK_XSL=$MANPAGE_DOCBOOK_XSL \ + prefix=%{_prefix} libdir=%{_libdir} \ + PYTHON_VERS=python3 all_cmd doc +for i in python/*.py ; do + sed -i 's/env python2/python3/g' $i +done +chrpath --delete tracecmd/trace-cmd + +%install +make libdir=%{_libdir} prefix=%{_prefix} PYTHON_VERS=python3 V=1 DESTDIR=%{buildroot}/ CFLAGS="%{optflags} -D_GNU_SOURCE" LDFLAGS="%{build_ldflags} -z muldefs " BUILD_TYPE=Release install install_doc install_python +find %{buildroot}%{_mandir} -type f | xargs chmod u-x,g-x,o-x +find %{buildroot}%{_datadir} -type f | xargs chmod u-x,g-x,o-x +find %{buildroot}%{_libdir} -type f -iname "*.so" | xargs chmod 0755 +mkdir -p -m755 %{buildroot}/%{_sysconfdir}/sysconfig/ +mkdir -p -m755 %{buildroot}/%{_unitdir}/ +mkdir -p -m755 %{buildroot}/%{_udevrulesdir}/ +install -p -m 644 trace-cmd.conf %{buildroot}/%{_sysconfdir}/sysconfig/ +install -p -m 644 trace-cmd.service %{buildroot}/%{_unitdir}/ +install -p -m 644 98-trace-cmd.rules %{buildroot}/%{_udevrulesdir}/ +rm -rf %{buildroot}/%{_docdir}/libtracecmd-doc +rm -rf %{buildroot}/%{_mandir}/man3/* + +%preun +%systemd_preun %{name}.service + +%files +%doc COPYING COPYING.LIB README +%{_bindir}/trace-cmd +%{_mandir}/man1/%{name}* +%{_mandir}/man5/%{name}* +%{_docdir}/trace-cmd/trace-cmd*.html +%{_sysconfdir}/bash_completion.d/trace-cmd.bash +%{_sysconfdir}/sysconfig/trace-cmd.conf +%{_unitdir}/trace-cmd.service +%{_udevrulesdir}/98-trace-cmd.rules + +%files python3 +%doc Documentation/README.PythonPlugin +%{_libdir}/%{name}/python/ + +%changelog +* Thu Aug 29 2024 Henry Beberman - 3.2-2 +- Backport from Azure Linux 3.0 + +* Mon Feb 12 2024 Aadhar Agarwal - 3.2-1 +- Initial CBL-Mariner import from Fedora 40 (license: MIT) +- License Verified diff --git a/SPECS/vim/CVE-2024-41957.patch b/SPECS/vim/CVE-2024-41957.patch new file mode 100644 index 00000000000..40d9bd2c298 --- /dev/null +++ b/SPECS/vim/CVE-2024-41957.patch @@ -0,0 +1,81 @@ +Modified patch to apply to older version +Modifed by: sumsharma@microsoft.com + +From 8a0bbe7b8aad6f8da28dee218c01bc8a0185a2d5 Mon Sep 17 00:00:00 2001 +From: Christian Brabandt +Date: Thu, 1 Aug 2024 20:16:51 +0200 +Subject: [PATCH] patch 9.1.0647: [security] use-after-free in + tagstack_clear_entry + +Problem: [security] use-after-free in tagstack_clear_entry + (Suyue Guo ) +Solution: Instead of manually calling vim_free() on each of the tagstack + entries, let's use tagstack_clear_entry(), which will + also free the stack, but using the VIM_CLEAR macro, + which prevents a use-after-free by setting those pointers + to NULL + +This addresses CVE-2024-41957 + +Github advisory: +https://github.com/vim/vim/security/advisories/GHSA-f9cr-gv85-hcr4 + +Signed-off-by: Christian Brabandt +--- + src/proto/tag.pro | 1 + + src/tag.c | 4 ++-- + src/window.c | 6 ++---- + 3 files changed, 5 insertions(+), 6 deletions(-) + +diff --git a/src/proto/tag.pro b/src/proto/tag.pro +index 6de463e..eec7c24 100644 +--- a/src/proto/tag.pro ++++ b/src/proto/tag.pro +@@ -14,4 +14,5 @@ int expand_tags(int tagnames, char_u *pat, int *num_file, char_u ***file); + int get_tags(list_T *list, char_u *pat, char_u *buf_fname); + void get_tagstack(win_T *wp, dict_T *retdict); + int set_tagstack(win_T *wp, dict_T *d, int action); ++void tagstack_clear_entry(taggy_T *item); + /* vim: set ft=c : */ +diff --git a/src/tag.c b/src/tag.c +index 8003156..31b89e7 100644 +--- a/src/tag.c ++++ b/src/tag.c +@@ -144,7 +144,7 @@ static void print_tag_list(int new_tag, int use_tagstack, int num_matches, char_ + #if defined(FEAT_QUICKFIX) && defined(FEAT_EVAL) + static int add_llist_tags(char_u *tag, int num_matches, char_u **matches); + #endif +-static void tagstack_clear_entry(taggy_T *item); ++void tagstack_clear_entry(taggy_T *item); + + static char_u *tagmatchname = NULL; // name of last used tag + +@@ -4225,7 +4225,7 @@ find_extra(char_u **pp) + /* + * Free a single entry in a tag stack + */ +- static void ++void + tagstack_clear_entry(taggy_T *item) + { + VIM_CLEAR(item->tagname); +diff --git a/src/window.c b/src/window.c +index 55ce31c..ffffde8 100644 +--- a/src/window.c ++++ b/src/window.c +@@ -5661,10 +5661,8 @@ win_free( + win_free_lsize(wp); + + for (i = 0; i < wp->w_tagstacklen; ++i) +- { +- vim_free(wp->w_tagstack[i].tagname); +- vim_free(wp->w_tagstack[i].user_data); +- } ++ tagstack_clear_entry(&wp->w_tagstack[i]); ++ + vim_free(wp->w_localdir); + vim_free(wp->w_prevdir); + +-- +2.25.1 + diff --git a/SPECS/vim/CVE-2024-41965.patch b/SPECS/vim/CVE-2024-41965.patch new file mode 100644 index 00000000000..ed2e0a7b62b --- /dev/null +++ b/SPECS/vim/CVE-2024-41965.patch @@ -0,0 +1,69 @@ +Modified patch to apply to older version of vim +Modified by: sumsharma@microsoft.com + +From b29f4abcd4b3382fa746edd1d0562b7b48c9de60 Mon Sep 17 00:00:00 2001 +From: Christian Brabandt +Date: Thu, 1 Aug 2024 22:10:28 +0200 +Subject: [PATCH] patch 9.1.0648: [security] double-free in dialog_changed() + +Problem: [security] double-free in dialog_changed() + (SuyueGuo) +Solution: Only clear pointer b_sfname pointer, if it is different + than the b_ffname pointer. Don't try to free b_fname, + set it to NULL instead. + +fixes: #15403 + +Github Advisory: +https://github.com/vim/vim/security/advisories/GHSA-46pw-v7qw-xc2f + +Signed-off-by: Christian Brabandt +--- +--- + src/ex_cmds2.c | 25 ++++++++++++++++++++++--- + 1 file changed, 22 insertions(+), 3 deletions(-) + +diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c +index 45ccb52..ede403a 100644 +--- a/src/ex_cmds2.c ++++ b/src/ex_cmds2.c +@@ -177,14 +177,33 @@ dialog_changed( + + if (ret == VIM_YES) + { ++ int empty_bufname; ++ + #ifdef FEAT_BROWSE + // May get file name, when there is none + browse_save_fname(buf); + #endif +- if (buf->b_fname != NULL && check_overwrite(&ea, buf, +- buf->b_fname, buf->b_ffname, FALSE) == OK) ++ empty_bufname = buf->b_fname == NULL ? TRUE : FALSE; ++ if (empty_bufname) ++ buf_set_name(buf->b_fnum, (char_u *)"Untitled"); ++ ++ if (check_overwrite(&ea, buf, buf->b_fname, buf->b_ffname, FALSE) == OK) ++ { + // didn't hit Cancel +- (void)buf_write_all(buf, FALSE); ++ if (buf_write_all(buf, FALSE) == OK) ++ return; ++ } ++ ++ // restore to empty when write failed ++ if (empty_bufname) ++ { ++ // prevent double free ++ if (buf->b_sfname != buf->b_ffname) ++ VIM_CLEAR(buf->b_sfname); ++ buf->b_fname = NULL; ++ VIM_CLEAR(buf->b_ffname); ++ unchanged(buf, TRUE, FALSE); ++ } + } + else if (ret == VIM_NO) + { +-- +2.25.1 + diff --git a/SPECS/vim/CVE-2024-43374.patch b/SPECS/vim/CVE-2024-43374.patch new file mode 100644 index 00000000000..0687ccf6788 --- /dev/null +++ b/SPECS/vim/CVE-2024-43374.patch @@ -0,0 +1,282 @@ +From 0a6e57b09bc8c76691b367a5babfb79b31b770e8 Mon Sep 17 00:00:00 2001 +From: Christian Brabandt +Date: Thu, 15 Aug 2024 22:15:28 +0200 +Subject: [PATCH] patch 9.1.0678: [security]: use-after-free in alist_add() + +Problem: [security]: use-after-free in alist_add() + (SuyueGuo) +Solution: Lock the current window, so that the reference to + the argument list remains valid. + +This fixes CVE-2024-43374 + +Signed-off-by: Christian Brabandt +--- + src/arglist.c | 6 ++++++ + src/buffer.c | 4 ++-- + src/ex_cmds.c | 4 ++-- + src/proto/window.pro | 1 + + src/structs.h | 2 +- + src/terminal.c | 4 ++-- + src/testdir/test_arglist.vim | 23 +++++++++++++++++++++++ + src/version.c | 2 ++ + src/window.c | 29 +++++++++++++++++++---------- + 9 files changed, 58 insertions(+), 17 deletions(-) + +diff --git a/src/arglist.c b/src/arglist.c +index 187e16e8354b1..8825c8e252ccc 100644 +--- a/src/arglist.c ++++ b/src/arglist.c +@@ -184,6 +184,8 @@ alist_set( + /* + * Add file "fname" to argument list "al". + * "fname" must have been allocated and "al" must have been checked for room. ++ * ++ * May trigger Buf* autocommands + */ + void + alist_add( +@@ -196,6 +198,7 @@ alist_add( + if (check_arglist_locked() == FAIL) + return; + arglist_locked = TRUE; ++ curwin->w_locked = TRUE; + + #ifdef BACKSLASH_IN_FILENAME + slash_adjust(fname); +@@ -207,6 +210,7 @@ alist_add( + ++al->al_ga.ga_len; + + arglist_locked = FALSE; ++ curwin->w_locked = FALSE; + } + + #if defined(BACKSLASH_IN_FILENAME) || defined(PROTO) +@@ -365,6 +369,7 @@ alist_add_list( + mch_memmove(&(ARGLIST[after + count]), &(ARGLIST[after]), + (ARGCOUNT - after) * sizeof(aentry_T)); + arglist_locked = TRUE; ++ curwin->w_locked = TRUE; + for (i = 0; i < count; ++i) + { + int flags = BLN_LISTED | (will_edit ? BLN_CURBUF : 0); +@@ -373,6 +378,7 @@ alist_add_list( + ARGLIST[after + i].ae_fnum = buflist_add(files[i], flags); + } + arglist_locked = FALSE; ++ curwin->w_locked = FALSE; + ALIST(curwin)->al_ga.ga_len += count; + if (old_argcount > 0 && curwin->w_arg_idx >= after) + curwin->w_arg_idx += count; +diff --git a/src/buffer.c b/src/buffer.c +index 447ce76d49a32..34500e4abc282 100644 +--- a/src/buffer.c ++++ b/src/buffer.c +@@ -1484,7 +1484,7 @@ do_buffer_ext( + // (unless it's the only window). Repeat this so long as we end up in + // a window with this buffer. + while (buf == curbuf +- && !(curwin->w_closing || curwin->w_buffer->b_locked > 0) ++ && !(win_locked(curwin) || curwin->w_buffer->b_locked > 0) + && (!ONE_WINDOW || first_tabpage->tp_next != NULL)) + { + if (win_close(curwin, FALSE) == FAIL) +@@ -5470,7 +5470,7 @@ ex_buffer_all(exarg_T *eap) + : wp->w_width != Columns) + || (had_tab > 0 && wp != firstwin)) + && !ONE_WINDOW +- && !(wp->w_closing || wp->w_buffer->b_locked > 0) ++ && !(win_locked(wp) || wp->w_buffer->b_locked > 0) + && !win_unlisted(wp)) + { + if (win_close(wp, FALSE) == FAIL) +diff --git a/src/ex_cmds.c b/src/ex_cmds.c +index 05778c8fd8b9c..349269a2bb8b6 100644 +--- a/src/ex_cmds.c ++++ b/src/ex_cmds.c +@@ -2840,7 +2840,7 @@ do_ecmd( + + // Set the w_closing flag to avoid that autocommands close the + // window. And set b_locked for the same reason. +- the_curwin->w_closing = TRUE; ++ the_curwin->w_locked = TRUE; + ++buf->b_locked; + + if (curbuf == old_curbuf.br_buf) +@@ -2854,7 +2854,7 @@ do_ecmd( + + // Autocommands may have closed the window. + if (win_valid(the_curwin)) +- the_curwin->w_closing = FALSE; ++ the_curwin->w_locked = FALSE; + --buf->b_locked; + + #ifdef FEAT_EVAL +diff --git a/src/proto/window.pro b/src/proto/window.pro +index 26c7040b8a1b4..441070ebfcb8e 100644 +--- a/src/proto/window.pro ++++ b/src/proto/window.pro +@@ -93,3 +93,4 @@ int get_win_number(win_T *wp, win_T *first_win); + int get_tab_number(tabpage_T *tp); + char *check_colorcolumn(win_T *wp); ++int win_locked(win_T *wp); + /* vim: set ft=c : */ +diff --git a/src/structs.h b/src/structs.h +index fe4704a367949..abda3a0c38b4e 100644 +--- a/src/structs.h ++++ b/src/structs.h +@@ -3785,7 +3785,7 @@ struct window_S + synblock_T *w_s; // for :ownsyntax + #endif + +- int w_closing; // window is being closed, don't let ++ int w_locked; // window is being closed, don't let + // autocommands close it too. + + frame_T *w_frame; // frame containing this window +diff --git a/src/terminal.c b/src/terminal.c +index 1fc0ef96881f9..f80196096df49 100644 +--- a/src/terminal.c ++++ b/src/terminal.c +@@ -3680,10 +3680,10 @@ term_after_channel_closed(term_T *term) + if (is_aucmd_win(curwin)) + do_set_w_closing = TRUE; + if (do_set_w_closing) +- curwin->w_closing = TRUE; ++ curwin->w_locked = TRUE; + do_bufdel(DOBUF_WIPE, (char_u *)"", 1, fnum, fnum, FALSE); + if (do_set_w_closing) +- curwin->w_closing = FALSE; ++ curwin->w_locked = FALSE; + aucmd_restbuf(&aco); + } + #ifdef FEAT_PROP_POPUP +diff --git a/src/testdir/test_arglist.vim b/src/testdir/test_arglist.vim +index edc8b77429e20..8d81a828b3e03 100644 +--- a/src/testdir/test_arglist.vim ++++ b/src/testdir/test_arglist.vim +@@ -359,6 +359,7 @@ func Test_argv() + call assert_equal('', argv(1, 100)) + call assert_equal([], argv(-1, 100)) + call assert_equal('', argv(10, -1)) ++ %argdelete + endfunc + + " Test for the :argedit command +@@ -744,4 +745,26 @@ func Test_all_command() + %bw! + endfunc + ++" Test for deleting buffer when creating an arglist. This was accessing freed ++" memory ++func Test_crash_arglist_uaf() ++ "%argdelete ++ new one ++ au BufAdd XUAFlocal :bw ++ "call assert_fails(':arglocal XUAFlocal', 'E163:') ++ arglocal XUAFlocal ++ au! BufAdd ++ bw! XUAFlocal ++ ++ au BufAdd XUAFlocal2 :bw ++ new two ++ new three ++ arglocal ++ argadd XUAFlocal2 Xfoobar ++ bw! XUAFlocal2 ++ bw! two ++ ++ au! BufAdd ++endfunc ++ + " vim: shiftwidth=2 sts=2 expandtab +diff --git a/src/window.c b/src/window.c +index 43a15e0561f2c..b2c90c7d64114 100644 +--- a/src/window.c ++++ b/src/window.c +@@ -2511,7 +2511,7 @@ close_windows( + for (wp = firstwin; wp != NULL && !ONE_WINDOW; ) + { + if (wp->w_buffer == buf && (!keep_curwin || wp != curwin) +- && !(wp->w_closing || wp->w_buffer->b_locked > 0)) ++ && !(win_locked(wp) || wp->w_buffer->b_locked > 0)) + { + if (win_close(wp, FALSE) == FAIL) + // If closing the window fails give up, to avoid looping +@@ -2532,7 +2532,7 @@ close_windows( + if (tp != curtab) + FOR_ALL_WINDOWS_IN_TAB(tp, wp) + if (wp->w_buffer == buf +- && !(wp->w_closing || wp->w_buffer->b_locked > 0)) ++ && !(win_locked(wp) || wp->w_buffer->b_locked > 0)) + { + win_close_othertab(wp, FALSE, tp); + +@@ -2654,10 +2654,10 @@ win_close_buffer(win_T *win, int action, int abort_if_last) + bufref_T bufref; + + set_bufref(&bufref, curbuf); +- win->w_closing = TRUE; ++ win->w_locked = TRUE; + close_buffer(win, win->w_buffer, action, abort_if_last, TRUE); + if (win_valid_any_tab(win)) +- win->w_closing = FALSE; ++ win->w_locked = FALSE; + // Make sure curbuf is valid. It can become invalid if 'bufhidden' is + // "wipe". + if (!bufref_valid(&bufref)) +@@ -2705,7 +2705,7 @@ win_close(win_T *win, int free_buf) + if (window_layout_locked(CMD_close)) + return FAIL; + +- if (win->w_closing || (win->w_buffer != NULL ++ if (win_locked(win) || (win->w_buffer != NULL + && win->w_buffer->b_locked > 0)) + return FAIL; // window is already being closed + if (win_unlisted(win)) +@@ -2754,19 +2754,19 @@ win_close(win_T *win, int free_buf) + other_buffer = TRUE; + if (!win_valid(win)) + return FAIL; +- win->w_closing = TRUE; ++ win->w_locked = TRUE; + apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf); + if (!win_valid(win)) + return FAIL; +- win->w_closing = FALSE; ++ win->w_locked = FALSE; + if (last_window()) + return FAIL; + } +- win->w_closing = TRUE; ++ win->w_locked = TRUE; + apply_autocmds(EVENT_WINLEAVE, NULL, NULL, FALSE, curbuf); + if (!win_valid(win)) + return FAIL; +- win->w_closing = FALSE; ++ win->w_locked = FALSE; + if (last_window()) + return FAIL; + #ifdef FEAT_EVAL +@@ -3346,7 +3346,7 @@ win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) + + // Get here with win->w_buffer == NULL when win_close() detects the tab + // page changed. +- if (win->w_closing || (win->w_buffer != NULL ++ if (win_locked(win) || (win->w_buffer != NULL + && win->w_buffer->b_locked > 0)) + return; // window is already being closed + +@@ -7808,3 +7808,12 @@ skip: + return NULL; // no error + } + #endif ++ ++/* ++ * Don't let autocommands close the given window ++ */ ++ int ++win_locked(win_T *wp) ++{ ++ return wp->w_locked; ++} diff --git a/SPECS/vim/vim.spec b/SPECS/vim/vim.spec index 1c1341ed621..83f6a49a1a2 100644 --- a/SPECS/vim/vim.spec +++ b/SPECS/vim/vim.spec @@ -2,7 +2,7 @@ Summary: Text editor Name: vim Version: 9.0.2121 -Release: 2%{?dist} +Release: 4%{?dist} License: Vim Vendor: Microsoft Corporation Distribution: Mariner @@ -10,6 +10,10 @@ Group: Applications/Editors URL: https://www.vim.org Source0: https://github.com/%{name}/%{name}/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz Patch0: CVE-2024-22667.patch +Patch1: CVE-2024-43374.patch +Patch2: CVE-2024-41957.patch +Patch3: CVE-2024-41965.patch + BuildRequires: ncurses-devel BuildRequires: python3-devel Requires(post): sed @@ -197,6 +201,12 @@ fi %{_bindir}/vimdiff %changelog +* Wed Sep 18 2024 Sumedh Sharma - 9.0.2121-4 +- Add patch to resolve CVE-2024-41957 & CVE-2024-41965 + +* Tue Aug 20 2024 Brian Fjeldstad - 9.0.2121-3 +- Patch CVE-2024-43374 + * Tue Feb 20 2024 Suresh Thelkar - 9.0.2121-2 - Patch CVE-2024-22667 diff --git a/SPECS/vitess/vitess.spec b/SPECS/vitess/vitess.spec index ecc827b076a..e4dbf783e91 100644 --- a/SPECS/vitess/vitess.spec +++ b/SPECS/vitess/vitess.spec @@ -3,7 +3,7 @@ Name: vitess Version: 17.0.7 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Database clustering system for horizontal scaling of MySQL # Upstream license specification: MIT and Apache-2.0 License: MIT and ASL 2.0 @@ -103,6 +103,9 @@ go check -t go/cmd \ %{_bindir}/* %changelog +* Mon Sep 09 2024 CBL-Mariner Servicing Account - 17.0.7-2 +- Bump release to rebuild with go 1.22.7 + * Tue Jun 11 2024 Sumedh Sharma - 17.0.7-1 - Bump version to 17.0.7 to address CVE-2024-32886 - Remove patches already fixed in sources diff --git a/SPECS/vte291/CVE-2024-37535.patch b/SPECS/vte291/CVE-2024-37535.patch index 14fdccf0dbb..2b379ef9fae 100644 --- a/SPECS/vte291/CVE-2024-37535.patch +++ b/SPECS/vte291/CVE-2024-37535.patch @@ -77,3 +77,61 @@ index 24bdd7184..48cae79c1 100644 catch (...) { -- + +From fd5511f24b7269195a7083f409244e9787c705dc Mon Sep 17 00:00:00 2001 +From: Christian Persch +Date: Sun, 2 Jun 2024 19:13:15 +0200 +Subject: [PATCH] emulation: Restrict resize request to sane numbers + +Fixes: https://gitlab.gnome.org/GNOME/vte/-/issues/2786 +--- + src/vteseq.cc | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +diff --git a/src/vteseq.cc b/src/vteseq.cc +index 2430054c..225c6a59 100644 +--- a/src/vteseq.cc ++++ b/src/vteseq.cc +@@ -216,9 +216,18 @@ Terminal::emit_bell() + /* Emit a "resize-window" signal. (Grid size.) */ + void + Terminal::emit_resize_window(guint columns, +- guint rows) +-{ +- _vte_debug_print(VTE_DEBUG_SIGNALS, "Emitting `resize-window'.\n"); ++ guint rows) ++{ ++ // Ignore resizes with excessive number of rows or columns, ++ // see https://gitlab.gnome.org/GNOME/vte/-/issues/2786 ++ if (columns < VTE_MIN_GRID_WIDTH || ++ columns > 511 || ++ rows < VTE_MIN_GRID_HEIGHT || ++ rows > 511) ++ return; ++ ++ _vte_debug_print(VTE_DEBUG_SIGNALS, "Emitting `resize-window' %d columns %d rows.\n", ++ columns, rows); + g_signal_emit(m_terminal, signals[SIGNAL_RESIZE_WINDOW], 0, columns, rows); + } + +@@ -4702,8 +4711,6 @@ Terminal::DECSLPP(vte::parser::Sequence const& seq) + else if (param < 24) + return; + +- _vte_debug_print(VTE_DEBUG_EMULATION, "Resizing to %d rows.\n", param); +- + emit_resize_window(m_column_count, param); + } + +@@ -9312,9 +9319,6 @@ Terminal::XTERM_WM(vte::parser::Sequence const& seq) + seq.collect(1, {&height, &width}); + + if (width != -1 && height != -1) { +- _vte_debug_print(VTE_DEBUG_EMULATION, +- "Resizing window to %d columns, %d rows.\n", +- width, height); + emit_resize_window(width, height); + } + break; +-- +2.34.1 diff --git a/SPECS/vte291/vte291.spec b/SPECS/vte291/vte291.spec index 29a03c8ab76..7ac109c80aa 100644 --- a/SPECS/vte291/vte291.spec +++ b/SPECS/vte291/vte291.spec @@ -11,7 +11,7 @@ Summary: Terminal emulator library Name: vte291 Version: 0.66.2 -Release: 3%{?dist} +Release: 4%{?dist} License: CC-BY AND GPLv2+ AND LGPLv2+ Vendor: Microsoft Corporation Distribution: Mariner @@ -119,6 +119,9 @@ sed -i -e "/^vte_systemduserunitdir =/s|vte_prefix|'/usr'|" meson.build %{_sysconfdir}/profile.d/vte.sh %changelog +* Thu Aug 29 2024 Neha Agarwal - 0.66.2-4 +- Apply correct patch for CVE-2024-37535 + * Thu Jun 13 2024 Neha Agarwal - 0.66.2-3 - Patch CVE-2024-37535 diff --git a/SPECS/xorg-x11-server/Avoid_possible_double-free_in_ProcRenderAddGlyphs.patch b/SPECS/xorg-x11-server/Avoid_possible_double-free_in_ProcRenderAddGlyphs.patch new file mode 100644 index 00000000000..99bfb87aedd --- /dev/null +++ b/SPECS/xorg-x11-server/Avoid_possible_double-free_in_ProcRenderAddGlyphs.patch @@ -0,0 +1,68 @@ +ProcRenderAddGlyphs() adds the glyph to the glyphset using AddGlyph() and +then frees it using FreeGlyph() to decrease the reference count, after +AddGlyph() has increased it. + +AddGlyph() however may chose to reuse an existing glyph if it's already +in the glyphSet, and free the glyph that was given, in which case the +caller function, ProcRenderAddGlyphs() will call FreeGlyph() on an +already freed glyph, as reported by ASan: + + READ of size 4 thread T0 + #0 in FreeGlyph xserver/render/glyph.c:252 + #1 in ProcRenderAddGlyphs xserver/render/render.c:1174 + #2 in Dispatch xserver/dix/dispatch.c:546 + #3 in dix_main xserver/dix/main.c:271 + #4 in main xserver/dix/stubmain.c:34 + #5 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 + #6 in __libc_start_main_impl ../csu/libc-start.c:360 + #7 (/usr/bin/Xwayland+0x44fe4) + Address is located 0 bytes inside of 64-byte region + freed by thread T0 here: + #0 in __interceptor_free libsanitizer/asan/asan_malloc_linux.cpp:52 + #1 in _dixFreeObjectWithPrivates xserver/dix/privates.c:538 + #2 in AddGlyph xserver/render/glyph.c:295 + #3 in ProcRenderAddGlyphs xserver/render/render.c:1173 + #4 in Dispatch xserver/dix/dispatch.c:546 + #5 in dix_main xserver/dix/main.c:271 + #6 in main xserver/dix/stubmain.c:34 + #7 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 + previously allocated by thread T0 here: + #0 in __interceptor_malloc libsanitizer/asan/asan_malloc_linux.cpp:69 + #1 in AllocateGlyph xserver/render/glyph.c:355 + #2 in ProcRenderAddGlyphs xserver/render/render.c:1085 + #3 in Dispatch xserver/dix/dispatch.c:546 + #4 in dix_main xserver/dix/main.c:271 + #5 in main xserver/dix/stubmain.c:34 + #6 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 + SUMMARY: AddressSanitizer: heap-use-after-free xserver/render/glyph.c:252 in FreeGlyph + +To avoid that, make sure not to free the given glyph in AddGlyph(). + +v2: Simplify the test using the boolean returned from AddGlyph() (Michel) +v3: Simplify even more by not freeing the glyph in AddGlyph() (Peter) + +Fixes: bdca6c3d + + - render: fix refcounting of glyphs during ProcRenderAddGlyphs +Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1659 +Signed-off-by: default avatarOlivier Fourdan +Part-of: +--- + render/glyph.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/render/glyph.c b/render/glyph.c +index d5fc5f3..f5069d4 100644 +--- a/render/glyph.c ++++ b/render/glyph.c +@@ -291,8 +291,6 @@ AddGlyph(GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id) + gr = FindGlyphRef(&globalGlyphs[glyphSet->fdepth], signature, + TRUE, glyph->sha1); + if (gr->glyph && gr->glyph != DeletedGlyph && gr->glyph != glyph) { +- FreeGlyphPicture(glyph); +- dixFreeObjectWithPrivates(glyph, PRIVATE_GLYPH); + glyph = gr->glyph; + } + else if (gr->glyph != glyph) { +-- +2.25.1 diff --git a/SPECS/xorg-x11-server/CVE-2024-0229.patch b/SPECS/xorg-x11-server/CVE-2024-0229.patch new file mode 100644 index 00000000000..1da189db963 --- /dev/null +++ b/SPECS/xorg-x11-server/CVE-2024-0229.patch @@ -0,0 +1,331 @@ +From ece23be888a93b741aa1209d1dbf64636109d6a5 Mon Sep 17 00:00:00 2001 +From: Peter Hutterer +Date: Mon, 18 Dec 2023 14:27:50 +1000 +Subject: [PATCH] dix: Allocate sufficient xEvents for our DeviceStateNotify + +If a device has both a button class and a key class and numButtons is +zero, we can get an OOB write due to event under-allocation. + +This function seems to assume a device has either keys or buttons, not +both. It has two virtually identical code paths, both of which assume +they're applying to the first event in the sequence. + +A device with both a key and button class triggered a logic bug - only +one xEvent was allocated but the deviceStateNotify pointer was pushed on +once per type. So effectively this logic code: + + int count = 1; + if (button && nbuttons > 32) count++; + if (key && nbuttons > 0) count++; + if (key && nkeys > 32) count++; // this is basically always true + // count is at 2 for our keys + zero button device + + ev = alloc(count * sizeof(xEvent)); + FixDeviceStateNotify(ev); + if (button) + FixDeviceStateNotify(ev++); + if (key) + FixDeviceStateNotify(ev++); // santa drops into the wrong chimney here + +If the device has more than 3 valuators, the OOB is pushed back - we're +off by one so it will happen when the last deviceValuator event is +written instead. + +Fix this by allocating the maximum number of events we may allocate. +Note that the current behavior is not protocol-correct anyway, this +patch fixes only the allocation issue. + +Note that this issue does not trigger if the device has at least one +button. While the server does not prevent a button class with zero +buttons, it is very unlikely. + +CVE-2024-0229, ZDI-CAN-22678 + +This vulnerability was discovered by: +Jan-Niklas Sohn working with Trend Micro Zero Day Initiative +--- + dix/enterleave.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/dix/enterleave.c b/dix/enterleave.c +index ded8679d76..17964b00a4 100644 +--- a/dix/enterleave.c ++++ b/dix/enterleave.c +@@ -675,7 +675,8 @@ static void + DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win) + { + int evcount = 1; +- deviceStateNotify *ev, *sev; ++ deviceStateNotify sev[6 + (MAX_VALUATORS + 2)/3]; ++ deviceStateNotify *ev; + deviceKeyStateNotify *kev; + deviceButtonStateNotify *bev; + +@@ -714,7 +715,7 @@ DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win) + } + } + +- sev = ev = xallocarray(evcount, sizeof(xEvent)); ++ ev = sev; + FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first); + + if (b != NULL) { +@@ -770,7 +771,6 @@ DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win) + + DeliverEventsToWindow(dev, win, (xEvent *) sev, evcount, + DeviceStateNotifyMask, NullGrab); +- free(sev); + } + + void +-- +From 219c54b8a3337456ce5270ded6a67bcde53553d5 Mon Sep 17 00:00:00 2001 +From: Peter Hutterer +Date: Mon, 18 Dec 2023 12:26:20 +1000 +Subject: [PATCH] dix: fix DeviceStateNotify event calculation + +The previous code only made sense if one considers buttons and keys to +be mutually exclusive on a device. That is not necessarily true, causing +a number of issues. + +This function allocates and fills in the number of xEvents we need to +send the device state down the wire. This is split across multiple +32-byte devices including one deviceStateNotify event and optional +deviceKeyStateNotify, deviceButtonStateNotify and (possibly multiple) +deviceValuator events. + +The previous behavior would instead compose a sequence +of [state, buttonstate, state, keystate, valuator...]. This is not +protocol correct, and on top of that made the code extremely convoluted. + +Fix this by streamlining: add both button and key into the deviceStateNotify +and then append the key state and button state, followed by the +valuators. Finally, the deviceValuator events contain up to 6 valuators +per event but we only ever sent through 3 at a time. Let's double that +troughput. + +CVE-2024-0229, ZDI-CAN-22678 + +This vulnerability was discovered by: +Jan-Niklas Sohn working with Trend Micro Zero Day Initiative +--- + dix/enterleave.c | 121 ++++++++++++++++++++--------------------------- + 1 file changed, 52 insertions(+), 69 deletions(-) + +diff --git a/dix/enterleave.c b/dix/enterleave.c +index 17964b00a4..7b7ba1098b 100644 +--- a/dix/enterleave.c ++++ b/dix/enterleave.c +@@ -615,9 +615,15 @@ FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v, + + ev->type = DeviceValuator; + ev->deviceid = dev->id; +- ev->num_valuators = nval < 3 ? nval : 3; ++ ev->num_valuators = nval < 6 ? nval : 6; + ev->first_valuator = first; + switch (ev->num_valuators) { ++ case 6: ++ ev->valuator2 = v->axisVal[first + 5]; ++ case 5: ++ ev->valuator2 = v->axisVal[first + 4]; ++ case 4: ++ ev->valuator2 = v->axisVal[first + 3]; + case 3: + ev->valuator2 = v->axisVal[first + 2]; + case 2: +@@ -626,7 +632,6 @@ FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v, + ev->valuator0 = v->axisVal[first]; + break; + } +- first += ev->num_valuators; + } + + static void +@@ -646,7 +651,7 @@ FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k, + ev->num_buttons = b->numButtons; + memcpy((char *) ev->buttons, (char *) b->down, 4); + } +- else if (k) { ++ if (k) { + ev->classes_reported |= (1 << KeyClass); + ev->num_keys = k->xkbInfo->desc->max_key_code - + k->xkbInfo->desc->min_key_code; +@@ -670,15 +675,26 @@ FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k, + } + } + +- ++/** ++ * The device state notify event is split across multiple 32-byte events. ++ * The first one contains the first 32 button state bits, the first 32 ++ * key state bits, and the first 3 valuator values. ++ * ++ * If a device has more than that, the server sends out: ++ * - one deviceButtonStateNotify for buttons 32 and above ++ * - one deviceKeyStateNotify for keys 32 and above ++ * - one deviceValuator event per 6 valuators above valuator 4 ++ * ++ * All events but the last one have the deviceid binary ORed with MORE_EVENTS, ++ */ + static void + DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win) + { ++ /* deviceStateNotify, deviceKeyStateNotify, deviceButtonStateNotify ++ * and one deviceValuator for each 6 valuators */ ++ deviceStateNotify sev[3 + (MAX_VALUATORS + 6)/6]; + int evcount = 1; +- deviceStateNotify sev[6 + (MAX_VALUATORS + 2)/3]; +- deviceStateNotify *ev; +- deviceKeyStateNotify *kev; +- deviceButtonStateNotify *bev; ++ deviceStateNotify *ev = sev; + + KeyClassPtr k; + ButtonClassPtr b; +@@ -691,82 +707,49 @@ DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win) + + if ((b = dev->button) != NULL) { + nbuttons = b->numButtons; +- if (nbuttons > 32) ++ if (nbuttons > 32) /* first 32 are encoded in deviceStateNotify */ + evcount++; + } + if ((k = dev->key) != NULL) { + nkeys = k->xkbInfo->desc->max_key_code - k->xkbInfo->desc->min_key_code; +- if (nkeys > 32) ++ if (nkeys > 32) /* first 32 are encoded in deviceStateNotify */ + evcount++; +- if (nbuttons > 0) { +- evcount++; +- } + } + if ((v = dev->valuator) != NULL) { + nval = v->numAxes; +- +- if (nval > 3) +- evcount++; +- if (nval > 6) { +- if (!(k && b)) +- evcount++; +- if (nval > 9) +- evcount += ((nval - 7) / 3); +- } ++ /* first three are encoded in deviceStateNotify, then ++ * it's 6 per deviceValuator event */ ++ evcount += ((nval - 3) + 6)/6; + } + +- ev = sev; +- FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first); +- +- if (b != NULL) { +- FixDeviceStateNotify(dev, ev++, NULL, b, v, first); +- first += 3; +- nval -= 3; +- if (nbuttons > 32) { +- (ev - 1)->deviceid |= MORE_EVENTS; +- bev = (deviceButtonStateNotify *) ev++; +- bev->type = DeviceButtonStateNotify; +- bev->deviceid = dev->id; +- memcpy((char *) &bev->buttons[4], (char *) &b->down[4], +- DOWN_LENGTH - 4); +- } +- if (nval > 0) { +- (ev - 1)->deviceid |= MORE_EVENTS; +- FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); +- first += 3; +- nval -= 3; +- } ++ BUG_RETURN(evcount <= ARRAY_SIZE(sev)); ++ ++ FixDeviceStateNotify(dev, ev, k, b, v, first); ++ ++ if (b != NULL && nbuttons > 32) { ++ deviceButtonStateNotify *bev = (deviceButtonStateNotify *) ++ev; ++ (ev - 1)->deviceid |= MORE_EVENTS; ++ bev->type = DeviceButtonStateNotify; ++ bev->deviceid = dev->id; ++ memcpy((char *) &bev->buttons[4], (char *) &b->down[4], ++ DOWN_LENGTH - 4); + } + +- if (k != NULL) { +- FixDeviceStateNotify(dev, ev++, k, NULL, v, first); +- first += 3; +- nval -= 3; +- if (nkeys > 32) { +- (ev - 1)->deviceid |= MORE_EVENTS; +- kev = (deviceKeyStateNotify *) ev++; +- kev->type = DeviceKeyStateNotify; +- kev->deviceid = dev->id; +- memmove((char *) &kev->keys[0], (char *) &k->down[4], 28); +- } +- if (nval > 0) { +- (ev - 1)->deviceid |= MORE_EVENTS; +- FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); +- first += 3; +- nval -= 3; +- } ++ if (k != NULL && nkeys > 32) { ++ deviceKeyStateNotify *kev = (deviceKeyStateNotify *) ++ev; ++ (ev - 1)->deviceid |= MORE_EVENTS; ++ kev->type = DeviceKeyStateNotify; ++ kev->deviceid = dev->id; ++ memmove((char *) &kev->keys[0], (char *) &k->down[4], 28); + } + ++ first = 3; ++ nval -= 3; + while (nval > 0) { +- FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first); +- first += 3; +- nval -= 3; +- if (nval > 0) { +- (ev - 1)->deviceid |= MORE_EVENTS; +- FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); +- first += 3; +- nval -= 3; +- } ++ ev->deviceid |= MORE_EVENTS; ++ FixDeviceValuator(dev, (deviceValuator *) ++ev, v, first); ++ first += 6; ++ nval -= 6; + } + + DeliverEventsToWindow(dev, win, (xEvent *) sev, evcount, +-- +From df3c65706eb169d5938df0052059f3e0d5981b74 Mon Sep 17 00:00:00 2001 +From: Peter Hutterer +Date: Thu, 21 Dec 2023 13:48:10 +1000 +Subject: [PATCH] Xi: when creating a new ButtonClass, set the number of + buttons + +There's a racy sequence where a master device may copy the button class +from the slave, without ever initializing numButtons. This leads to a +device with zero buttons but a button class which is invalid. + +Let's copy the numButtons value from the source - by definition if we +don't have a button class yet we do not have any other slave devices +with more than this number of buttons anyway. + +CVE-2024-0229, ZDI-CAN-22678 + +This vulnerability was discovered by: +Jan-Niklas Sohn working with Trend Micro Zero Day Initiative +--- + Xi/exevents.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Xi/exevents.c b/Xi/exevents.c +index 54ea11a938..e161714682 100644 +--- a/Xi/exevents.c ++++ b/Xi/exevents.c +@@ -605,6 +605,7 @@ DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to) + to->button = calloc(1, sizeof(ButtonClassRec)); + if (!to->button) + FatalError("[Xi] no memory for class shift.\n"); ++ to->button->numButtons = from->button->numButtons; + } + else + classes->button = NULL; +-- diff --git a/SPECS/xorg-x11-server/CVE-2024-0409.patch b/SPECS/xorg-x11-server/CVE-2024-0409.patch new file mode 100644 index 00000000000..7e956fba368 --- /dev/null +++ b/SPECS/xorg-x11-server/CVE-2024-0409.patch @@ -0,0 +1,56 @@ +From 2ef0f1116c65d5cb06d7b6d83f8a1aea702c94f7 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Wed, 6 Dec 2023 11:51:56 +0100 +Subject: [PATCH] ephyr,xwayland: Use the proper private key for cursor + +The cursor in DIX is actually split in two parts, the cursor itself and +the cursor bits, each with their own devPrivates. + +The cursor itself includes the cursor bits, meaning that the cursor bits +devPrivates in within structure of the cursor. + +Both Xephyr and Xwayland were using the private key for the cursor bits +to store the data for the cursor, and when using XSELINUX which comes +with its own special devPrivates, the data stored in that cursor bits' +devPrivates would interfere with the XSELINUX devPrivates data and the +SELINUX security ID would point to some other unrelated data, causing a +crash in the XSELINUX code when trying to (re)use the security ID. + +CVE-2024-0409 + +Signed-off-by: Olivier Fourdan +Reviewed-by: Peter Hutterer +--- + hw/kdrive/ephyr/ephyrcursor.c | 2 +- + hw/xwayland/xwayland-cursor.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/kdrive/ephyr/ephyrcursor.c b/hw/kdrive/ephyr/ephyrcursor.c +index f991899c50..3f192d034a 100644 +--- a/hw/kdrive/ephyr/ephyrcursor.c ++++ b/hw/kdrive/ephyr/ephyrcursor.c +@@ -246,7 +246,7 @@ miPointerSpriteFuncRec EphyrPointerSpriteFuncs = { + Bool + ephyrCursorInit(ScreenPtr screen) + { +- if (!dixRegisterPrivateKey(&ephyrCursorPrivateKey, PRIVATE_CURSOR_BITS, ++ if (!dixRegisterPrivateKey(&ephyrCursorPrivateKey, PRIVATE_CURSOR, + sizeof(ephyrCursorRec))) + return FALSE; + +diff --git a/hw/xwayland/xwayland-cursor.c b/hw/xwayland/xwayland-cursor.c +index e3c1aaa50c..bd94b0cfbb 100644 +--- a/hw/xwayland/xwayland-cursor.c ++++ b/hw/xwayland/xwayland-cursor.c +@@ -431,7 +431,7 @@ static miPointerScreenFuncRec xwl_pointer_screen_funcs = { + Bool + xwl_screen_init_cursor(struct xwl_screen *xwl_screen) + { +- if (!dixRegisterPrivateKey(&xwl_cursor_private_key, PRIVATE_CURSOR_BITS, 0)) ++ if (!dixRegisterPrivateKey(&xwl_cursor_private_key, PRIVATE_CURSOR, 0)) + return FALSE; + + return miPointerInitialize(xwl_screen->screen, +-- +GitLab + diff --git a/SPECS/xorg-x11-server/CVE-2024-21886.patch b/SPECS/xorg-x11-server/CVE-2024-21886.patch new file mode 100644 index 00000000000..7bfaffd0c4b --- /dev/null +++ b/SPECS/xorg-x11-server/CVE-2024-21886.patch @@ -0,0 +1,120 @@ +From bc1fdbe46559dd947674375946bbef54dd0ce36b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= +Date: Fri, 22 Dec 2023 18:28:31 +0100 +Subject: [PATCH] Xi: do not keep linked list pointer during recursion + +The `DisableDevice()` function is called whenever an enabled device +is disabled and it moves the device from the `inputInfo.devices` linked +list to the `inputInfo.off_devices` linked list. + +However, its link/unlink operation has an issue during the recursive +call to `DisableDevice()` due to the `prev` pointer pointing to a +removed device. + +This issue leads to a length mismatch between the total number of +devices and the number of device in the list, leading to a heap +overflow and, possibly, to local privilege escalation. + +Simplify the code that checked whether the device passed to +`DisableDevice()` was in `inputInfo.devices` or not and find the +previous device after the recursion. + +CVE-2024-21886, ZDI-CAN-22840 + +This vulnerability was discovered by: +Jan-Niklas Sohn working with Trend Micro Zero Day Initiative +--- + dix/devices.c | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/dix/devices.c b/dix/devices.c +index dca98c8d1b..389d28a23c 100644 +--- a/dix/devices.c ++++ b/dix/devices.c +@@ -453,14 +453,20 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent) + { + DeviceIntPtr *prev, other; + BOOL enabled; ++ BOOL dev_in_devices_list = FALSE; + int flags[MAXDEVICES] = { 0 }; + + if (!dev->enabled) + return TRUE; + +- for (prev = &inputInfo.devices; +- *prev && (*prev != dev); prev = &(*prev)->next); +- if (*prev != dev) ++ for (other = inputInfo.devices; other; other = other->next) { ++ if (other == dev) { ++ dev_in_devices_list = TRUE; ++ break; ++ } ++ } ++ ++ if (!dev_in_devices_list) + return FALSE; + + TouchEndPhysicallyActiveTouches(dev); +@@ -511,6 +517,9 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent) + LeaveWindow(dev); + SetFocusOut(dev); + ++ for (prev = &inputInfo.devices; ++ *prev && (*prev != dev); prev = &(*prev)->next); ++ + *prev = dev->next; + dev->next = inputInfo.off_devices; + inputInfo.off_devices = dev; + +--- +From 26769aa71fcbe0a8403b7fb13b7c9010cc07c3a8 Mon Sep 17 00:00:00 2001 +From: Peter Hutterer +Date: Fri, 5 Jan 2024 09:40:27 +1000 +Subject: [PATCH] dix: when disabling a master, float disabled slaved devices + too + +Disabling a master device floats all slave devices but we didn't do this +to already-disabled slave devices. As a result those devices kept their +reference to the master device resulting in access to already freed +memory if the master device was removed before the corresponding slave +device. + +And to match this behavior, also forcibly reset that pointer during +CloseDownDevices(). + +Related to CVE-2024-21886, ZDI-CAN-22840 +--- + dix/devices.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/dix/devices.c b/dix/devices.c +index 389d28a23c..84a6406d13 100644 +--- a/dix/devices.c ++++ b/dix/devices.c +@@ -483,6 +483,13 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent) + flags[other->id] |= XISlaveDetached; + } + } ++ ++ for (other = inputInfo.off_devices; other; other = other->next) { ++ if (!IsMaster(other) && GetMaster(other, MASTER_ATTACHED) == dev) { ++ AttachDevice(NULL, other, NULL); ++ flags[other->id] |= XISlaveDetached; ++ } ++ } + } + else { + for (other = inputInfo.devices; other; other = other->next) { +@@ -1088,6 +1095,11 @@ CloseDownDevices(void) + dev->master = NULL; + } + ++ for (dev = inputInfo.off_devices; dev; dev = dev->next) { ++ if (!IsMaster(dev) && !IsFloating(dev)) ++ dev->master = NULL; ++ } ++ + CloseDeviceList(&inputInfo.devices); + CloseDeviceList(&inputInfo.off_devices); + +-- diff --git a/SPECS/xorg-x11-server/CVE-2024-31080.patch b/SPECS/xorg-x11-server/CVE-2024-31080.patch new file mode 100644 index 00000000000..00e979d7acb --- /dev/null +++ b/SPECS/xorg-x11-server/CVE-2024-31080.patch @@ -0,0 +1,44 @@ +From 96798fc1967491c80a4d0c8d9e0a80586cb2152b Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Fri, 22 Mar 2024 18:51:45 -0700 +Subject: [PATCH 1/4] Xi: ProcXIGetSelectedEvents needs to use unswapped length + to send reply + +CVE-2024-31080 + +Reported-by: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=69762 +Fixes: 53e821ab4 ("Xi: add request processing for XIGetSelectedEvents.") +Signed-off-by: Alan Coopersmith +Part-of: +--- + Xi/xiselectev.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/Xi/xiselectev.c b/Xi/xiselectev.c +index edcb8a0d36..ac14949871 100644 +--- a/Xi/xiselectev.c ++++ b/Xi/xiselectev.c +@@ -349,6 +349,7 @@ ProcXIGetSelectedEvents(ClientPtr client) + InputClientsPtr others = NULL; + xXIEventMask *evmask = NULL; + DeviceIntPtr dev; ++ uint32_t length; + + REQUEST(xXIGetSelectedEventsReq); + REQUEST_SIZE_MATCH(xXIGetSelectedEventsReq); +@@ -418,10 +419,12 @@ ProcXIGetSelectedEvents(ClientPtr client) + } + } + ++ /* save the value before SRepXIGetSelectedEvents swaps it */ ++ length = reply.length; + WriteReplyToClient(client, sizeof(xXIGetSelectedEventsReply), &reply); + + if (reply.num_masks) +- WriteToClient(client, reply.length * 4, buffer); ++ WriteToClient(client, length * 4, buffer); + + free(buffer); + return Success; +-- +GitLab diff --git a/SPECS/xorg-x11-server/CVE-2024-31081.patch b/SPECS/xorg-x11-server/CVE-2024-31081.patch new file mode 100644 index 00000000000..11e266f979a --- /dev/null +++ b/SPECS/xorg-x11-server/CVE-2024-31081.patch @@ -0,0 +1,42 @@ +From 3e77295f888c67fc7645db5d0c00926a29ffecee Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Fri, 22 Mar 2024 18:56:27 -0700 +Subject: [PATCH 2/4] Xi: ProcXIPassiveGrabDevice needs to use unswapped length + to send reply + +CVE-2024-31081 + +Fixes: d220d6907 ("Xi: add GrabButton and GrabKeysym code.") +Signed-off-by: Alan Coopersmith +Part-of: +--- + Xi/xipassivegrab.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c +index c9ac2f8553..896233bec2 100644 +--- a/Xi/xipassivegrab.c ++++ b/Xi/xipassivegrab.c +@@ -93,6 +93,7 @@ ProcXIPassiveGrabDevice(ClientPtr client) + GrabParameters param; + void *tmp; + int mask_len; ++ uint32_t length; + + REQUEST(xXIPassiveGrabDeviceReq); + REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq, +@@ -247,9 +248,11 @@ ProcXIPassiveGrabDevice(ClientPtr client) + } + } + ++ /* save the value before SRepXIPassiveGrabDevice swaps it */ ++ length = rep.length; + WriteReplyToClient(client, sizeof(rep), &rep); + if (rep.num_modifiers) +- WriteToClient(client, rep.length * 4, modifiers_failed); ++ WriteToClient(client, length * 4, modifiers_failed); + + out: + free(modifiers_failed); +-- +GitLab diff --git a/SPECS/xorg-x11-server/CVE-2024-31082.patch b/SPECS/xorg-x11-server/CVE-2024-31082.patch new file mode 100644 index 00000000000..004f135b035 --- /dev/null +++ b/SPECS/xorg-x11-server/CVE-2024-31082.patch @@ -0,0 +1,46 @@ +From 6c684d035c06fd41c727f0ef0744517580864cef Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Fri, 22 Mar 2024 19:07:34 -0700 +Subject: [PATCH 3/4] Xquartz: ProcAppleDRICreatePixmap needs to use unswapped + length to send reply + +CVE-2024-31082 + +Fixes: 14205ade0 ("XQuartz: appledri: Fix byte swapping in replies") +Signed-off-by: Alan Coopersmith +Part-of: +--- + hw/xquartz/xpr/appledri.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/hw/xquartz/xpr/appledri.c b/hw/xquartz/xpr/appledri.c +index 77574655b2..40422b61a9 100644 +--- a/hw/xquartz/xpr/appledri.c ++++ b/hw/xquartz/xpr/appledri.c +@@ -272,6 +272,7 @@ ProcAppleDRICreatePixmap(ClientPtr client) + xAppleDRICreatePixmapReply rep; + int width, height, pitch, bpp; + void *ptr; ++ CARD32 stringLength; + + REQUEST_SIZE_MATCH(xAppleDRICreatePixmapReq); + +@@ -307,6 +308,7 @@ ProcAppleDRICreatePixmap(ClientPtr client) + if (sizeof(rep) != sz_xAppleDRICreatePixmapReply) + ErrorF("error sizeof(rep) is %zu\n", sizeof(rep)); + ++ stringLength = rep.stringLength; /* save unswapped value */ + if (client->swapped) { + swaps(&rep.sequenceNumber); + swapl(&rep.length); +@@ -319,7 +321,7 @@ ProcAppleDRICreatePixmap(ClientPtr client) + } + + WriteToClient(client, sizeof(rep), &rep); +- WriteToClient(client, rep.stringLength, path); ++ WriteToClient(client, stringLength, path); + + return Success; + } +-- +GitLab diff --git a/SPECS/xorg-x11-server/CVE-2024-31083.patch b/SPECS/xorg-x11-server/CVE-2024-31083.patch new file mode 100644 index 00000000000..c880f6ca7a7 --- /dev/null +++ b/SPECS/xorg-x11-server/CVE-2024-31083.patch @@ -0,0 +1,113 @@ +From bdca6c3d1f5057eeb31609b1280fc93237b00c77 Mon Sep 17 00:00:00 2001 +From: Peter Hutterer +Date: Tue, 30 Jan 2024 13:13:35 +1000 +Subject: [PATCH 4/4] render: fix refcounting of glyphs during + ProcRenderAddGlyphs + +Previously, AllocateGlyph would return a new glyph with refcount=0 and a +re-used glyph would end up not changing the refcount at all. The +resulting glyph_new array would thus have multiple entries pointing to +the same non-refcounted glyphs. + +AddGlyph may free a glyph, resulting in a UAF when the same glyph +pointer is then later used. + +Fix this by returning a refcount of 1 for a new glyph and always +incrementing the refcount for a re-used glyph, followed by dropping that +refcount back down again when we're done with it. + +CVE-2024-31083, ZDI-CAN-22880 + +This vulnerability was discovered by: +Jan-Niklas Sohn working with Trend Micro Zero Day Initiative + +Part-of: +--- + render/glyph.c | 5 +++-- + render/glyphstr.h | 2 ++ + render/render.c | 15 +++++++++++---- + 3 files changed, 16 insertions(+), 6 deletions(-) + +diff --git a/render/glyph.c b/render/glyph.c +index f3ed9cf..d5fc5f3 100644 +--- a/render/glyph.c ++++ b/render/glyph.c +@@ -245,10 +245,11 @@ FreeGlyphPicture(GlyphPtr glyph) + } + } + +-static void ++void + FreeGlyph(GlyphPtr glyph, int format) + { + CheckDuplicates(&globalGlyphs[format], "FreeGlyph"); ++ BUG_RETURN(glyph->refcnt == 0); + if (--glyph->refcnt == 0) { + GlyphRefPtr gr; + int i; +@@ -354,7 +355,7 @@ AllocateGlyph(xGlyphInfo * gi, int fdepth) + glyph = (GlyphPtr) malloc(size); + if (!glyph) + return 0; +- glyph->refcnt = 0; ++ glyph->refcnt = 1; + glyph->size = size + sizeof(xGlyphInfo); + glyph->info = *gi; + dixInitPrivates(glyph, (char *) glyph + head_size, PRIVATE_GLYPH); +diff --git a/render/glyphstr.h b/render/glyphstr.h +index 2f51bd2..e803455 100644 +--- a/render/glyphstr.h ++++ b/render/glyphstr.h +@@ -109,6 +109,8 @@ extern GlyphPtr FindGlyph(GlyphSetPtr glyphSet, Glyph id); + + extern GlyphPtr AllocateGlyph(xGlyphInfo * gi, int format); + ++extern void FreeGlyph(GlyphPtr glyph, int format); ++ + extern Bool + ResizeGlyphSet(GlyphSetPtr glyphSet, CARD32 change); + +diff --git a/render/render.c b/render/render.c +index c376090..868bb1e 100644 +--- a/render/render.c ++++ b/render/render.c +@@ -1076,6 +1076,7 @@ ProcRenderAddGlyphs(ClientPtr client) + + if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph) { + glyph_new->found = TRUE; ++ ++glyph_new->glyph->refcnt; + } + else { + GlyphPtr glyph; +@@ -1168,8 +1169,10 @@ ProcRenderAddGlyphs(ClientPtr client) + err = BadAlloc; + goto bail; + } +- for (i = 0; i < nglyphs; i++) ++ for (i = 0; i < nglyphs; i++) { + AddGlyph(glyphSet, glyphs[i].glyph, glyphs[i].id); ++ FreeGlyph(glyphs[i].glyph, glyphSet->fdepth); ++ } + + if (glyphsBase != glyphsLocal) + free(glyphsBase); +@@ -1179,9 +1182,13 @@ ProcRenderAddGlyphs(ClientPtr client) + FreePicture((void *) pSrc, 0); + if (pSrcPix) + FreeScratchPixmapHeader(pSrcPix); +- for (i = 0; i < nglyphs; i++) +- if (glyphs[i].glyph && !glyphs[i].found) +- free(glyphs[i].glyph); ++ for (i = 0; i < nglyphs; i++) { ++ if (glyphs[i].glyph) { ++ --glyphs[i].glyph->refcnt; ++ if (!glyphs[i].found) ++ free(glyphs[i].glyph); ++ } ++ } + if (glyphsBase != glyphsLocal) + free(glyphsBase); + return err; +-- +2.25.1 + diff --git a/SPECS/xorg-x11-server/xorg-x11-server.spec b/SPECS/xorg-x11-server/xorg-x11-server.spec index 9e445ceab53..21ee39cb1f6 100644 --- a/SPECS/xorg-x11-server/xorg-x11-server.spec +++ b/SPECS/xorg-x11-server/xorg-x11-server.spec @@ -21,7 +21,7 @@ Summary: X.Org X11 X server Name: xorg-x11-server Version: 1.20.10 -Release: 10%{?dist} +Release: 12%{?dist} License: MIT Vendor: Microsoft Corporation Distribution: Mariner @@ -53,14 +53,22 @@ Patch6: 0001-Fedora-hack-Make-the-suid-root-wrapper-always-start-.patch # # Backports from "master" upstream: -Patch7: CVE-2023-1594.patch -Patch8: CVE-2023-6377.patch -Patch9: CVE-2023-6478.patch -Patch10: CVE-2024-21885.patch -Patch11: CVE-2023-6816.patch -Patch12: CVE-2023-5574.patch -Patch13: CVE-2023-5367.patch -Patch14: CVE-2023-5380.patch +Patch7: CVE-2023-1594.patch +Patch8: CVE-2023-6377.patch +Patch9: CVE-2023-6478.patch +Patch10: CVE-2024-21885.patch +Patch11: CVE-2023-6816.patch +Patch12: CVE-2023-5574.patch +Patch13: CVE-2023-5367.patch +Patch14: CVE-2023-5380.patch +Patch15: CVE-2024-31080.patch +Patch16: CVE-2024-31081.patch +Patch17: CVE-2024-31082.patch +Patch18: CVE-2024-31083.patch +Patch19: Avoid_possible_double-free_in_ProcRenderAddGlyphs.patch +Patch20: CVE-2024-0229.patch +Patch21: CVE-2024-0409.patch +Patch22: CVE-2024-21886.patch # Backported Xwayland randr resolution change emulation support Patch501: 0001-dix-Add-GetCurrentClient-helper.patch @@ -391,6 +399,12 @@ find %{buildroot} -type f -name "*.la" -delete -print %{_datadir}/aclocal/xorg-server.m4 %changelog +* Tue Sep 17 2024 Sumedh Sharma - 1.20.10-12 +- Add patch to resolve CVE-2024-0229, CVE-2024-0409 & CVE-2024-21886. + +* Tue Aug 06 2024 Sumedh Sharma - 1.20.10-11 +- Add patch for CVE-2024-31080, CVE-2024-31081, CVE-2024-31082 & CVE-2024-31083. + * Thu Mar 28 2024 Alberto David Perez Guevara - 1.20.10-10 - Add patch for CVE-2023-5380 diff --git a/cgmanifest.json b/cgmanifest.json index 17a2156f4fa..a73beccd185 100644 --- a/cgmanifest.json +++ b/cgmanifest.json @@ -3418,8 +3418,8 @@ "type": "other", "other": { "name": "expat", - "version": "2.6.2", - "downloadUrl": "https://github.com/libexpat/libexpat/releases/download/R_2_6_2/expat-2.6.2.tar.bz2" + "version": "2.6.3", + "downloadUrl": "https://github.com/libexpat/libexpat/releases/download/R_2_6_3/expat-2.6.3.tar.bz2" } } }, @@ -4620,8 +4620,8 @@ "type": "other", "other": { "name": "golang", - "version": "1.22.5", - "downloadUrl": "https://golang.org/dl/go1.22.5.src.tar.gz" + "version": "1.22.7", + "downloadUrl": "https://golang.org/dl/go1.22.7.src.tar.gz" } } }, @@ -6540,8 +6540,8 @@ "type": "other", "other": { "name": "hyperv-daemons", - "version": "5.15.164.1", - "downloadUrl": "https://github.com/microsoft/CBL-Mariner-Linux-Kernel/archive/rolling-lts/mariner-2/5.15.164.1.tar.gz" + "version": "5.15.167.1", + "downloadUrl": "https://github.com/microsoft/CBL-Mariner-Linux-Kernel/archive/rolling-lts/mariner-2/5.15.167.1.tar.gz" } } }, @@ -8101,8 +8101,8 @@ "type": "other", "other": { "name": "keepalived", - "version": "2.2.7", - "downloadUrl": "https://www.keepalived.org/software/keepalived-2.2.7.tar.gz" + "version": "2.3.1", + "downloadUrl": "https://www.keepalived.org/software/keepalived-2.3.1.tar.gz" } } }, @@ -8121,8 +8121,8 @@ "type": "other", "other": { "name": "kernel", - "version": "5.15.164.1", - "downloadUrl": "https://github.com/microsoft/CBL-Mariner-Linux-Kernel/archive/rolling-lts/mariner-2/5.15.164.1.tar.gz" + "version": "5.15.167.1", + "downloadUrl": "https://github.com/microsoft/CBL-Mariner-Linux-Kernel/archive/rolling-lts/mariner-2/5.15.167.1.tar.gz" } } }, @@ -8131,8 +8131,8 @@ "type": "other", "other": { "name": "kernel-azure", - "version": "5.15.164.1", - "downloadUrl": "https://github.com/microsoft/CBL-Mariner-Linux-Kernel/archive/rolling-lts/mariner-2/5.15.164.1.tar.gz" + "version": "5.15.167.1", + "downloadUrl": "https://github.com/microsoft/CBL-Mariner-Linux-Kernel/archive/rolling-lts/mariner-2/5.15.167.1.tar.gz" } } }, @@ -8141,8 +8141,8 @@ "type": "other", "other": { "name": "kernel-hci", - "version": "5.15.164.1", - "downloadUrl": "https://github.com/microsoft/CBL-Mariner-Linux-Kernel/archive/rolling-lts/mariner-2/5.15.164.1.tar.gz" + "version": "5.15.167.1", + "downloadUrl": "https://github.com/microsoft/CBL-Mariner-Linux-Kernel/archive/rolling-lts/mariner-2/5.15.167.1.tar.gz" } } }, @@ -8151,8 +8151,8 @@ "type": "other", "other": { "name": "kernel-headers", - "version": "5.15.164.1", - "downloadUrl": "https://github.com/microsoft/CBL-Mariner-Linux-Kernel/archive/rolling-lts/mariner-2/5.15.164.1.tar.gz" + "version": "5.15.167.1", + "downloadUrl": "https://github.com/microsoft/CBL-Mariner-Linux-Kernel/archive/rolling-lts/mariner-2/5.15.167.1.tar.gz" } } }, @@ -8341,8 +8341,8 @@ "type": "other", "other": { "name": "krb5", - "version": "1.21.3", - "downloadUrl": "https://kerberos.org/dist/krb5/1.21/krb5-1.21.3.tar.gz" + "version": "1.19.4", + "downloadUrl": "https://kerberos.org/dist/krb5/1.19/krb5-1.19.4.tar.gz" } } }, @@ -11226,13 +11226,33 @@ } } }, + { + "component": { + "type": "other", + "other": { + "name": "libtracecmd", + "version": "1.5.1", + "downloadUrl": "https://git.kernel.org/pub/scm/utils/trace-cmd/trace-cmd.git/snapshot/trace-cmd-libtracecmd-1.5.1.tar.gz" + } + } + }, { "component": { "type": "other", "other": { "name": "libtraceevent", - "version": "1.7.2", - "downloadUrl": "https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/snapshot/libtraceevent-1.7.2.tar.gz" + "version": "1.8.2", + "downloadUrl": "https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/snapshot/libtraceevent-1.8.2.tar.gz" + } + } + }, + { + "component": { + "type": "other", + "other": { + "name": "libtracefs", + "version": "1.8.0", + "downloadUrl": "https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/snapshot/libtracefs-1.8.0.tar.gz" } } }, @@ -13653,8 +13673,8 @@ "type": "other", "other": { "name": "msft-golang", - "version": "1.22.5", - "downloadUrl": "https://github.com/microsoft/go/releases/download/v1.22.5-1/go1.22.5-20240702.3.src.tar.gz" + "version": "1.22.7", + "downloadUrl": "https://github.com/microsoft/go/releases/download/v1.22.7-1/go1.22.7-20240905.3.src.tar.gz" } } }, @@ -24994,8 +25014,8 @@ "type": "other", "other": { "name": "python-webob", - "version": "1.8.7", - "downloadUrl": "https://github.com/Pylons/webob/archive/refs/tags/1.8.7.tar.gz" + "version": "1.8.8", + "downloadUrl": "https://github.com/Pylons/webob/archive/refs/tags/1.8.8.tar.gz" } } }, @@ -28457,8 +28477,8 @@ "type": "other", "other": { "name": "sysstat", - "version": "12.7.1", - "downloadUrl": "https://github.com/sysstat/sysstat/archive/v12.7.1.tar.gz" + "version": "12.7.6", + "downloadUrl": "https://github.com/sysstat/sysstat/archive/v12.7.6.tar.gz" } } }, @@ -28912,6 +28932,16 @@ } } }, + { + "component": { + "type": "other", + "other": { + "name": "trace-cmd", + "version": "3.2", + "downloadUrl": "https://git.kernel.org/pub/scm/utils/trace-cmd/trace-cmd.git/snapshot/trace-cmd-v3.2.tar.gz" + } + } + }, { "component": { "type": "other", diff --git a/toolkit/imageconfigs/marketplace-gen2-aarch64-fips.json b/toolkit/imageconfigs/marketplace-gen2-aarch64-fips.json new file mode 100644 index 00000000000..848eb53e14d --- /dev/null +++ b/toolkit/imageconfigs/marketplace-gen2-aarch64-fips.json @@ -0,0 +1,88 @@ +{ + "Disks": [ + { + "PartitionTableType": "gpt", + "MaxSize": 5000, + "Artifacts": [ + { + "Name": "cblmariner-arm64-gen2-fips", + "Type": "vhd" + } + ], + "Partitions": [ + { + "ID": "efi", + "Flags": [ + "esp", + "boot" + ], + "Start": 1, + "End": 65, + "FsType": "fat32" + }, + { + "ID": "boot", + "Start": 65, + "End": 565, + "FsType": "ext4" + }, + { + "ID": "rootfs", + "Name": "rootfs", + "Start": 565, + "End": 0, + "FsType": "ext4" + } + ] + } + ], + "SystemConfigs": [ + { + "Name": "Standard", + "BootType": "efi", + "PartitionSettings": [ + { + "ID": "efi", + "MountPoint": "/boot/efi", + "MountOptions" : "umask=0077" + }, + { + "ID": "boot", + "MountPoint": "/boot" + }, + { + "ID": "rootfs", + "MountPoint": "/" + } + ], + "PackageLists": [ + "packagelists/fips-packages.json", + "packagelists/core-packages-image-aarch64.json", + "packagelists/marketplace-tools-packages.json", + "packagelists/azurevm-packages.json" + ], + "AdditionalFiles": { + "additionalconfigs/cloud-init.cfg": "/etc/cloud/cloud.cfg", + "additionalconfigs/chrony.cfg": "/etc/chrony.conf", + "additionalconfigs/wait-for-ptp-hyperv.conf": "/etc/systemd/system/chronyd.service.d/wait-for-ptp-hyperv.conf", + "additionalconfigs/51-ptp-hyperv.rules": "/etc/udev/rules.d/51-ptp-hyperv.rules" + }, + "PostInstallScripts": [ + { + "Path": "additionalconfigs/configure-systemd-networkd.sh" + }, + { + "Path": "postinstallscripts/remove-tdnf-cache.sh" + } + ], + "KernelOptions": { + "default": "kernel" + }, + "KernelCommandLine": { + "EnableFIPS": true, + "ExtraCommandLine": "console=tty1 console=ttyAMA0 earlycon=pl011,0xeffec000 initcall_blacklist=arm_pmu_acpi_init" + }, + "Hostname": "cbl-mariner" + } + ] +} diff --git a/toolkit/resources/manifests/package/pkggen_core_aarch64.txt b/toolkit/resources/manifests/package/pkggen_core_aarch64.txt index a0994607928..2f390d8fa15 100644 --- a/toolkit/resources/manifests/package/pkggen_core_aarch64.txt +++ b/toolkit/resources/manifests/package/pkggen_core_aarch64.txt @@ -1,5 +1,5 @@ filesystem-1.1-20.cm2.aarch64.rpm -kernel-headers-5.15.164.1-1.cm2.noarch.rpm +kernel-headers-5.15.167.1-1.cm2.noarch.rpm glibc-2.35-7.cm2.aarch64.rpm glibc-devel-2.35-7.cm2.aarch64.rpm glibc-i18n-2.35-7.cm2.aarch64.rpm @@ -95,9 +95,9 @@ elfutils-libelf-0.186-2.cm2.aarch64.rpm elfutils-libelf-devel-0.186-2.cm2.aarch64.rpm elfutils-libelf-devel-static-0.186-2.cm2.aarch64.rpm elfutils-libelf-lang-0.186-2.cm2.aarch64.rpm -expat-2.6.2-2.cm2.aarch64.rpm -expat-devel-2.6.2-2.cm2.aarch64.rpm -expat-libs-2.6.2-2.cm2.aarch64.rpm +expat-2.6.3-1.cm2.aarch64.rpm +expat-devel-2.6.3-1.cm2.aarch64.rpm +expat-libs-2.6.3-1.cm2.aarch64.rpm libpipeline-1.5.5-3.cm2.aarch64.rpm libpipeline-devel-1.5.5-3.cm2.aarch64.rpm gdbm-1.21-1.cm2.aarch64.rpm @@ -188,14 +188,14 @@ libsolv-0.7.24-1.cm2.aarch64.rpm libsolv-devel-0.7.24-1.cm2.aarch64.rpm libssh2-1.9.0-4.cm2.aarch64.rpm libssh2-devel-1.9.0-4.cm2.aarch64.rpm -krb5-1.21.3-1.cm2.aarch64.rpm +krb5-1.19.4-3.cm2.aarch64.rpm nghttp2-1.57.0-1.cm2.aarch64.rpm -curl-8.8.0-1.cm2.aarch64.rpm -curl-devel-8.8.0-1.cm2.aarch64.rpm -curl-libs-8.8.0-1.cm2.aarch64.rpm +curl-8.8.0-2.cm2.aarch64.rpm +curl-devel-8.8.0-2.cm2.aarch64.rpm +curl-libs-8.8.0-2.cm2.aarch64.rpm createrepo_c-0.17.5-1.cm2.aarch64.rpm -libxml2-2.10.4-3.cm2.aarch64.rpm -libxml2-devel-2.10.4-3.cm2.aarch64.rpm +libxml2-2.10.4-4.cm2.aarch64.rpm +libxml2-devel-2.10.4-4.cm2.aarch64.rpm docbook-dtd-xml-4.5-11.cm2.noarch.rpm docbook-style-xsl-1.79.1-14.cm2.noarch.rpm libsepol-3.2-2.cm2.aarch64.rpm @@ -237,10 +237,10 @@ ca-certificates-base-2.0.0-18.cm2.noarch.rpm ca-certificates-2.0.0-18.cm2.noarch.rpm dwz-0.14-2.cm2.aarch64.rpm unzip-6.0-20.cm2.aarch64.rpm -python3-3.9.19-4.cm2.aarch64.rpm -python3-devel-3.9.19-4.cm2.aarch64.rpm -python3-libs-3.9.19-4.cm2.aarch64.rpm -python3-setuptools-3.9.19-4.cm2.noarch.rpm +python3-3.9.19-5.cm2.aarch64.rpm +python3-devel-3.9.19-5.cm2.aarch64.rpm +python3-libs-3.9.19-5.cm2.aarch64.rpm +python3-setuptools-3.9.19-5.cm2.noarch.rpm python3-pygments-2.4.2-7.cm2.noarch.rpm which-2.21-8.cm2.aarch64.rpm libselinux-3.2-1.cm2.aarch64.rpm diff --git a/toolkit/resources/manifests/package/pkggen_core_x86_64.txt b/toolkit/resources/manifests/package/pkggen_core_x86_64.txt index 42e607ee967..62d50b10c68 100644 --- a/toolkit/resources/manifests/package/pkggen_core_x86_64.txt +++ b/toolkit/resources/manifests/package/pkggen_core_x86_64.txt @@ -1,5 +1,5 @@ filesystem-1.1-20.cm2.x86_64.rpm -kernel-headers-5.15.164.1-1.cm2.noarch.rpm +kernel-headers-5.15.167.1-1.cm2.noarch.rpm glibc-2.35-7.cm2.x86_64.rpm glibc-devel-2.35-7.cm2.x86_64.rpm glibc-i18n-2.35-7.cm2.x86_64.rpm @@ -95,9 +95,9 @@ elfutils-libelf-0.186-2.cm2.x86_64.rpm elfutils-libelf-devel-0.186-2.cm2.x86_64.rpm elfutils-libelf-devel-static-0.186-2.cm2.x86_64.rpm elfutils-libelf-lang-0.186-2.cm2.x86_64.rpm -expat-2.6.2-2.cm2.x86_64.rpm -expat-devel-2.6.2-2.cm2.x86_64.rpm -expat-libs-2.6.2-2.cm2.x86_64.rpm +expat-2.6.3-1.cm2.x86_64.rpm +expat-devel-2.6.3-1.cm2.x86_64.rpm +expat-libs-2.6.3-1.cm2.x86_64.rpm libpipeline-1.5.5-3.cm2.x86_64.rpm libpipeline-devel-1.5.5-3.cm2.x86_64.rpm gdbm-1.21-1.cm2.x86_64.rpm @@ -188,14 +188,14 @@ libsolv-0.7.24-1.cm2.x86_64.rpm libsolv-devel-0.7.24-1.cm2.x86_64.rpm libssh2-1.9.0-4.cm2.x86_64.rpm libssh2-devel-1.9.0-4.cm2.x86_64.rpm -krb5-1.21.3-1.cm2.x86_64.rpm +krb5-1.19.4-3.cm2.x86_64.rpm nghttp2-1.57.0-1.cm2.x86_64.rpm -curl-8.8.0-1.cm2.x86_64.rpm -curl-devel-8.8.0-1.cm2.x86_64.rpm -curl-libs-8.8.0-1.cm2.x86_64.rpm +curl-8.8.0-2.cm2.x86_64.rpm +curl-devel-8.8.0-2.cm2.x86_64.rpm +curl-libs-8.8.0-2.cm2.x86_64.rpm createrepo_c-0.17.5-1.cm2.x86_64.rpm -libxml2-2.10.4-3.cm2.x86_64.rpm -libxml2-devel-2.10.4-3.cm2.x86_64.rpm +libxml2-2.10.4-4.cm2.x86_64.rpm +libxml2-devel-2.10.4-4.cm2.x86_64.rpm docbook-dtd-xml-4.5-11.cm2.noarch.rpm docbook-style-xsl-1.79.1-14.cm2.noarch.rpm libsepol-3.2-2.cm2.x86_64.rpm @@ -237,10 +237,10 @@ ca-certificates-base-2.0.0-18.cm2.noarch.rpm ca-certificates-2.0.0-18.cm2.noarch.rpm dwz-0.14-2.cm2.x86_64.rpm unzip-6.0-20.cm2.x86_64.rpm -python3-3.9.19-4.cm2.x86_64.rpm -python3-devel-3.9.19-4.cm2.x86_64.rpm -python3-libs-3.9.19-4.cm2.x86_64.rpm -python3-setuptools-3.9.19-4.cm2.noarch.rpm +python3-3.9.19-5.cm2.x86_64.rpm +python3-devel-3.9.19-5.cm2.x86_64.rpm +python3-libs-3.9.19-5.cm2.x86_64.rpm +python3-setuptools-3.9.19-5.cm2.noarch.rpm python3-pygments-2.4.2-7.cm2.noarch.rpm which-2.21-8.cm2.x86_64.rpm libselinux-3.2-1.cm2.x86_64.rpm diff --git a/toolkit/resources/manifests/package/toolchain_aarch64.txt b/toolkit/resources/manifests/package/toolchain_aarch64.txt index b76f05fad72..cb017a79e27 100644 --- a/toolkit/resources/manifests/package/toolchain_aarch64.txt +++ b/toolkit/resources/manifests/package/toolchain_aarch64.txt @@ -30,8 +30,8 @@ check-debuginfo-0.15.2-1.cm2.aarch64.rpm chkconfig-1.20-4.cm2.aarch64.rpm chkconfig-debuginfo-1.20-4.cm2.aarch64.rpm chkconfig-lang-1.20-4.cm2.aarch64.rpm -cmake-3.21.4-11.cm2.aarch64.rpm -cmake-debuginfo-3.21.4-11.cm2.aarch64.rpm +cmake-3.21.4-12.cm2.aarch64.rpm +cmake-debuginfo-3.21.4-12.cm2.aarch64.rpm coreutils-8.32-7.cm2.aarch64.rpm coreutils-debuginfo-8.32-7.cm2.aarch64.rpm coreutils-lang-8.32-7.cm2.aarch64.rpm @@ -46,10 +46,10 @@ cracklib-lang-2.9.7-5.cm2.aarch64.rpm createrepo_c-0.17.5-1.cm2.aarch64.rpm createrepo_c-debuginfo-0.17.5-1.cm2.aarch64.rpm createrepo_c-devel-0.17.5-1.cm2.aarch64.rpm -curl-8.8.0-1.cm2.aarch64.rpm -curl-debuginfo-8.8.0-1.cm2.aarch64.rpm -curl-devel-8.8.0-1.cm2.aarch64.rpm -curl-libs-8.8.0-1.cm2.aarch64.rpm +curl-8.8.0-2.cm2.aarch64.rpm +curl-debuginfo-8.8.0-2.cm2.aarch64.rpm +curl-devel-8.8.0-2.cm2.aarch64.rpm +curl-libs-8.8.0-2.cm2.aarch64.rpm Cython-debuginfo-0.29.33-2.cm2.aarch64.rpm debugedit-5.0-2.cm2.aarch64.rpm debugedit-debuginfo-5.0-2.cm2.aarch64.rpm @@ -73,10 +73,10 @@ elfutils-libelf-0.186-2.cm2.aarch64.rpm elfutils-libelf-devel-0.186-2.cm2.aarch64.rpm elfutils-libelf-devel-static-0.186-2.cm2.aarch64.rpm elfutils-libelf-lang-0.186-2.cm2.aarch64.rpm -expat-2.6.2-2.cm2.aarch64.rpm -expat-debuginfo-2.6.2-2.cm2.aarch64.rpm -expat-devel-2.6.2-2.cm2.aarch64.rpm -expat-libs-2.6.2-2.cm2.aarch64.rpm +expat-2.6.3-1.cm2.aarch64.rpm +expat-debuginfo-2.6.3-1.cm2.aarch64.rpm +expat-devel-2.6.3-1.cm2.aarch64.rpm +expat-libs-2.6.3-1.cm2.aarch64.rpm file-5.40-2.cm2.aarch64.rpm file-debuginfo-5.40-2.cm2.aarch64.rpm file-devel-5.40-2.cm2.aarch64.rpm @@ -136,14 +136,14 @@ intltool-0.51.0-7.cm2.noarch.rpm itstool-2.0.6-4.cm2.noarch.rpm kbd-2.2.0-1.cm2.aarch64.rpm kbd-debuginfo-2.2.0-1.cm2.aarch64.rpm -kernel-headers-5.15.164.1-1.cm2.noarch.rpm +kernel-headers-5.15.167.1-1.cm2.noarch.rpm kmod-29-2.cm2.aarch64.rpm kmod-debuginfo-29-2.cm2.aarch64.rpm kmod-devel-29-2.cm2.aarch64.rpm -krb5-1.21.3-1.cm2.aarch64.rpm -krb5-debuginfo-1.21.3-1.cm2.aarch64.rpm -krb5-devel-1.21.3-1.cm2.aarch64.rpm -krb5-lang-1.21.3-1.cm2.aarch64.rpm +krb5-1.19.4-3.cm2.aarch64.rpm +krb5-debuginfo-1.19.4-3.cm2.aarch64.rpm +krb5-devel-1.19.4-3.cm2.aarch64.rpm +krb5-lang-1.19.4-3.cm2.aarch64.rpm libarchive-3.6.1-3.cm2.aarch64.rpm libarchive-debuginfo-3.6.1-3.cm2.aarch64.rpm libarchive-devel-3.6.1-3.cm2.aarch64.rpm @@ -209,9 +209,9 @@ libtasn1-debuginfo-4.19.0-1.cm2.aarch64.rpm libtasn1-devel-4.19.0-1.cm2.aarch64.rpm libtool-2.4.6-8.cm2.aarch64.rpm libtool-debuginfo-2.4.6-8.cm2.aarch64.rpm -libxml2-2.10.4-3.cm2.aarch64.rpm -libxml2-debuginfo-2.10.4-3.cm2.aarch64.rpm -libxml2-devel-2.10.4-3.cm2.aarch64.rpm +libxml2-2.10.4-4.cm2.aarch64.rpm +libxml2-debuginfo-2.10.4-4.cm2.aarch64.rpm +libxml2-devel-2.10.4-4.cm2.aarch64.rpm libxslt-1.1.34-7.cm2.aarch64.rpm libxslt-debuginfo-1.1.34-7.cm2.aarch64.rpm libxslt-devel-1.1.34-7.cm2.aarch64.rpm @@ -510,28 +510,28 @@ procps-ng-devel-3.3.17-2.cm2.aarch64.rpm procps-ng-lang-3.3.17-2.cm2.aarch64.rpm pyproject-rpm-macros-1.0.0~rc1-4.cm2.noarch.rpm python-markupsafe-debuginfo-2.1.0-1.cm2.aarch64.rpm -python3-3.9.19-4.cm2.aarch64.rpm +python3-3.9.19-5.cm2.aarch64.rpm python3-audit-3.0.6-8.cm2.aarch64.rpm python3-cracklib-2.9.7-5.cm2.aarch64.rpm -python3-curses-3.9.19-4.cm2.aarch64.rpm +python3-curses-3.9.19-5.cm2.aarch64.rpm python3-Cython-0.29.33-2.cm2.aarch64.rpm -python3-debuginfo-3.9.19-4.cm2.aarch64.rpm -python3-devel-3.9.19-4.cm2.aarch64.rpm +python3-debuginfo-3.9.19-5.cm2.aarch64.rpm +python3-devel-3.9.19-5.cm2.aarch64.rpm python3-gpg-1.16.0-2.cm2.aarch64.rpm python3-jinja2-3.0.3-4.cm2.noarch.rpm python3-libcap-ng-0.8.2-2.cm2.aarch64.rpm -python3-libs-3.9.19-4.cm2.aarch64.rpm -python3-libxml2-2.10.4-3.cm2.aarch64.rpm +python3-libs-3.9.19-5.cm2.aarch64.rpm +python3-libxml2-2.10.4-4.cm2.aarch64.rpm python3-lxml-4.9.1-1.cm2.aarch64.rpm python3-magic-5.40-2.cm2.noarch.rpm python3-markupsafe-2.1.0-1.cm2.aarch64.rpm python3-newt-0.52.21-5.cm2.aarch64.rpm -python3-pip-3.9.19-4.cm2.noarch.rpm +python3-pip-3.9.19-5.cm2.noarch.rpm python3-pygments-2.4.2-7.cm2.noarch.rpm python3-rpm-4.18.0-4.cm2.aarch64.rpm -python3-setuptools-3.9.19-4.cm2.noarch.rpm -python3-test-3.9.19-4.cm2.aarch64.rpm -python3-tools-3.9.19-4.cm2.aarch64.rpm +python3-setuptools-3.9.19-5.cm2.noarch.rpm +python3-test-3.9.19-5.cm2.aarch64.rpm +python3-tools-3.9.19-5.cm2.aarch64.rpm readline-8.1-1.cm2.aarch64.rpm readline-debuginfo-8.1-1.cm2.aarch64.rpm readline-devel-8.1-1.cm2.aarch64.rpm diff --git a/toolkit/resources/manifests/package/toolchain_x86_64.txt b/toolkit/resources/manifests/package/toolchain_x86_64.txt index 8870096c635..64b26096068 100644 --- a/toolkit/resources/manifests/package/toolchain_x86_64.txt +++ b/toolkit/resources/manifests/package/toolchain_x86_64.txt @@ -31,8 +31,8 @@ check-debuginfo-0.15.2-1.cm2.x86_64.rpm chkconfig-1.20-4.cm2.x86_64.rpm chkconfig-debuginfo-1.20-4.cm2.x86_64.rpm chkconfig-lang-1.20-4.cm2.x86_64.rpm -cmake-3.21.4-11.cm2.x86_64.rpm -cmake-debuginfo-3.21.4-11.cm2.x86_64.rpm +cmake-3.21.4-12.cm2.x86_64.rpm +cmake-debuginfo-3.21.4-12.cm2.x86_64.rpm coreutils-8.32-7.cm2.x86_64.rpm coreutils-debuginfo-8.32-7.cm2.x86_64.rpm coreutils-lang-8.32-7.cm2.x86_64.rpm @@ -49,10 +49,10 @@ createrepo_c-debuginfo-0.17.5-1.cm2.x86_64.rpm createrepo_c-devel-0.17.5-1.cm2.x86_64.rpm cross-binutils-common-2.37-8.cm2.noarch.rpm cross-gcc-common-11.2.0-8.cm2.noarch.rpm -curl-8.8.0-1.cm2.x86_64.rpm -curl-debuginfo-8.8.0-1.cm2.x86_64.rpm -curl-devel-8.8.0-1.cm2.x86_64.rpm -curl-libs-8.8.0-1.cm2.x86_64.rpm +curl-8.8.0-2.cm2.x86_64.rpm +curl-debuginfo-8.8.0-2.cm2.x86_64.rpm +curl-devel-8.8.0-2.cm2.x86_64.rpm +curl-libs-8.8.0-2.cm2.x86_64.rpm Cython-debuginfo-0.29.33-2.cm2.x86_64.rpm debugedit-5.0-2.cm2.x86_64.rpm debugedit-debuginfo-5.0-2.cm2.x86_64.rpm @@ -76,10 +76,10 @@ elfutils-libelf-0.186-2.cm2.x86_64.rpm elfutils-libelf-devel-0.186-2.cm2.x86_64.rpm elfutils-libelf-devel-static-0.186-2.cm2.x86_64.rpm elfutils-libelf-lang-0.186-2.cm2.x86_64.rpm -expat-2.6.2-2.cm2.x86_64.rpm -expat-debuginfo-2.6.2-2.cm2.x86_64.rpm -expat-devel-2.6.2-2.cm2.x86_64.rpm -expat-libs-2.6.2-2.cm2.x86_64.rpm +expat-2.6.3-1.cm2.x86_64.rpm +expat-debuginfo-2.6.3-1.cm2.x86_64.rpm +expat-devel-2.6.3-1.cm2.x86_64.rpm +expat-libs-2.6.3-1.cm2.x86_64.rpm file-5.40-2.cm2.x86_64.rpm file-debuginfo-5.40-2.cm2.x86_64.rpm file-devel-5.40-2.cm2.x86_64.rpm @@ -141,15 +141,15 @@ intltool-0.51.0-7.cm2.noarch.rpm itstool-2.0.6-4.cm2.noarch.rpm kbd-2.2.0-1.cm2.x86_64.rpm kbd-debuginfo-2.2.0-1.cm2.x86_64.rpm -kernel-cross-headers-5.15.164.1-1.cm2.noarch.rpm -kernel-headers-5.15.164.1-1.cm2.noarch.rpm +kernel-cross-headers-5.15.167.1-1.cm2.noarch.rpm +kernel-headers-5.15.167.1-1.cm2.noarch.rpm kmod-29-2.cm2.x86_64.rpm kmod-debuginfo-29-2.cm2.x86_64.rpm kmod-devel-29-2.cm2.x86_64.rpm -krb5-1.21.3-1.cm2.x86_64.rpm -krb5-debuginfo-1.21.3-1.cm2.x86_64.rpm -krb5-devel-1.21.3-1.cm2.x86_64.rpm -krb5-lang-1.21.3-1.cm2.x86_64.rpm +krb5-1.19.4-3.cm2.x86_64.rpm +krb5-debuginfo-1.19.4-3.cm2.x86_64.rpm +krb5-devel-1.19.4-3.cm2.x86_64.rpm +krb5-lang-1.19.4-3.cm2.x86_64.rpm libarchive-3.6.1-3.cm2.x86_64.rpm libarchive-debuginfo-3.6.1-3.cm2.x86_64.rpm libarchive-devel-3.6.1-3.cm2.x86_64.rpm @@ -215,9 +215,9 @@ libtasn1-debuginfo-4.19.0-1.cm2.x86_64.rpm libtasn1-devel-4.19.0-1.cm2.x86_64.rpm libtool-2.4.6-8.cm2.x86_64.rpm libtool-debuginfo-2.4.6-8.cm2.x86_64.rpm -libxml2-2.10.4-3.cm2.x86_64.rpm -libxml2-debuginfo-2.10.4-3.cm2.x86_64.rpm -libxml2-devel-2.10.4-3.cm2.x86_64.rpm +libxml2-2.10.4-4.cm2.x86_64.rpm +libxml2-debuginfo-2.10.4-4.cm2.x86_64.rpm +libxml2-devel-2.10.4-4.cm2.x86_64.rpm libxslt-1.1.34-7.cm2.x86_64.rpm libxslt-debuginfo-1.1.34-7.cm2.x86_64.rpm libxslt-devel-1.1.34-7.cm2.x86_64.rpm @@ -516,28 +516,28 @@ procps-ng-devel-3.3.17-2.cm2.x86_64.rpm procps-ng-lang-3.3.17-2.cm2.x86_64.rpm pyproject-rpm-macros-1.0.0~rc1-4.cm2.noarch.rpm python-markupsafe-debuginfo-2.1.0-1.cm2.x86_64.rpm -python3-3.9.19-4.cm2.x86_64.rpm +python3-3.9.19-5.cm2.x86_64.rpm python3-audit-3.0.6-8.cm2.x86_64.rpm python3-cracklib-2.9.7-5.cm2.x86_64.rpm -python3-curses-3.9.19-4.cm2.x86_64.rpm +python3-curses-3.9.19-5.cm2.x86_64.rpm python3-Cython-0.29.33-2.cm2.x86_64.rpm -python3-debuginfo-3.9.19-4.cm2.x86_64.rpm -python3-devel-3.9.19-4.cm2.x86_64.rpm +python3-debuginfo-3.9.19-5.cm2.x86_64.rpm +python3-devel-3.9.19-5.cm2.x86_64.rpm python3-gpg-1.16.0-2.cm2.x86_64.rpm python3-jinja2-3.0.3-4.cm2.noarch.rpm python3-libcap-ng-0.8.2-2.cm2.x86_64.rpm -python3-libs-3.9.19-4.cm2.x86_64.rpm -python3-libxml2-2.10.4-3.cm2.x86_64.rpm +python3-libs-3.9.19-5.cm2.x86_64.rpm +python3-libxml2-2.10.4-4.cm2.x86_64.rpm python3-lxml-4.9.1-1.cm2.x86_64.rpm python3-magic-5.40-2.cm2.noarch.rpm python3-markupsafe-2.1.0-1.cm2.x86_64.rpm python3-newt-0.52.21-5.cm2.x86_64.rpm -python3-pip-3.9.19-4.cm2.noarch.rpm +python3-pip-3.9.19-5.cm2.noarch.rpm python3-pygments-2.4.2-7.cm2.noarch.rpm python3-rpm-4.18.0-4.cm2.x86_64.rpm -python3-setuptools-3.9.19-4.cm2.noarch.rpm -python3-test-3.9.19-4.cm2.x86_64.rpm -python3-tools-3.9.19-4.cm2.x86_64.rpm +python3-setuptools-3.9.19-5.cm2.noarch.rpm +python3-test-3.9.19-5.cm2.x86_64.rpm +python3-tools-3.9.19-5.cm2.x86_64.rpm readline-8.1-1.cm2.x86_64.rpm readline-debuginfo-8.1-1.cm2.x86_64.rpm readline-devel-8.1-1.cm2.x86_64.rpm diff --git a/toolkit/scripts/check_entangled_specs.py b/toolkit/scripts/check_entangled_specs.py index 0d2e608e9c7..87edc6d5e0d 100755 --- a/toolkit/scripts/check_entangled_specs.py +++ b/toolkit/scripts/check_entangled_specs.py @@ -2,15 +2,15 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +from collections import defaultdict +from os import path from typing import FrozenSet, List, Set -from pyrpm.spec import Spec - import argparse -from collections import defaultdict -from pathlib import Path import pprint import sys +from pyrpm.spec import replace_macros, Spec + version_release_matching_groups = [ frozenset([ "SPECS-SIGNED/kernel-signed/kernel-signed.spec", @@ -75,10 +75,10 @@ def check_spec_tags(base_path: str, tags: List[str], groups: List[FrozenSet]) -> variants = defaultdict(set) for spec_filename in group: - parsed_spec = Spec.from_file(Path(base_path, spec_filename)) + parsed_spec = Spec.from_file(path.join(base_path, spec_filename)) for tag in tags: - variants[tag].add(getattr( - parsed_spec, tag)) + tag_value = get_tag_value(parsed_spec, tag) + variants[tag].add(tag_value) for tag in tags: if len(variants[tag]) > 1: @@ -118,6 +118,13 @@ def check_matches(base_path: str): sys.exit(1) +def get_tag_value(spec: "Spec", tag: str) -> str: + value = getattr(spec, tag) + if value: + value = replace_macros(value, spec) + return value + + if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument(