fix: add MountedFilesystemRoot helper and apply it consistently

This commit is contained in:
blacktop
2026-05-07 10:12:55 -06:00
parent cb4148b9ff
commit 5ce9eb1525
5 changed files with 91 additions and 13 deletions
+20
View File
@@ -496,6 +496,26 @@ func Mount(image, mountPoint string) error {
return nil
}
// MountedFilesystemRoot returns the root directory of a mounted filesystem.
// apfs-fuse exposes APFS volume contents below <mountPoint>/root; hdiutil and
// hfsfuse expose the volume contents directly at <mountPoint>.
func MountedFilesystemRoot(mountPoint string) string {
mountPoint = filepath.Clean(mountPoint)
rootPath := filepath.Join(mountPoint, "root")
rootInfo, err := os.Stat(rootPath)
if err != nil || !rootInfo.IsDir() {
return mountPoint
}
systemPath := filepath.Join(mountPoint, "System")
if _, err := os.Stat(systemPath); !os.IsNotExist(err) {
return mountPoint
}
return rootPath
}
// mountLinux mounts a DMG on Linux using the appropriate FUSE tool based on filesystem type
func mountLinux(image, mountPoint string) error {
// First, try to detect the filesystem type
+28
View File
@@ -1,6 +1,7 @@
package utils
import (
"os"
"path/filepath"
"reflect"
"testing"
@@ -45,6 +46,33 @@ func TestSanitizeArchivePath(t *testing.T) {
}
}
func TestMountedFilesystemRoot(t *testing.T) {
t.Run("apfs fuse root", func(t *testing.T) {
root := t.TempDir()
if err := os.MkdirAll(filepath.Join(root, "root", "System"), 0755); err != nil {
t.Fatal(err)
}
if got, want := MountedFilesystemRoot(root), filepath.Join(root, "root"); got != want {
t.Fatalf("MountedFilesystemRoot() = %q, want %q", got, want)
}
})
t.Run("direct system wins", func(t *testing.T) {
root := t.TempDir()
if err := os.MkdirAll(filepath.Join(root, "root", "System"), 0755); err != nil {
t.Fatal(err)
}
if err := os.MkdirAll(filepath.Join(root, "System"), 0755); err != nil {
t.Fatal(err)
}
if got, want := MountedFilesystemRoot(root), filepath.Clean(root); got != want {
t.Fatalf("MountedFilesystemRoot() = %q, want %q", got, want)
}
})
}
func TestDifference(t *testing.T) {
type args struct {
a []string
+1 -8
View File
@@ -34,14 +34,7 @@ func GetDscPathsInMount(mountPoint string, driverKit, all bool) ([]string, error
var matches []string
var re *regexp.Regexp
if runtime.GOOS == "linux" {
// apfs-fuse mounts volume at mountPoint + "/root", but hfsfuse mounts directly
// Check if /root subdirectory exists to determine mount structure
rootPath := filepath.Join(mountPoint, "root")
if _, err := os.Stat(rootPath); err == nil {
mountPoint = rootPath
}
}
mountPoint = utils.MountedFilesystemRoot(mountPoint)
if driverKit {
re = regexp.MustCompile(filepath.Join(mountPoint, DriverKitCacheRegex))
+8 -5
View File
@@ -16,6 +16,7 @@ import (
"github.com/blacktop/go-plist"
"github.com/blacktop/ipsw/internal/commands/mount"
"github.com/blacktop/ipsw/internal/utils"
)
const (
@@ -156,10 +157,12 @@ func WalkIPSW(path string, cfg *IPSWConfig) ([]Record, []SkippedVolume, error) {
}
func WalkVolume(root, volume string) ([]Record, error) {
volumeRoot := utils.MountedFilesystemRoot(root)
var candidates []plistCandidate
seen := make(map[string]struct{})
addCandidate := func(kind, path string) {
rel := relativePlistPath(root, path)
rel := relativePlistPath(volumeRoot, path)
key := kind + "\x00" + rel
if _, ok := seen[key]; ok {
return
@@ -169,7 +172,7 @@ func WalkVolume(root, volume string) ([]Record, error) {
}
for _, spec := range launchdPlistDirs {
matches, err := filepath.Glob(filepath.Join(root, filepath.FromSlash(spec.dir), "*.plist"))
matches, err := filepath.Glob(filepath.Join(volumeRoot, filepath.FromSlash(spec.dir), "*.plist"))
if err != nil {
return nil, err
}
@@ -178,7 +181,7 @@ func WalkVolume(root, volume string) ([]Record, error) {
}
}
if err := filepath.WalkDir(root, func(path string, d os.DirEntry, err error) error {
if err := filepath.WalkDir(volumeRoot, func(path string, d os.DirEntry, err error) error {
if err != nil {
if os.IsPermission(err) {
return nil
@@ -188,7 +191,7 @@ func WalkVolume(root, volume string) ([]Record, error) {
if d.IsDir() || d.Name() != "Info.plist" {
return nil
}
rel := relativePlistPath(root, path)
rel := relativePlistPath(volumeRoot, path)
switch {
case isXPCInfoPlist(rel):
addCandidate(SourceKindXPCBundle, path)
@@ -209,7 +212,7 @@ func WalkVolume(root, volume string) ([]Record, error) {
records := make([]Record, 0, len(candidates))
for _, candidate := range candidates {
record, ok := recordFromFile(root, volume, candidate.kind, candidate.path)
record, ok := recordFromFile(volumeRoot, volume, candidate.kind, candidate.path)
if ok {
records = append(records, record)
}
+34
View File
@@ -126,6 +126,40 @@ func TestWalkVolumeXPCBundleLayouts(t *testing.T) {
}
}
func TestWalkVolumeAPFSFuseRootPrefix(t *testing.T) {
root := t.TempDir()
writePlist(t, root, "/root/System/Library/LaunchDaemons/com.apple.rooted.plist", map[string]any{
"Label": "com.apple.rooted",
"Program": "/usr/libexec/rooted",
}, plist.XMLFormat)
writePlist(t, root, "/root/Applications/Foo.app/XPCServices/FooService.xpc/Info.plist", map[string]any{
"CFBundleIdentifier": "com.apple.FooService",
"CFBundleExecutable": "FooService",
"XPCService": map[string]any{
"ServiceType": "Application",
},
}, plist.XMLFormat)
records, err := WalkVolume(root, "FileSystem")
if err != nil {
t.Fatal(err)
}
if len(records) != 2 {
t.Fatalf("expected launchd and XPC records under apfs-fuse root, got %d", len(records))
}
if findRecord(records, "/System/Library/LaunchDaemons/com.apple.rooted.plist") == nil {
t.Fatalf("missing launchd daemon with normalized path: %#v", records)
}
if findRecord(records, "/Applications/Foo.app/XPCServices/FooService.xpc/Info.plist") == nil {
t.Fatalf("missing XPC bundle with normalized path: %#v", records)
}
for _, record := range records {
if strings.HasPrefix(record.PlistPath, "/root/") {
t.Fatalf("plist_path kept apfs-fuse root prefix: %#v", record)
}
}
}
func TestWalkVolumeAppXPCAndPlainApp(t *testing.T) {
root := t.TempDir()
writePlist(t, root, "/Applications/HasService.app/Info.plist", map[string]any{