mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 08:23:15 +01:00
support universal (fat) mach-o binary files (#4278)
Signed-off-by: Joseph Shapiro <joeyashapiro@gmail.com>
This commit is contained in:
parent
07029ead8a
commit
31b2c4c090
@ -3,6 +3,7 @@ package executable
|
||||
import (
|
||||
"debug/macho"
|
||||
|
||||
"github.com/anchore/syft/internal"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/internal/unionreader"
|
||||
)
|
||||
@ -19,20 +20,38 @@ const (
|
||||
func findMachoFeatures(data *file.Executable, reader unionreader.UnionReader) error {
|
||||
// TODO: support security features
|
||||
|
||||
// TODO: support multi-architecture binaries
|
||||
f, err := macho.NewFile(reader)
|
||||
// a universal binary may have multiple architectures, so we need to check each one
|
||||
readers, err := unionreader.GetReaders(reader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
libs, err := f.ImportedLibraries()
|
||||
if err != nil {
|
||||
return err
|
||||
var libs []string
|
||||
for _, r := range readers {
|
||||
f, err := macho.NewFile(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rLibs, err := f.ImportedLibraries()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
libs = append(libs, rLibs...)
|
||||
|
||||
// TODO handle only some having entrypoints/exports? If that is even practical
|
||||
// only check for entrypoint if we don't already have one
|
||||
if !data.HasEntrypoint {
|
||||
data.HasEntrypoint = machoHasEntrypoint(f)
|
||||
}
|
||||
// only check for exports if we don't already have them
|
||||
if !data.HasExports {
|
||||
data.HasExports = machoHasExports(f)
|
||||
}
|
||||
}
|
||||
|
||||
data.ImportedLibraries = libs
|
||||
data.HasEntrypoint = machoHasEntrypoint(f)
|
||||
data.HasExports = machoHasExports(f)
|
||||
// de-duplicate libraries
|
||||
data.ImportedLibraries = internal.NewSet(libs...).ToSlice()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/internal/unionreader"
|
||||
)
|
||||
|
||||
@ -83,3 +84,39 @@ func Test_machoHasExports(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_machoUniversal(t *testing.T) {
|
||||
readerForFixture := func(t *testing.T, fixture string) unionreader.UnionReader {
|
||||
t.Helper()
|
||||
f, err := os.Open(filepath.Join("test-fixtures/shared-info", fixture))
|
||||
require.NoError(t, err)
|
||||
return f
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
fixture string
|
||||
want file.Executable
|
||||
}{
|
||||
{
|
||||
name: "universal lib",
|
||||
fixture: "bin/libhello_universal.dylib",
|
||||
want: file.Executable{HasExports: true, HasEntrypoint: false},
|
||||
},
|
||||
{
|
||||
name: "universal application",
|
||||
fixture: "bin/hello_mac_universal",
|
||||
want: file.Executable{HasExports: false, HasEntrypoint: true},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var data file.Executable
|
||||
err := findMachoFeatures(&data, readerForFixture(t, tt.fixture))
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, tt.want.HasEntrypoint, data.HasEntrypoint)
|
||||
assert.Equal(t, tt.want.HasExports, data.HasExports)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,13 +2,13 @@
|
||||
|
||||
BIN=../../bin
|
||||
|
||||
all: $(BIN)/hello_linux $(BIN)/hello.exe $(BIN)/hello_mac
|
||||
all: $(BIN)/hello_linux $(BIN)/hello.exe $(BIN)/hello_mac $(BIN)/hello_mac_universal
|
||||
|
||||
linux: $(BIN)/libhello.so
|
||||
|
||||
windows: $(BIN)/libhello.dll
|
||||
|
||||
mac: $(BIN)/libhello.dylib
|
||||
mac: $(BIN)/libhello.dylib $(BIN)/hello_mac_universal
|
||||
|
||||
$(BIN)/hello_linux:
|
||||
gcc hello.c -o $(BIN)/hello_linux
|
||||
@ -19,5 +19,8 @@ $(BIN)/hello.exe:
|
||||
$(BIN)/hello_mac:
|
||||
o64-clang hello.c -o $(BIN)/hello_mac
|
||||
|
||||
$(BIN)/hello_mac_universal:
|
||||
o64-clang -arch arm64 -arch x86_64 hello.c -o $(BIN)/hello_mac_universal
|
||||
|
||||
clean:
|
||||
rm -f $(BIN)/hello_linux $(BIN)/hello.exe $(BIN)/hello_mac
|
||||
rm -f $(BIN)/hello_linux $(BIN)/hello.exe $(BIN)/hello_mac $(BIN)/hello_mac_universal
|
||||
|
||||
@ -2,13 +2,13 @@
|
||||
|
||||
BIN=../../bin
|
||||
|
||||
all: $(BIN)/libhello.so $(BIN)/libhello.dll $(BIN)/libhello.dylib
|
||||
all: $(BIN)/libhello.so $(BIN)/libhello.dll $(BIN)/libhello.dylib $(BIN)/libhello_universal.dylib
|
||||
|
||||
linux: $(BIN)/libhello.so
|
||||
|
||||
windows: $(BIN)/libhello.dll
|
||||
|
||||
mac: $(BIN)/libhello.dylib
|
||||
mac: $(BIN)/libhello.dylib $(BIN)/libhello_universal.dylib
|
||||
|
||||
$(BIN)/libhello.so:
|
||||
gcc -shared -fPIC -o $(BIN)/libhello.so hello.c
|
||||
@ -19,5 +19,8 @@ $(BIN)/libhello.dll:
|
||||
$(BIN)/libhello.dylib:
|
||||
o64-clang -dynamiclib -o $(BIN)/libhello.dylib hello.c
|
||||
|
||||
$(BIN)/libhello_universal.dylib:
|
||||
o64-clang -dynamiclib -arch arm64 -arch x86_64 hello.c -o $(BIN)/libhello_universal.dylib
|
||||
|
||||
clean:
|
||||
rm -f $(BIN)/libhello.so $(BIN)/hello.dll $(BIN)/libhello.dylib $(BIN)/libhello.a
|
||||
rm -f $(BIN)/libhello.so $(BIN)/hello.dll $(BIN)/libhello.dylib $(BIN)/libhello.a $(BIN)/libhello_universal.dylib
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user