Skip to content

Commit d5ea63a

Browse files
authored
Merge branch 'main' into dependabot/github_actions/actions-monthly-1ac88f8dce
2 parents c3c9b8a + cd2c9be commit d5ea63a

9 files changed

Lines changed: 99 additions & 89 deletions

File tree

‎.github/actions/setup-hardened-python/action.yml‎

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ inputs:
2626
venv:
2727
description: Directory for the venv. Defaults to a new directory under RUNNER_TEMP.
2828
default: ""
29+
stack-reserve:
30+
description: >-
31+
Windows only. Raise the base interpreter's main-thread stack reserve to at
32+
least this many bytes. Empty (default) leaves the interpreter unchanged.
33+
default: ""
2934

3035
outputs:
3136
python-path:
@@ -123,3 +128,41 @@ runs:
123128
PYTHON: ${{ steps.venv.outputs.python-path }}
124129
run: |
125130
"${PYTHON}" -m pip install -U pip
131+
132+
- name: Raise the interpreter's stack reserve
133+
if: runner.os == 'Windows' && inputs.stack-reserve != ''
134+
shell: bash --noprofile --norc -xeuo pipefail {0}
135+
env:
136+
PYTHON: ${{ steps.venv.outputs.python-path }}
137+
STACK_RESERVE: ${{ inputs.stack-reserve }}
138+
run: |
139+
# sys.stdout.write avoids a trailing CR from Windows Python's CRLF.
140+
base="$("${PYTHON}" -c 'import sys; sys.stdout.write(sys._base_executable)')"
141+
# Windows cannot overwrite a running executable. Prepare a copy and
142+
# replace the original after the patching interpreter exits.
143+
uv run --no-project --isolated --with pefile==2024.8.26 --python "${base}" python - "${base}" "${STACK_RESERVE}" <<'EOF'
144+
import sys
145+
146+
import pefile
147+
148+
path, reserve = sys.argv[1], int(sys.argv[2])
149+
if reserve <= 0:
150+
raise ValueError("stack-reserve must be a positive number of bytes")
151+
with pefile.PE(path) as pe:
152+
pe.OPTIONAL_HEADER.SizeOfStackReserve = max(pe.OPTIONAL_HEADER.SizeOfStackReserve, reserve)
153+
pe.write(path + ".stack-reserve")
154+
EOF
155+
mv -f -- "${base}.stack-reserve" "${base}"
156+
# Verify the running interpreter's stack, rather than just its header.
157+
"${base}" - "${STACK_RESERVE}" <<'EOF'
158+
import ctypes
159+
import sys
160+
161+
lo, hi = ctypes.c_size_t(), ctypes.c_size_t()
162+
get_limits = ctypes.windll.kernel32.GetCurrentThreadStackLimits
163+
get_limits.argtypes = [ctypes.POINTER(ctypes.c_size_t), ctypes.POINTER(ctypes.c_size_t)]
164+
get_limits.restype = None
165+
get_limits(ctypes.byref(lo), ctypes.byref(hi))
166+
print("main-thread stack reserve:", hi.value - lo.value)
167+
sys.exit(hi.value - lo.value < int(sys.argv[1]))
168+
EOF

‎.github/actions/upgrade-ca-certificates/emudhra_intermediates.ps1‎

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,33 @@
1414
$EmudhraIntermediatesPath = Join-Path $PSScriptRoot 'impacted-intermediates.json'
1515
$EmudhraIntermediatesCount = 16
1616

17+
# Uppercase hex SHA-256 of the certificate's DER encoding. Computed directly
18+
# because X509Certificate.GetCertHashString(HashAlgorithmName) does not exist
19+
# in Windows PowerShell 5.1 (.NET Framework).
20+
function Get-CertificateSha256([System.Security.Cryptography.X509Certificates.X509Certificate2]$Cert) {
21+
$sha256 = [System.Security.Cryptography.SHA256]::Create()
22+
try {
23+
return [System.BitConverter]::ToString($sha256.ComputeHash($Cert.RawData)).Replace('-', '')
24+
} finally {
25+
$sha256.Dispose()
26+
}
27+
}
28+
1729
# Returns the certificates as X509Certificate2 objects; callers dispose them.
30+
# Works on both Windows PowerShell 5.1 and PowerShell 7+.
1831
function Get-EmudhraIntermediates {
19-
$entries = @(Get-Content -LiteralPath $EmudhraIntermediatesPath -Raw | ConvertFrom-Json)
32+
# Windows PowerShell 5.1's ConvertFrom-Json emits a JSON array as a single
33+
# object; piping it through ForEach-Object enumerates it on both versions.
34+
$parsed = Get-Content -LiteralPath $EmudhraIntermediatesPath -Raw | ConvertFrom-Json
35+
$entries = @($parsed | ForEach-Object { $_ })
2036
if ($entries.Count -ne $EmudhraIntermediatesCount) {
2137
throw "Expected $EmudhraIntermediatesCount certificates in $EmudhraIntermediatesPath, found $($entries.Count)."
2238
}
2339
foreach ($entry in $entries) {
24-
$cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::CreateFromPem($entry.pem)
25-
if ($cert.GetCertHashString('SHA256') -ne $entry.sha256.ToUpperInvariant()) {
40+
# X509Certificate2.CreateFromPem is .NET 5+ only; decode the PEM body manually.
41+
$der = [System.Convert]::FromBase64String(($entry.pem -replace '-----[A-Z ]+-----', '' -replace '\s', ''))
42+
$cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($der)
43+
if ((Get-CertificateSha256 $cert) -ne $entry.sha256.ToUpperInvariant()) {
2644
$cert.Dispose()
2745
throw "SHA-256 mismatch for $($entry.name) (issued by $($entry.issued_by))."
2846
}
@@ -40,7 +58,10 @@ function Test-ExplicitlyDistrusted([System.Security.Cryptography.X509Certificate
4058
$chain = [System.Security.Cryptography.X509Certificates.X509Chain]::new()
4159
try {
4260
$chain.ChainPolicy.RevocationMode = [System.Security.Cryptography.X509Certificates.X509RevocationMode]::NoCheck
43-
$chain.ChainPolicy.DisableCertificateDownloads = $true
61+
# DisableCertificateDownloads does not exist on .NET Framework (Windows PowerShell 5.1).
62+
if ($chain.ChainPolicy | Get-Member -Name DisableCertificateDownloads) {
63+
$chain.ChainPolicy.DisableCertificateDownloads = $true
64+
}
4465
[void]$chain.Build($Cert)
4566
$statuses = @($chain.ChainStatus) + @($chain.ChainElements | ForEach-Object { $_.ChainElementStatus })
4667
return [bool]($statuses | Where-Object { $_.Status.HasFlag($explicitDistrust) })

‎.github/workflows/coverage.yml‎

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -242,22 +242,15 @@ jobs:
242242
submodules: true
243243

244244
- name: Set up Python
245-
uses: ./.github/actions/setup-hardened-python
245+
uses: $/.github/actions/setup-hardened-python
246246
with:
247247
python-version: ${{ env.PY_VER }}
248248
venv: .venv
249+
stack-reserve: 8388608
249250

250251
- name: Set up MSVC
251252
uses: step-security/msvc-dev-cmd@22c98154b708dbd743e6f27a933cf6ceba3305c4 # v1.13.1
252253

253-
- name: Raise the interpreter's stack reserve to 8 MiB
254-
# Importing the coverage-built cuda.bindings.driver overflows the
255-
# 2,000,000-byte main-thread stack of python-build-standalone (#3330).
256-
run: |
257-
base_py="$(.venv/Scripts/python -c 'import sys; print(sys._base_executable)')"
258-
editbin -nologo -stack:8388608 "$base_py"
259-
dumpbin -nologo -headers "$base_py" | grep -i "size of stack reserve"
260-
261254
- name: Set up mini CTK
262255
uses: ./.github/actions/fetch_ctk
263256
continue-on-error: false
@@ -381,10 +374,11 @@ jobs:
381374
nvidia-smi
382375
383376
- name: Set up Python
384-
uses: ./.github/actions/setup-hardened-python
377+
uses: $/.github/actions/setup-hardened-python
385378
with:
386379
python-version: ${{ env.PY_VER }}
387380
venv: .venv
381+
stack-reserve: 8388608
388382

389383
- name: Set up mini CTK
390384
uses: ./.github/actions/fetch_ctk
@@ -435,22 +429,22 @@ jobs:
435429
cd "${{ steps.install-root.outputs.INSTALL_ROOT }}"
436430
"$GITHUB_WORKSPACE/.venv/Scripts/pytest" -v --cov=./cuda --cov-append --cov-context=test --cov-config="$GITHUB_WORKSPACE/.coveragerc" "$GITHUB_WORKSPACE/cuda_pathfinder/tests"
437431
438-
# Cython linetrace under coverage on Windows needs more stack than the
439-
# default 1 MB thread size. The helper runs pytest on an 8 MB thread.
440-
- name: Run cuda.bindings tests (with 8MB stack)
432+
# The patched interpreter provides the larger stack on the main thread
433+
# and in child interpreters. Deferred cleanup needs pytest on the main thread.
434+
- name: Run cuda.bindings tests
441435
continue-on-error: true
442436
run: |
443-
"$GITHUB_WORKSPACE/.venv/Scripts/python" "$GITHUB_WORKSPACE/ci/tools/run_pytest_with_stack.py" \
444-
--cwd "${{ steps.install-root.outputs.INSTALL_ROOT }}" \
437+
cd "${{ steps.install-root.outputs.INSTALL_ROOT }}"
438+
"$GITHUB_WORKSPACE/.venv/Scripts/python" -m pytest \
445439
-v --cov=./cuda --cov-append --cov-context=test \
446440
--cov-config="$GITHUB_WORKSPACE/.coveragerc" \
447441
"$GITHUB_WORKSPACE/cuda_bindings_13/tests"
448442
449-
- name: Run cuda.core tests (with 8MB stack)
443+
- name: Run cuda.core tests
450444
continue-on-error: true
451445
run: |
452-
"$GITHUB_WORKSPACE/.venv/Scripts/python" "$GITHUB_WORKSPACE/ci/tools/run_pytest_with_stack.py" \
453-
--cwd "${{ steps.install-root.outputs.INSTALL_ROOT }}" \
446+
cd "${{ steps.install-root.outputs.INSTALL_ROOT }}"
447+
"$GITHUB_WORKSPACE/.venv/Scripts/python" -m pytest \
454448
-v --cov=./cuda --cov-append --cov-context=test \
455449
--cov-config="$GITHUB_WORKSPACE/.coveragerc" \
456450
"$GITHUB_WORKSPACE/cuda_core/tests"

‎.github/workflows/runner-trust-probe.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ jobs:
134134
135135
- name: Probe Windows OS trust store
136136
if: ${{ runner.os == 'Windows' }}
137-
shell: pwsh
137+
shell: powershell
138138
run: ./ci/tools/runner_trust_probe.ps1
139139

140140
- name: Probe Node 20 action runtime (informational)

‎.github/workflows/test-wheel-linux.yml‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -565,10 +565,6 @@ jobs:
565565
# that cuda-core version shipped with.
566566
pip install --upgrade "pip>=25.1"
567567
pip install --group "${CUDA_CORE_TEST_GROUP}"
568-
# Cap pytest below 9.1: released cuda-core <=1.0.1 has parametrize
569-
# patterns that pytest 9.1 rejects; the main-side fix (#2212) has
570-
# not yet shipped in a cuda-core release.
571-
pip install "pytest<9.1"
572568
# Version-gated deselects: drop automatically when a newer
573569
# cuda-core release ships that removes each source.
574570
DESELECTS=()

‎.github/workflows/test-wheel-windows.yml‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -537,9 +537,6 @@ jobs:
537537
pushd cuda-core-released/cuda_core
538538
pip install --upgrade "pip>=25.1"
539539
pip install --group "${CUDA_CORE_TEST_GROUP}"
540-
# Cap pytest below 9.1 — released cuda-core <=1.0.1 has parametrize
541-
# patterns that pytest 9.1 rejects (see #2212).
542-
pip install "pytest<9.1"
543540
# Version-gated deselects — dropped automatically when a newer
544541
# cuda-core release ships. See linux step for full rationale on
545542
# NvlinkVersion. The Windows-only tests are:

‎ci/tools/run_pytest_with_stack.py‎

Lines changed: 0 additions & 54 deletions
This file was deleted.

‎ci/tools/runner_trust_probe.ps1‎

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#
55
# runner_trust_probe.ps1 -- probe the Windows certificate store on a CI runner
66
# for the compromised eMudhra intermediates and their Sectigo cross-signs.
7+
# Compatible with Windows PowerShell 5.1 (`shell: powershell`) and PowerShell 7+.
78

89
$ErrorActionPreference = 'Stop'
910

@@ -21,7 +22,8 @@ $SummaryFile = $env:GITHUB_STEP_SUMMARY
2122

2223
function Append-Summary([string]$Line) {
2324
if ($SummaryFile) {
24-
Add-Content -Path $SummaryFile -Value $Line -Encoding utf8
25+
# Windows PowerShell 5.1's `-Encoding utf8` emits a BOM; write BOM-less UTF-8 explicitly.
26+
[System.IO.File]::AppendAllText($SummaryFile, "$Line`n", [System.Text.UTF8Encoding]::new($false))
2527
}
2628
}
2729

@@ -40,9 +42,9 @@ Append-Summary "| --- | --- | --- |"
4042
# 1. Root anchor state (informational). Microsoft's fix blocks the
4143
# intermediates and leaves the root in place, so this is not a pass criterion.
4244
$rootCerts = @(Get-ChildItem -Path 'Cert:\LocalMachine\Root' -ErrorAction Stop)
43-
$inRoot = [bool]($rootCerts | Where-Object { $_.GetCertHashString('SHA256') -eq $EmSignG3Hex })
45+
$inRoot = [bool]($rootCerts | Where-Object { (Get-CertificateSha256 $_) -eq $EmSignG3Hex })
4446
$inDisallowed = [bool](Get-ChildItem -Path 'Cert:\LocalMachine\Disallowed' -ErrorAction SilentlyContinue |
45-
Where-Object { $_.GetCertHashString('SHA256') -eq $EmSignG3Hex })
47+
Where-Object { (Get-CertificateSha256 $_) -eq $EmSignG3Hex })
4648
Record-Check 'emSign ECC Root CA - G3 store state' 'INFO' "LocalMachine\Root=$inRoot ($($rootCerts.Count) certs), LocalMachine\Disallowed=$inDisallowed"
4749

4850
# 2. All compromised intermediates and cross-signs explicitly distrusted (gating)
@@ -59,17 +61,24 @@ if ($notDistrusted.Count -eq 0) {
5961
$GatingFailures++
6062
}
6163

62-
# 3. OS-store client (Invoke-WebRequest) rejects each test endpoint (only a successful connection fails the job)
64+
# 3. OS-store client (Invoke-WebRequest) rejects each test endpoint (only a successful connection fails the job).
65+
# -SkipHttpErrorCheck is PowerShell 7+ only, so HTTP error statuses are caught below instead:
66+
# any response at all means the TLS handshake (and thus the certificate chain) succeeded.
6367
$progTmp = $ProgressPreference
6468
$ProgressPreference = 'SilentlyContinue'
6569
try {
6670
foreach ($endpoint in $TestEndpoints) {
6771
$checkName = "Invoke-WebRequest rejects ``$endpoint``"
6872
try {
69-
$res = Invoke-WebRequest -Uri $endpoint -UseBasicParsing -SkipHttpErrorCheck -TimeoutSec 15
73+
$res = Invoke-WebRequest -Uri $endpoint -UseBasicParsing -TimeoutSec 15
7074
Record-Check $checkName 'FAIL' "Connection succeeded with HTTP $($res.StatusCode) (certificate was trusted)"
7175
$GatingFailures++
7276
} catch {
77+
if ($null -ne $_.Exception.Response) {
78+
Record-Check $checkName 'FAIL' "Connection succeeded with HTTP $([int]$_.Exception.Response.StatusCode) (certificate was trusted)"
79+
$GatingFailures++
80+
continue
81+
}
7382
$certRejected = $false
7483
$hostnameMismatchOnly = $false
7584
$ex = $_.Exception

‎ci/versions.yml‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@
33

44
backport_branch: "12.9.x" # keep in sync with target-branch in .github/dependabot.yml
55

6+
# This controls the version of the upstream CTK to install to build the wheels.
7+
# It is not the version of cuda_bindings/cuda_python being released, which is
8+
# solely determined by git tags via setuptools_scm.
69
cuda:
710
build:
811
version: "13.4.2"
912
prev_build:
1013
version: "12.9.1"
14+
1115
python:
1216
# Python versions the wheel matrix is built across. ci.yml reads this list
1317
# and passes it to build-wheel.yml as the `python-versions` input.

0 commit comments

Comments
 (0)