2 Commits
1.6 ... 1.6.1

Author SHA1 Message Date
Clayton Craft
731a805a9e getBinaryDeps: properly handle circular lib dependencies
This moves the recursive bit outside of getBinaryDeps and properly
handles circular dependencies.
2023-02-09 12:42:06 -08:00
Clayton Craft
b90624d7dd getBinaryDeps: move recursive bit to new function 2023-02-09 12:41:34 -08:00

66
main.go
View File

@@ -177,45 +177,24 @@ func getHookFiles(filesdir string) (files []string, err error) {
return files, nil return files, nil
} }
// Recursively list all dependencies for a given ELF binary func getDeps(file string, parents map[string]struct{}) (files []string, err error) {
func getBinaryDeps(file string) (files []string, err error) {
// if file is a symlink, resolve dependencies for target
fileStat, err := os.Lstat(file)
if err != nil {
return nil, fmt.Errorf("getBinaryDeps: failed to stat file %q: %w", file, err)
}
// Symlink: write symlink to archive then set 'file' to link target if _, found := parents[file]; found {
if fileStat.Mode()&os.ModeSymlink != 0 { return
target, err := os.Readlink(file)
if err != nil {
return nil, fmt.Errorf("getBinaryDeps: unable to read symlink %q: %w", file, err)
}
if !filepath.IsAbs(target) {
target, err = misc.RelativeSymlinkTargetToDir(target, filepath.Dir(file))
if err != nil {
return files, err
}
}
binaryDepFiles, err := getBinaryDeps(target)
if err != nil {
return files, err
}
files = append(files, binaryDepFiles...)
return files, err
} }
// get dependencies for binaries // get dependencies for binaries
fd, err := elf.Open(file) fd, err := elf.Open(file)
if err != nil { if err != nil {
return nil, fmt.Errorf("getBinaryDeps: unable to open elf binary %q: %w", file, err) return nil, fmt.Errorf("getDeps: unable to open elf binary %q: %w", file, err)
} }
libs, _ := fd.ImportedLibraries() libs, _ := fd.ImportedLibraries()
fd.Close() fd.Close()
files = append(files, file) files = append(files, file)
parents[file] = struct{}{}
if len(libs) == 0 { if len(libs) == 0 {
return files, err return
} }
// we don't recursively search these paths for performance reasons // we don't recursively search these paths for performance reasons
@@ -233,9 +212,9 @@ func getBinaryDeps(file string) (files []string, err error) {
for _, libdir := range libdirs { for _, libdir := range libdirs {
path := filepath.Join(libdir, lib) path := filepath.Join(libdir, lib)
if _, err := os.Stat(path); err == nil { if _, err := os.Stat(path); err == nil {
binaryDepFiles, err := getBinaryDeps(path) binaryDepFiles, err := getDeps(path, parents)
if err != nil { if err != nil {
return files, err return nil, err
} }
files = append(files, binaryDepFiles...) files = append(files, binaryDepFiles...)
files = append(files, path) files = append(files, path)
@@ -245,13 +224,40 @@ func getBinaryDeps(file string) (files []string, err error) {
} }
} }
if !found { if !found {
return nil, fmt.Errorf("getBinaryDeps: unable to locate dependency for %q: %s", file, lib) return nil, fmt.Errorf("getDeps: unable to locate dependency for %q: %s", file, lib)
} }
} }
return return
} }
// Recursively list all dependencies for a given ELF binary
func getBinaryDeps(file string) ([]string, error) {
// if file is a symlink, resolve dependencies for target
fileStat, err := os.Lstat(file)
if err != nil {
return nil, fmt.Errorf("getBinaryDeps: failed to stat file %q: %w", file, err)
}
// Symlink: write symlink to archive then set 'file' to link target
if fileStat.Mode()&os.ModeSymlink != 0 {
target, err := os.Readlink(file)
if err != nil {
return nil, fmt.Errorf("getBinaryDeps: unable to read symlink %q: %w", file, err)
}
if !filepath.IsAbs(target) {
target, err = misc.RelativeSymlinkTargetToDir(target, filepath.Dir(file))
if err != nil {
return nil, err
}
}
file = target
}
return getDeps(file, make(map[string]struct{}))
}
func getFiles(list []string, required bool) (files []string, err error) { func getFiles(list []string, required bool) (files []string, err error) {
for _, file := range list { for _, file := range list {
filelist, err := getFile(file, required) filelist, err := getFile(file, required)