mirror of
https://github.com/blacktop/ipsw.git
synced 2026-05-08 12:22:26 +00:00
fix: refactor ent file walking to use mounted filesystem root
This commit is contained in:
@@ -30,6 +30,11 @@ import (
|
||||
// Entitlements is a map of entitlements
|
||||
type Entitlements map[string]any
|
||||
|
||||
type mountedEntitlementFile struct {
|
||||
Path string
|
||||
DBPath string
|
||||
}
|
||||
|
||||
// Config is the configuration for the entitlements command
|
||||
type Config struct {
|
||||
IPSW string
|
||||
@@ -377,37 +382,23 @@ func scanEnts(ipswPath, dmgPath, dmgType string, conf *Config) (map[string]strin
|
||||
}()
|
||||
}
|
||||
|
||||
var files []string
|
||||
if err := filepath.Walk(mountPoint, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
// Skip paths with permission errors gracefully
|
||||
if os.IsPermission(err) {
|
||||
log.Debugf("skipping path due to permission denied: %s", path)
|
||||
return nil
|
||||
}
|
||||
log.Debugf("failed to walk mount %s: %v", mountPoint, err)
|
||||
return nil
|
||||
}
|
||||
if !info.IsDir() {
|
||||
files = append(files, path)
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, fmt.Errorf("failed to walk files in dir %s: %v", mountPoint, err)
|
||||
files, err := mountedEntitlementFiles(mountPoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
entDB := make(map[string]string)
|
||||
|
||||
for _, file := range files {
|
||||
var m *macho.File
|
||||
fat, err := macho.OpenFat(file)
|
||||
fat, err := macho.OpenFat(file.Path)
|
||||
if err == nil {
|
||||
m = fat.Arches[len(fat.Arches)-1].File // grab last arch (probably arm64e)
|
||||
} else {
|
||||
if err == macho.ErrNotFat {
|
||||
m, err = macho.Open(file)
|
||||
m, err = macho.Open(file.Path)
|
||||
if err != nil {
|
||||
log.WithError(err).Warnf("failed to get entitlements for %s", file)
|
||||
log.WithError(err).Warnf("failed to get entitlements for %s", file.Path)
|
||||
continue // bad macho file (skip)
|
||||
}
|
||||
} else {
|
||||
@@ -423,7 +414,7 @@ func scanEnts(ipswPath, dmgPath, dmgType string, conf *Config) (map[string]strin
|
||||
// Fallback to DER entitlements if normal ones are empty
|
||||
if decoded, err := ents.DerDecode(m.CodeSignature().EntitlementsDER); err == nil {
|
||||
output.WriteString(decoded)
|
||||
log.Warnf("using DER entitlements for %s", file)
|
||||
log.Warnf("using DER entitlements for %s", file.Path)
|
||||
}
|
||||
}
|
||||
// Add launch constraints if requested (for diff, not for database)
|
||||
@@ -466,11 +457,37 @@ func scanEnts(ipswPath, dmgPath, dmgType string, conf *Config) (map[string]strin
|
||||
}
|
||||
}
|
||||
|
||||
entDB[strings.TrimPrefix(file, mountPoint)] = output.String()
|
||||
entDB[file.DBPath] = output.String()
|
||||
} else {
|
||||
entDB[strings.TrimPrefix(file, mountPoint)] = ""
|
||||
entDB[file.DBPath] = ""
|
||||
}
|
||||
}
|
||||
|
||||
return entDB, nil
|
||||
}
|
||||
|
||||
func mountedEntitlementFiles(mountPoint string) ([]mountedEntitlementFile, error) {
|
||||
root := utils.MountedFilesystemRoot(mountPoint)
|
||||
var files []mountedEntitlementFile
|
||||
if err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
// Skip paths with permission errors gracefully
|
||||
if os.IsPermission(err) {
|
||||
log.Debugf("skipping path due to permission denied: %s", path)
|
||||
return nil
|
||||
}
|
||||
log.Debugf("failed to walk mount %s: %v", root, err)
|
||||
return nil
|
||||
}
|
||||
if !info.IsDir() {
|
||||
files = append(files, mountedEntitlementFile{
|
||||
Path: path,
|
||||
DBPath: strings.TrimPrefix(path, root),
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, fmt.Errorf("failed to walk files in dir %s: %v", root, err)
|
||||
}
|
||||
return files, nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package ent
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMountedEntitlementFilesRootNormalization(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
fileParts []string
|
||||
wantParts []string
|
||||
}{
|
||||
{
|
||||
name: "apfs fuse root",
|
||||
fileParts: []string{"root", "System", "Library", "CoreServices", "testd"},
|
||||
wantParts: []string{"System", "Library", "CoreServices", "testd"},
|
||||
},
|
||||
{
|
||||
name: "direct root",
|
||||
fileParts: []string{"System", "Library", "CoreServices", "testd"},
|
||||
wantParts: []string{"System", "Library", "CoreServices", "testd"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
path := pathUnder(root, tt.fileParts...)
|
||||
writeTestFile(t, path)
|
||||
|
||||
files, err := mountedEntitlementFiles(root)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(files) != 1 {
|
||||
t.Fatalf("expected 1 file, got %d: %#v", len(files), files)
|
||||
}
|
||||
|
||||
wantDBPath := rootedPath(tt.wantParts...)
|
||||
if files[0].Path != path {
|
||||
t.Fatalf("Path = %q, want %q", files[0].Path, path)
|
||||
}
|
||||
if files[0].DBPath != wantDBPath {
|
||||
t.Fatalf("DBPath = %q, want %q", files[0].DBPath, wantDBPath)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func writeTestFile(t *testing.T, path string) {
|
||||
t.Helper()
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.WriteFile(path, []byte("test"), 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func pathUnder(root string, parts ...string) string {
|
||||
return filepath.Join(append([]string{root}, parts...)...)
|
||||
}
|
||||
|
||||
func rootedPath(parts ...string) string {
|
||||
return string(filepath.Separator) + filepath.Join(parts...)
|
||||
}
|
||||
Reference in New Issue
Block a user