Skip to content

Commit

Permalink
fix how we find parent process (#472)
Browse files Browse the repository at this point in the history
Turns out BusyBox only implements a small portion of the [POSIX spec][1]
for its [ps][2], so our code that gets the parent process (and hence
`bmx print`) never worked on Alpine...
(I guess no one ever used `bmx print` on alpine...)

Switch to use native API call, which is actually easier.

[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html
[2]: https://boxmatrix.info/wiki/Property:ps

https://desire2learn.atlassian.net/browse/VUL-403
  • Loading branch information
cfbao authored Jul 26, 2024
1 parent 96473de commit d8e59c1
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 70 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ jobs:
Throw "Tag name format incorrect"
}
if ($env:PRERELEASE -eq 'true') {
$releaseUrl = gh release create "$env:RELEASE_TAG" --repo Brightspace/bmx --draft --prerelease --generate-notes --title "Release $env:RELEASE_TAG"
$releaseUrl = gh release create "$env:RELEASE_TAG" --repo Brightspace/bmx --draft --prerelease --generate-notes --title "Release $env:RELEASE_TAG" --target $env:GITHUB_SHA
} else {
$releaseUrl = gh release create "$env:RELEASE_TAG" --repo Brightspace/bmx --draft --generate-notes --title "Release $env:RELEASE_TAG"
$releaseUrl = gh release create "$env:RELEASE_TAG" --repo Brightspace/bmx --draft --generate-notes --title "Release $env:RELEASE_TAG" --target $env:GITHUB_SHA
}
if ( $LASTEXITCODE -ne 0 ) { throw "Failed to create draft release" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,41 @@
using System.Runtime.InteropServices;

namespace D2L.Bmx;

/**
This file may eventually be replaced if the following dotnet runtime api proposals are implemented:
- https://github.com/dotnet/runtime/issues/21941
- https://github.com/dotnet/runtime/issues/24423
Uses the same approach of calling NtQueryInformationProcess as in the PowerShell library
https://github.com/PowerShell/PowerShell/blob/26f621952910e33840efb0c539fbef1e2a467a0d/src/System.Management.Automation/engine/ProcessCodeMethods.cs
*/
internal partial class WindowsParentProcess {
internal partial class ParentProcess {
public static string? GetParentProcessName() {
int parentPid = -1;
if( OperatingSystem.IsWindows() ) {
parentPid = GetWindowsParentProcessId();
} else if( OperatingSystem.IsLinux() || OperatingSystem.IsMacOS() ) {
parentPid = GetPosixParentProcessId();
}
if( parentPid == -1 ) {
return null;
}
return Process.GetProcessById( parentPid ).ProcessName;
}

[LibraryImport( "ntdll.dll", EntryPoint = "NtQueryInformationProcess" )]
internal static partial int NtQueryInformationProcess(
IntPtr processHandle,
int processInformationClass,
ref PROCESS_BASIC_INFORMATION processInformation,
int processInformationLength,
out int returnLength
);
[LibraryImport( "libc", EntryPoint = "getppid" )]
private static partial int GetPosixParentProcessId();

internal struct PROCESS_BASIC_INFORMATION {
public IntPtr ExitStatus;
public IntPtr PebBaseAddress;
public IntPtr AffinityMask;
public IntPtr BasePriority;
public UIntPtr UniqueProcessId;
public UIntPtr InheritedFromUniqueProcessId;
}

private static int GetParentProcessId() {
// Uses the same approach of calling NtQueryInformationProcess as in the PowerShell library
// https://github.com/PowerShell/PowerShell/blob/26f621952910e33840efb0c539fbef1e2a467a0d/src/System.Management.Automation/engine/ProcessCodeMethods.cs
private static int GetWindowsParentProcessId() {
var proc = Process.GetCurrentProcess();
var pbi = new PROCESS_BASIC_INFORMATION();
int status = NtQueryInformationProcess(
proc.Handle,
0,
ref pbi,
Marshal.SizeOf<PROCESS_BASIC_INFORMATION>(),
out int infoLen
out _
);

if( status != 0 ) {
Expand All @@ -47,7 +45,21 @@ out int infoLen
return (int)pbi.InheritedFromUniqueProcessId;
}

public static string GetParentProcessName() {
return Process.GetProcessById( GetParentProcessId() ).ProcessName;
[LibraryImport( "ntdll.dll" )]
private static partial int NtQueryInformationProcess(
IntPtr processHandle,
int processInformationClass,
ref PROCESS_BASIC_INFORMATION processInformation,
int processInformationLength,
out int returnLength
);

private struct PROCESS_BASIC_INFORMATION {
public IntPtr ExitStatus;
public IntPtr PebBaseAddress;
public IntPtr AffinityMask;
public IntPtr BasePriority;
public UIntPtr UniqueProcessId;
public UIntPtr InheritedFromUniqueProcessId;
}
}
9 changes: 1 addition & 8 deletions src/D2L.Bmx/PrintHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,7 @@ bool cacheAwsCredentials
} else if( string.Equals( format, PrintFormat.Json, StringComparison.OrdinalIgnoreCase ) ) {
PrintJson( awsCreds );
} else {
string? procName = null;
if( OperatingSystem.IsWindows() ) {
procName = WindowsParentProcess.GetParentProcessName().ToLower();
} else if( OperatingSystem.IsLinux() || OperatingSystem.IsMacOS() ) {
procName = UnixParentProcess.GetParentProcessName().ToLower();
}

switch( procName ) {
switch( ParentProcess.GetParentProcessName() ) {
case "pwsh":
case "powershell":
PrintPowershell( awsCreds );
Expand Down
36 changes: 0 additions & 36 deletions src/D2L.Bmx/UnixParentProcess.cs

This file was deleted.

0 comments on commit d8e59c1

Please sign in to comment.