From 3d13188032c3784ecbf7a9cb6111aefe6bf7ba61 Mon Sep 17 00:00:00 2001 From: Andy Jordan <2226434+andyleejordan@users.noreply.github.com> Date: Fri, 24 Apr 2026 15:43:50 -0700 Subject: [PATCH] Fix executable permissions for pwsh and createdump The tarball staging path used `Copy-Item`, which on *nix doesn't preserve the source file mode, so `pwsh` ended up 644 in the `.tar.gz`. The Debian, RPM, and macOS PKG paths explicitly `chmod` everything to 644 and then bump `pwsh` back to 755, which silently demoted `createdump` (the .NET helper that produces crash minidumps) along with it. Now we `chmod 755` both executables in all package staging paths, guarded by `Test-Path` since fxdependent builds don't bundle `createdump`. Also added regression tests which check the permissions of `pwsh` inside the Linux and macOS tarballs before we upload them. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .pipelines/templates/linux-package-build.yml | 7 ++++++ .pipelines/templates/mac-package-build.yml | 4 ++++ tools/packaging/packaging.psm1 | 24 +++++++++++++++++++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/.pipelines/templates/linux-package-build.yml b/.pipelines/templates/linux-package-build.yml index 1487455107..56988523a8 100644 --- a/.pipelines/templates/linux-package-build.yml +++ b/.pipelines/templates/linux-package-build.yml @@ -193,6 +193,13 @@ jobs: $pkgPath = Get-ChildItem -Path $(Pipeline.Workspace) -Filter $pkgFilter -Recurse -File | Select-Object -ExpandProperty FullName Write-Verbose -Verbose "pkgPath: $pkgPath" Copy-Item -Path $pkgPath -Destination '$(ob_outputDirectory)' -Force -Verbose + + if ($pkgPath -like '*.tar.gz') { + $entry = & tar -tzvf $pkgPath | Where-Object { $_ -match '\spwsh$' } | Select-Object -First 1 + if ($entry -notmatch '^-..x') { + throw "pwsh is not executable in $pkgPath : $entry" + } + } displayName: 'Copy artifacts to output directory' env: __DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY) diff --git a/.pipelines/templates/mac-package-build.yml b/.pipelines/templates/mac-package-build.yml index 154cb6c025..416ee9f40c 100644 --- a/.pipelines/templates/mac-package-build.yml +++ b/.pipelines/templates/mac-package-build.yml @@ -162,6 +162,10 @@ jobs: foreach($t in $tarPkgPath) { $file = $t.FullName + $entry = & tar -tzvf $file | Where-Object { $_ -match '\spwsh$' } | Select-Object -First 1 + if ($entry -notmatch '^-..x') { + throw "pwsh is not executable in $file : $entry" + } Write-Verbose -verbose "Uploading $file to macos-pkgs" Write-Host "##vso[artifact.upload containerfolder=macos-pkgs;artifactname=macos-pkgs]$file" } diff --git a/tools/packaging/packaging.psm1 b/tools/packaging/packaging.psm1 index 085c2478cd..e88e8f191a 100644 --- a/tools/packaging/packaging.psm1 +++ b/tools/packaging/packaging.psm1 @@ -794,6 +794,18 @@ function New-TarballPackage { $Staging = "$PSScriptRoot/staging" New-StagingFolder -StagingPath $Staging -PackageSourcePath $PackageSourcePath -R2RVerification $R2RVerification + # Ensure PowerShell executable has correct permissions in tarball + $pwshInStaging = Join-Path $Staging 'pwsh' + if (Test-Path -LiteralPath $pwshInStaging) { + Start-NativeExecution { chmod 755 $pwshInStaging } + } + + # Included .NET executable for producing crash dumps + $createdumpInStaging = Join-Path $Staging 'createdump' + if (Test-Path -LiteralPath $createdumpInStaging) { + Start-NativeExecution { chmod 755 $createdumpInStaging } + } + if (Get-Command -Name tar -CommandType Application -ErrorAction Ignore) { if ($Force -or $PSCmdlet.ShouldProcess("Create tarball package")) { $options = "-czf" @@ -1212,7 +1224,11 @@ function New-UnixPackage { find $Staging -type f | xargs chmod 644 chmod 644 $ManGzipInfo.GzipFile # refers to executable, does not vary by channel - chmod 755 "$Staging/pwsh" #only the executable file should be granted the execution permission + chmod 755 "$Staging/pwsh" # only the executable file should be granted the execution permission + # Included .NET executable for producing crash dumps + if (Test-Path "$Staging/createdump") { + chmod 755 "$Staging/createdump" + } } } @@ -1892,6 +1908,12 @@ $(if ($extendedDescription) { $extendedDescription + "`n" }) Start-NativeExecution { chmod 755 $pwshPath } } + # Included .NET executable for producing crash dumps + $createdumpPath = "$targetPath/createdump" + if (Test-Path $createdumpPath) { + Start-NativeExecution { chmod 755 $createdumpPath } + } + # Calculate md5sums for all files in data directory (excluding symlinks) $md5sumsFile = Join-Path $debianDir "md5sums" $md5Content = ""