27

Quick look at user-mode file systems on macOS Ventura

 1 year ago
source link: https://threedots.ovh/blog/2022/06/quick-look-at-user-mode-file-systems-on-macos-ventura/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Quick look at user-mode file systems on macOS Ventura

  • June 9, 2022

Let’s start by plugging in a USB stick (using the FAT, ExFAT or NTFS file systems) on macOS Ventura… and see what happens. The NTFS kext isn’t even present anymore!

It turns out:

% mount | grep disk4
fat://disk4s1/NO NAME on /Volumes/NO NAME (lifs, local, nodev, nosuid, noowners, noatime)

macOS Ventura does use user-mode file systems for external disk drives.

The file system extensions

/System/Library/Filesystems/msdos.fs/Contents/Resources/livefiles_msdos.dylib
/System/Library/Filesystems/exfat.fs/Contents/Resources/livefiles_exfat.dylib
/System/Library/Filesystems/ntfs.fs/Contents/Resources/livefiles_ntfs.dylib

We see that the livefiles extensions are shipping today for 3 file systems: FAT, ExFAT and NTFS.

Those are loaded by the UVFSService process, which is itself loaded by userfsd.

The bad news, the set of entitlements used by UVFSService:

entitlements = {
	"com.apple.private.LiveFS.connection" = true;
	"com.apple.security.iokit-user-client-class" = "AppleLIFSUserClient";
	"com.apple.private.allow-external-storage" = true;
};

This means that we cannot load our own LiveFS extension modules within a stock operating system configuration.

What does that interface between the LiveFS provider and UVFSService look like anyway?

https://github.com/apple-oss-distributions/msdosfs/blob/main/LiveFilesTester/UserVFS.h gives the answer. It’s a fairly conventional interface that matches the semantics required quite well.

What if we try to mount directly?

% sudo diskutil unmount "/Volumes/NO NAME" 
Volume NO NAME on disk4s1 unmounted
% sudo mount -o local,nodev,nosuid,noowners,noatime -t lifs "fat://disk4s1/NO NAME" ~/a   
mount error:: Input/output error
mount: /Users/sunrise/a failed with 71
% sudo dmesg | grep lifs
arm64e_plugin_host: running binary "sudo" in keys-off mode due to entitlement: com.apple.private.security.clear-library-validation
lifs_mount:uid:501:gid:20
lifs_req_callback_thread: thread <ptr> starting for mount <ptr>
lifs_io_strategy_thread: thread <ptr> starting for mount <ptr>
Invalid lifs host port or port dying
Got error during mount request: 5
lifs_io_strategy_thread: thread <ptr> exiting for mount <ptr>
lifs_req_callback_thread: thread <ptr> exiting for mount <ptr>

Ok, it wants the lifs host port to be set properly before calling mount. What if we try to mount the disk using the regular Unix mount command sequence?

% sudo mount -t msdos /dev/disk4s1 ~/a
Executing: /usr/bin/kmutil load -p /System/Library/Extensions/msdosfs.kext
% mount | grep disk4
/dev/disk4s1 on /Users/sunrise/a (msdos, local, noowners)

Ok, in that case it doesn’t use UserFS, but the kext instead. Now what if we use diskutil mount?

% sudo umount ~/a
% sudo diskutil mount /dev/disk4s1
Volume NO NAME on /dev/disk4s1 mounted
% mount | grep disk4       
fat://disk4s1/NO NAME on /Volumes/NO NAME (lifs, local, nodev, nosuid, noowners, noatime)

OK, that makes sense.

More questions…

I didn’t track down yet how to mount manually for this scenario. How should that be done?

And, I really want this to be extensible to FUSE too. It turns out that there’s a sign of that at /System/Library/PrivateFrameworks/UVFSXPCService.framework/XPCServices/UVFSService.xpc/Contents/Resources/knownPlugins.internal.plist which does have a fuse entry. I wonder when that will happen to the public?

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Name *

Email *

Website

Comment *

Save my name, email, and website in this browser for the next time I comment.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK