From 6aa12ea7f09604b75789f26935615a430d7bd499 Mon Sep 17 00:00:00 2001 From: Rebecca Mahany-Horton Date: Fri, 17 Nov 2023 09:36:22 -0500 Subject: [PATCH 1/8] Make package for nixos support --- pkg/allowedcmd/cmd.go | 14 +++----------- pkg/nixos/check_linux.go | 11 +++++++++++ pkg/nixos/check_other.go | 5 +++++ 3 files changed, 19 insertions(+), 11 deletions(-) create mode 100644 pkg/nixos/check_linux.go create mode 100644 pkg/nixos/check_other.go diff --git a/pkg/allowedcmd/cmd.go b/pkg/allowedcmd/cmd.go index eb054b761..40e2cefa4 100644 --- a/pkg/allowedcmd/cmd.go +++ b/pkg/allowedcmd/cmd.go @@ -6,7 +6,8 @@ import ( "os" "os/exec" "path/filepath" - "runtime" + + "github.com/kolide/launcher/pkg/nixos" ) type AllowedCommand func(ctx context.Context, arg ...string) (*exec.Cmd, error) @@ -38,14 +39,5 @@ func validatedCommand(ctx context.Context, knownPath string, arg ...string) (*ex } func allowSearchPath() bool { - if runtime.GOOS != "linux" { - return false - } - - // We only allow searching for binaries in PATH on NixOS - if _, err := os.Stat("/etc/NIXOS"); err == nil { - return true - } - - return false + return nixos.IsNixOS() } diff --git a/pkg/nixos/check_linux.go b/pkg/nixos/check_linux.go new file mode 100644 index 000000000..aa3d62ef6 --- /dev/null +++ b/pkg/nixos/check_linux.go @@ -0,0 +1,11 @@ +package nixos + +import "os" + +func IsNixOS() bool { + if _, err := os.Stat("/etc/NIXOS"); err == nil { + return true + } + + return false +} diff --git a/pkg/nixos/check_other.go b/pkg/nixos/check_other.go new file mode 100644 index 000000000..1f3f24da0 --- /dev/null +++ b/pkg/nixos/check_other.go @@ -0,0 +1,5 @@ +package nixos + +func IsNixOS() bool { + return false +} From bb2be512179386a3c0fc33b0cb1f17a088e39e9c Mon Sep 17 00:00:00 2001 From: Rebecca Mahany-Horton Date: Fri, 17 Nov 2023 15:37:02 -0500 Subject: [PATCH 2/8] Add finalize patchelf --- pkg/allowedcmd/cmd.go | 24 ++++++++++++++--- pkg/allowedcmd/cmd_linux.go | 4 +++ pkg/autoupdate/tuf/finalize_linux.go | 38 +++++++++++++++++++++++++++ pkg/autoupdate/tuf/finalize_other.go | 5 ++++ pkg/autoupdate/tuf/library_manager.go | 5 ++++ pkg/nixos/check_linux.go | 11 -------- pkg/nixos/check_other.go | 5 ---- 7 files changed, 73 insertions(+), 19 deletions(-) create mode 100644 pkg/autoupdate/tuf/finalize_linux.go create mode 100644 pkg/autoupdate/tuf/finalize_other.go delete mode 100644 pkg/nixos/check_linux.go delete mode 100644 pkg/nixos/check_other.go diff --git a/pkg/allowedcmd/cmd.go b/pkg/allowedcmd/cmd.go index 40e2cefa4..128908a51 100644 --- a/pkg/allowedcmd/cmd.go +++ b/pkg/allowedcmd/cmd.go @@ -6,8 +6,6 @@ import ( "os" "os/exec" "path/filepath" - - "github.com/kolide/launcher/pkg/nixos" ) type AllowedCommand func(ctx context.Context, arg ...string) (*exec.Cmd, error) @@ -39,5 +37,25 @@ func validatedCommand(ctx context.Context, knownPath string, arg ...string) (*ex } func allowSearchPath() bool { - return nixos.IsNixOS() + return IsNixOS() +} + +// Save results of lookup so we don't have to stat for /etc/NIXOS every time +// we want to know. +var ( + checkedIsNixOS = false + isNixOS = false +) + +func IsNixOS() bool { + if checkedIsNixOS { + return isNixOS + } + + if _, err := os.Stat("/etc/NIXOS"); err == nil { + isNixOS = true + } + + checkedIsNixOS = true + return isNixOS } diff --git a/pkg/allowedcmd/cmd_linux.go b/pkg/allowedcmd/cmd_linux.go index 4923644ed..35c08d78e 100644 --- a/pkg/allowedcmd/cmd_linux.go +++ b/pkg/allowedcmd/cmd_linux.go @@ -95,6 +95,10 @@ func Pacman(ctx context.Context, arg ...string) (*exec.Cmd, error) { return validatedCommand(ctx, "/usr/bin/pacman", arg...) } +func Patchelf(ctx context.Context, arg ...string) (*exec.Cmd, error) { + return validatedCommand(ctx, "/run/current-system/sw/bin/patchelf", arg...) +} + func Ps(ctx context.Context, arg ...string) (*exec.Cmd, error) { return validatedCommand(ctx, "/usr/bin/ps", arg...) } diff --git a/pkg/autoupdate/tuf/finalize_linux.go b/pkg/autoupdate/tuf/finalize_linux.go new file mode 100644 index 000000000..04013ded0 --- /dev/null +++ b/pkg/autoupdate/tuf/finalize_linux.go @@ -0,0 +1,38 @@ +package tuf + +import ( + "context" + "fmt" + "path/filepath" + "time" +) + +func patchExecutable(executableLocation string) error { + if !allowedcmd.IsNixOS() { + return nil + } + + interpreter, err := getLoader(executableLocation) + if err != nil { + return fmt.Errorf("getting loader for %s: %w", executableLocation, err) + } + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + cmd := allowedcmd.Patchelf(ctx, "--set-interpreter", interpreter, executableLocation) + if out, err := cmd.CombinedOutput(); err != nil { + return fmt.Errorf("running patchelf: output `%s`, error `%w`", string(out), err) + } + + return nil +} + +func getLoader(_ string) (string, error) { + matches, err := filepath.Glob("/nix/store/*glibc*/lib/ld-linux-x86-64.so.2") + if err != nil { + return "", fmt.Errorf("globbing for loader: %w", err) + } + + return matches[0], nil +} diff --git a/pkg/autoupdate/tuf/finalize_other.go b/pkg/autoupdate/tuf/finalize_other.go new file mode 100644 index 000000000..55859e843 --- /dev/null +++ b/pkg/autoupdate/tuf/finalize_other.go @@ -0,0 +1,5 @@ +package tuf + +func patchExecutable(executableLocation string) error { + return nil +} diff --git a/pkg/autoupdate/tuf/library_manager.go b/pkg/autoupdate/tuf/library_manager.go index 269934799..bd01ff61f 100644 --- a/pkg/autoupdate/tuf/library_manager.go +++ b/pkg/autoupdate/tuf/library_manager.go @@ -201,6 +201,11 @@ func (ulm *updateLibraryManager) moveVerifiedUpdate(binary autoupdatableBinary, return fmt.Errorf("could not set +x permissions on executable: %w", err) } + // If necessary, patch the executable (NixOS only) + if err := patchExecutable(executableLocation(stagedVersionedDirectory, binary)); err != nil { + return fmt.Errorf("could not patch executable: %w", err) + } + // Validate the executable if err := autoupdate.CheckExecutable(context.TODO(), executableLocation(stagedVersionedDirectory, binary), "--version"); err != nil { return fmt.Errorf("could not verify executable: %w", err) diff --git a/pkg/nixos/check_linux.go b/pkg/nixos/check_linux.go deleted file mode 100644 index aa3d62ef6..000000000 --- a/pkg/nixos/check_linux.go +++ /dev/null @@ -1,11 +0,0 @@ -package nixos - -import "os" - -func IsNixOS() bool { - if _, err := os.Stat("/etc/NIXOS"); err == nil { - return true - } - - return false -} diff --git a/pkg/nixos/check_other.go b/pkg/nixos/check_other.go deleted file mode 100644 index 1f3f24da0..000000000 --- a/pkg/nixos/check_other.go +++ /dev/null @@ -1,5 +0,0 @@ -package nixos - -func IsNixOS() bool { - return false -} From 76bc55d663c8224cff0ffa14c77ce7efb8838fc1 Mon Sep 17 00:00:00 2001 From: Rebecca Mahany-Horton Date: Tue, 21 Nov 2023 10:09:53 -0500 Subject: [PATCH 3/8] Read ELF headers to determine correct interpreter --- ee/tuf/finalize_linux.go | 46 ++++++++++++++++++++++++++++++++++------ ee/tuf/finalize_other.go | 3 +++ 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/ee/tuf/finalize_linux.go b/ee/tuf/finalize_linux.go index 04013ded0..f8a335f65 100644 --- a/ee/tuf/finalize_linux.go +++ b/ee/tuf/finalize_linux.go @@ -1,10 +1,17 @@ +//go:build linux +// +build linux + package tuf import ( "context" + "debug/elf" + "errors" "fmt" "path/filepath" "time" + + "github.com/kolide/launcher/pkg/allowedcmd" ) func patchExecutable(executableLocation string) error { @@ -12,15 +19,19 @@ func patchExecutable(executableLocation string) error { return nil } - interpreter, err := getLoader(executableLocation) + interpreter, err := getInterpreter(executableLocation) + if err != nil { + return fmt.Errorf("getting interpreter for %s: %w", executableLocation, err) + } + interpreterLocation, err := findInterpreterInNixStore(interpreter) if err != nil { - return fmt.Errorf("getting loader for %s: %w", executableLocation, err) + return fmt.Errorf("finding interpreter %s in nix store: %w", interpreter, err) } ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - cmd := allowedcmd.Patchelf(ctx, "--set-interpreter", interpreter, executableLocation) + cmd := allowedcmd.Patchelf(ctx, "--set-interpreter", interpreterLocation, executableLocation) if out, err := cmd.CombinedOutput(); err != nil { return fmt.Errorf("running patchelf: output `%s`, error `%w`", string(out), err) } @@ -28,10 +39,33 @@ func patchExecutable(executableLocation string) error { return nil } -func getLoader(_ string) (string, error) { - matches, err := filepath.Glob("/nix/store/*glibc*/lib/ld-linux-x86-64.so.2") +func getInterpreter(executableLocation string) (string, error) { + f, err := elf.Open(executableLocation) + if err != nil { + return "", fmt.Errorf("opening ELF file: %w", err) + } + defer f.Close() + + interpSection := f.Section(".interp") + if interpSection == nil { + return "", errors.New("no .interp section") + } + + interpData, err := interpSection.Data() + if err != nil { + return "", fmt.Errorf("reading .interp section: %w", err) + } + + // interpData should look something like "/lib64/ld-linux-x86-64.so.2" + return filepath.Base(string(interpData)), nil +} + +func findInterpreterInNixStore(interpreter string) (string, error) { + storeLocationPattern := filepath.Join("/nix/store/*glibc*/lib", interpreter) + + matches, err := filepath.Glob(storeLocationPattern) if err != nil { - return "", fmt.Errorf("globbing for loader: %w", err) + return "", fmt.Errorf("globbing for interpreter %s at %s: %w", interpreter, storeLocationPattern, err) } return matches[0], nil diff --git a/ee/tuf/finalize_other.go b/ee/tuf/finalize_other.go index 55859e843..b645ffbfe 100644 --- a/ee/tuf/finalize_other.go +++ b/ee/tuf/finalize_other.go @@ -1,3 +1,6 @@ +//go:build !linux +// +build !linux + package tuf func patchExecutable(executableLocation string) error { From 3d63d779073f6154e2468c53e4ba9112e55f15dc Mon Sep 17 00:00:00 2001 From: Rebecca Mahany-Horton Date: Tue, 21 Nov 2023 10:09:53 -0500 Subject: [PATCH 4/8] Read ELF headers to determine correct interpreter --- ee/tuf/finalize_linux.go | 50 +++++++++++++++++++++++++++++++++++----- ee/tuf/finalize_other.go | 3 +++ 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/ee/tuf/finalize_linux.go b/ee/tuf/finalize_linux.go index 04013ded0..569d0944c 100644 --- a/ee/tuf/finalize_linux.go +++ b/ee/tuf/finalize_linux.go @@ -1,10 +1,17 @@ +//go:build linux +// +build linux + package tuf import ( "context" + "debug/elf" + "errors" "fmt" "path/filepath" "time" + + "github.com/kolide/launcher/pkg/allowedcmd" ) func patchExecutable(executableLocation string) error { @@ -12,15 +19,23 @@ func patchExecutable(executableLocation string) error { return nil } - interpreter, err := getLoader(executableLocation) + interpreter, err := getInterpreter(executableLocation) if err != nil { - return fmt.Errorf("getting loader for %s: %w", executableLocation, err) + return fmt.Errorf("getting interpreter for %s: %w", executableLocation, err) + } + interpreterLocation, err := findInterpreterInNixStore(interpreter) + if err != nil { + return fmt.Errorf("finding interpreter %s in nix store: %w", interpreter, err) } ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - cmd := allowedcmd.Patchelf(ctx, "--set-interpreter", interpreter, executableLocation) + cmd, err := allowedcmd.Patchelf(ctx, "--set-interpreter", interpreterLocation, executableLocation) + if err != nil { + return fmt.Errorf("creating patchelf command: %w", err) + } + if out, err := cmd.CombinedOutput(); err != nil { return fmt.Errorf("running patchelf: output `%s`, error `%w`", string(out), err) } @@ -28,10 +43,33 @@ func patchExecutable(executableLocation string) error { return nil } -func getLoader(_ string) (string, error) { - matches, err := filepath.Glob("/nix/store/*glibc*/lib/ld-linux-x86-64.so.2") +func getInterpreter(executableLocation string) (string, error) { + f, err := elf.Open(executableLocation) + if err != nil { + return "", fmt.Errorf("opening ELF file: %w", err) + } + defer f.Close() + + interpSection := f.Section(".interp") + if interpSection == nil { + return "", errors.New("no .interp section") + } + + interpData, err := interpSection.Data() + if err != nil { + return "", fmt.Errorf("reading .interp section: %w", err) + } + + // interpData should look something like "/lib64/ld-linux-x86-64.so.2" + return filepath.Base(string(interpData)), nil +} + +func findInterpreterInNixStore(interpreter string) (string, error) { + storeLocationPattern := filepath.Join("/nix/store/*glibc*/lib", interpreter) + + matches, err := filepath.Glob(storeLocationPattern) if err != nil { - return "", fmt.Errorf("globbing for loader: %w", err) + return "", fmt.Errorf("globbing for interpreter %s at %s: %w", interpreter, storeLocationPattern, err) } return matches[0], nil diff --git a/ee/tuf/finalize_other.go b/ee/tuf/finalize_other.go index 55859e843..b645ffbfe 100644 --- a/ee/tuf/finalize_other.go +++ b/ee/tuf/finalize_other.go @@ -1,3 +1,6 @@ +//go:build !linux +// +build !linux + package tuf func patchExecutable(executableLocation string) error { From 2741611e2760c9376e13a42d3ca8613bfe5253fb Mon Sep 17 00:00:00 2001 From: RebeccaMahany Date: Tue, 21 Nov 2023 10:54:17 -0500 Subject: [PATCH 5/8] Add tests, documentation --- ee/tuf/finalize_linux.go | 10 ++++++++-- ee/tuf/finalize_linux_test.go | 24 ++++++++++++++++++++++++ ee/tuf/finalize_other_test.go | 17 +++++++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 ee/tuf/finalize_linux_test.go create mode 100644 ee/tuf/finalize_other_test.go diff --git a/ee/tuf/finalize_linux.go b/ee/tuf/finalize_linux.go index 569d0944c..0b935eff7 100644 --- a/ee/tuf/finalize_linux.go +++ b/ee/tuf/finalize_linux.go @@ -4,6 +4,7 @@ package tuf import ( + "bytes" "context" "debug/elf" "errors" @@ -14,6 +15,9 @@ import ( "github.com/kolide/launcher/pkg/allowedcmd" ) +// On NixOS, we have to set the interpreter for any non-NixOS executable we want to +// run. This means the binaries that our updater downloads. +// See: https://unix.stackexchange.com/a/522823 func patchExecutable(executableLocation string) error { if !allowedcmd.IsNixOS() { return nil @@ -60,8 +64,10 @@ func getInterpreter(executableLocation string) (string, error) { return "", fmt.Errorf("reading .interp section: %w", err) } - // interpData should look something like "/lib64/ld-linux-x86-64.so.2" - return filepath.Base(string(interpData)), nil + trimmedInterpData := bytes.TrimRight(interpData, "\x00") + + // interpData should look something like "/lib64/ld-linux-x86-64.so.2" -- grab just the filename + return filepath.Base(string(trimmedInterpData)), nil } func findInterpreterInNixStore(interpreter string) (string, error) { diff --git a/ee/tuf/finalize_linux_test.go b/ee/tuf/finalize_linux_test.go new file mode 100644 index 000000000..6d71ee222 --- /dev/null +++ b/ee/tuf/finalize_linux_test.go @@ -0,0 +1,24 @@ +//go:build linux +// +build linux + +package tuf + +import ( + "os" + "testing" + + "github.com/stretchr/testify/require" +) + +func Test_getInterpreter(t *testing.T) { + t.Parallel() + + // Use the current executable in our test + currentRunningExecutable, err := os.Executable() + require.NoError(t, err, "getting current executable") + + // Confirm we pick the expected interpreter + interpreter, err := getInterpreter(currentRunningExecutable) + require.NoError(t, err, "expected no error getting interpreter") + require.Equal(t, "ld-linux-x86-64.so.2", interpreter) +} diff --git a/ee/tuf/finalize_other_test.go b/ee/tuf/finalize_other_test.go new file mode 100644 index 000000000..8458c18a4 --- /dev/null +++ b/ee/tuf/finalize_other_test.go @@ -0,0 +1,17 @@ +//go:build !linux +// +build !linux + +package tuf + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func Test_patchExecutable(t *testing.T) { + t.Parallel() + + // patchExecutable is a no-op on windows and darwin + require.NoError(t, patchExecutable("")) +} From 325366ecc2689796a93a83dfd421f7bd44f2f0ae Mon Sep 17 00:00:00 2001 From: Rebecca Mahany-Horton Date: Tue, 21 Nov 2023 12:18:14 -0500 Subject: [PATCH 6/8] Fix rebase whoops --- ee/tuf/finalize_linux.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ee/tuf/finalize_linux.go b/ee/tuf/finalize_linux.go index a424ddda0..0b935eff7 100644 --- a/ee/tuf/finalize_linux.go +++ b/ee/tuf/finalize_linux.go @@ -64,15 +64,10 @@ func getInterpreter(executableLocation string) (string, error) { return "", fmt.Errorf("reading .interp section: %w", err) } -<<<<<<< HEAD - // interpData should look something like "/lib64/ld-linux-x86-64.so.2" - return filepath.Base(string(interpData)), nil -======= trimmedInterpData := bytes.TrimRight(interpData, "\x00") // interpData should look something like "/lib64/ld-linux-x86-64.so.2" -- grab just the filename return filepath.Base(string(trimmedInterpData)), nil ->>>>>>> 2741611e2760c9376e13a42d3ca8613bfe5253fb } func findInterpreterInNixStore(interpreter string) (string, error) { From aa6faea36504d96465a95f187a3c35e950234a63 Mon Sep 17 00:00:00 2001 From: Rebecca Mahany-Horton Date: Tue, 21 Nov 2023 12:29:28 -0500 Subject: [PATCH 7/8] Don't reload launcher if localdev_path is set --- ee/tuf/autoupdate.go | 9 ++++++--- ee/tuf/autoupdate_test.go | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ee/tuf/autoupdate.go b/ee/tuf/autoupdate.go index b8aaa52c9..9bf34159f 100644 --- a/ee/tuf/autoupdate.go +++ b/ee/tuf/autoupdate.go @@ -328,9 +328,12 @@ func (ta *TufAutoupdater) checkForUpdate() error { // If launcher was updated, we want to exit and reload if updatedVersion, ok := updatesDownloaded[binaryLauncher]; ok { - level.Debug(ta.logger).Log("msg", "launcher updated -- exiting to load new version", "new_binary_version", updatedVersion) - ta.signalRestart <- NewLauncherReloadNeededErr(updatedVersion) - return nil + // Only reload if we're not using a localdev path + if ta.knapsack.LocalDevelopmentPath() == "" { + level.Debug(ta.logger).Log("msg", "launcher updated -- exiting to load new version", "new_binary_version", updatedVersion) + ta.signalRestart <- NewLauncherReloadNeededErr(updatedVersion) + return nil + } } // For non-launcher binaries (i.e. osqueryd), call any reload functions we have saved diff --git a/ee/tuf/autoupdate_test.go b/ee/tuf/autoupdate_test.go index b45a6246f..207754feb 100644 --- a/ee/tuf/autoupdate_test.go +++ b/ee/tuf/autoupdate_test.go @@ -73,6 +73,7 @@ func TestExecute_launcherUpdate(t *testing.T) { mockKnapsack.On("TufServerURL").Return(tufServerUrl) mockKnapsack.On("UpdateDirectory").Return("") mockKnapsack.On("MirrorServerURL").Return("https://example.com") + mockKnapsack.On("LocalDevelopmentPath").Return("") mockQuerier := newMockQuerier(t) // Set up autoupdater From 50b30be126302f29a7a06355904947912fbb1bd5 Mon Sep 17 00:00:00 2001 From: RebeccaMahany Date: Wed, 22 Nov 2023 14:14:58 -0500 Subject: [PATCH 8/8] Use interpreter set by autopatchelfhook --- ee/tuf/finalize_linux.go | 51 +++++++++++++---------------------- ee/tuf/finalize_linux_test.go | 24 ----------------- 2 files changed, 19 insertions(+), 56 deletions(-) delete mode 100644 ee/tuf/finalize_linux_test.go diff --git a/ee/tuf/finalize_linux.go b/ee/tuf/finalize_linux.go index 0b935eff7..395eb5fc4 100644 --- a/ee/tuf/finalize_linux.go +++ b/ee/tuf/finalize_linux.go @@ -4,19 +4,18 @@ package tuf import ( - "bytes" "context" - "debug/elf" - "errors" "fmt" - "path/filepath" + "os" + "strings" "time" "github.com/kolide/launcher/pkg/allowedcmd" ) -// On NixOS, we have to set the interpreter for any non-NixOS executable we want to -// run. This means the binaries that our updater downloads. +// patchExecutable updates the downloaded binary as necessary for it to be able to +// run on this system. On NixOS, we have to set the interpreter for any non-NixOS +// executable we want to run. // See: https://unix.stackexchange.com/a/522823 func patchExecutable(executableLocation string) error { if !allowedcmd.IsNixOS() { @@ -27,15 +26,11 @@ func patchExecutable(executableLocation string) error { if err != nil { return fmt.Errorf("getting interpreter for %s: %w", executableLocation, err) } - interpreterLocation, err := findInterpreterInNixStore(interpreter) - if err != nil { - return fmt.Errorf("finding interpreter %s in nix store: %w", interpreter, err) - } ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - cmd, err := allowedcmd.Patchelf(ctx, "--set-interpreter", interpreterLocation, executableLocation) + cmd, err := allowedcmd.Patchelf(ctx, "--set-interpreter", interpreter, executableLocation) if err != nil { return fmt.Errorf("creating patchelf command: %w", err) } @@ -47,36 +42,28 @@ func patchExecutable(executableLocation string) error { return nil } +// getInterpreter asks patchelf what the interpreter is for the current running +// executable, assuming that's a reasonable choice given that the current executable +// is able to run. func getInterpreter(executableLocation string) (string, error) { - f, err := elf.Open(executableLocation) + currentExecutable, err := os.Executable() if err != nil { - return "", fmt.Errorf("opening ELF file: %w", err) + return "", fmt.Errorf("getting current running executable: %w", err) } - defer f.Close() - interpSection := f.Section(".interp") - if interpSection == nil { - return "", errors.New("no .interp section") - } + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() - interpData, err := interpSection.Data() + cmd, err := allowedcmd.Patchelf(ctx, "--print-interpreter", currentExecutable) if err != nil { - return "", fmt.Errorf("reading .interp section: %w", err) + return "", fmt.Errorf("creating patchelf command: %w", err) } - trimmedInterpData := bytes.TrimRight(interpData, "\x00") - - // interpData should look something like "/lib64/ld-linux-x86-64.so.2" -- grab just the filename - return filepath.Base(string(trimmedInterpData)), nil -} - -func findInterpreterInNixStore(interpreter string) (string, error) { - storeLocationPattern := filepath.Join("/nix/store/*glibc*/lib", interpreter) - - matches, err := filepath.Glob(storeLocationPattern) + out, err := cmd.CombinedOutput() if err != nil { - return "", fmt.Errorf("globbing for interpreter %s at %s: %w", interpreter, storeLocationPattern, err) + return "", fmt.Errorf("running patchelf: output `%s`, error `%w`", string(out), err) + } - return matches[0], nil + return strings.TrimSpace(string(out)), nil } diff --git a/ee/tuf/finalize_linux_test.go b/ee/tuf/finalize_linux_test.go deleted file mode 100644 index 6d71ee222..000000000 --- a/ee/tuf/finalize_linux_test.go +++ /dev/null @@ -1,24 +0,0 @@ -//go:build linux -// +build linux - -package tuf - -import ( - "os" - "testing" - - "github.com/stretchr/testify/require" -) - -func Test_getInterpreter(t *testing.T) { - t.Parallel() - - // Use the current executable in our test - currentRunningExecutable, err := os.Executable() - require.NoError(t, err, "getting current executable") - - // Confirm we pick the expected interpreter - interpreter, err := getInterpreter(currentRunningExecutable) - require.NoError(t, err, "expected no error getting interpreter") - require.Equal(t, "ld-linux-x86-64.so.2", interpreter) -}