ops icon indicating copy to clipboard operation
ops copied to clipboard

getSharedLibs on Linux fails when __libc_enable_secure is enabled in the ELF

Open francescolavra opened this issue 2 years ago • 0 comments

When trying to determine the shared libraries needed by an ELF executable with __libc_enable_secure enabled (e.g. clickhouse version 21.7.3.14), ops run fails with:

panic: failed building manifest: exit status 5

goroutine 1 [running]:
github.com/nanovms/ops/cmd.runCommandHandler(0xc00049a500, 0xc0004a3470, 0x1, 0x3)
	/Users/eyberg/go/src/github.com/nanovms/ops/cmd/cmd_run.go:60 +0x48d
github.com/spf13/cobra.(*Command).execute(0xc00049a500, 0xc0004a33b0, 0x3, 0x3, 0xc00049a500, 0xc0004a33b0)
	/Users/eyberg/go/pkg/mod/github.com/spf13/[email protected]/command.go:830 +0x2c2
github.com/spf13/cobra.(*Command).ExecuteC(0xc0000e2c80, 0x0, 0x1d8b120, 0xc000102058)
	/Users/eyberg/go/pkg/mod/github.com/spf13/[email protected]/command.go:914 +0x30b
github.com/spf13/cobra.(*Command).Execute(...)
	/Users/eyberg/go/pkg/mod/github.com/spf13/[email protected]/command.go:864
main.main()
	/Users/eyberg/go/src/github.com/nanovms/ops/ops.go:8 +0x2a

The reason is that launching the ELF directly with LD_TRACE_LOADED_OBJECTS=1 (as done in getSharedLibs()) returns an exit code 5 (and doesn't print the shared libraries). According to glibc documentation, the __libc_enable_secure variable is set nonzero at startup if the process's effective IDs differ from its real IDs, or it is otherwise indicated that extra security should be used. When this is set the dynamic linker and some functions contained in the C library ignore various environment variables that normally affect them. Using the ldd script instead of invoking directly the executable with LD_TRACE_LOADED_OBJECTS=1 solves this issue.

diff --git a/lepton/ldd_linux.go b/lepton/ldd_linux.go
index 1d959ff..261903d 100644
--- a/lepton/ldd_linux.go
+++ b/lepton/ldd_linux.go
@@ -67,10 +67,7 @@ func getSharedLibs(targetRoot string, path string) ([]string, error) {
        elfFile, err := GetElfFileInfo(path)
 
        if err == nil && IsDynamicLinked(elfFile) {
-               env := os.Environ()
-               env = append(env, "LD_TRACE_LOADED_OBJECTS=1")
-               cmd := exec.Command(path)
-               cmd.Env = env
+               cmd := exec.Command("ldd", path)
                out, _ := cmd.StdoutPipe()
                scanner := bufio.NewScanner(out)
 

francescolavra avatar Jul 18 '21 17:07 francescolavra