0x09 / hfsfuse

FUSE driver for HFS+ filesystems
Other
77 stars 13 forks source link

Fix st_mode on root #25

Closed phcoder closed 1 year ago

phcoder commented 1 year ago

st_mode on root is sometimes weird on e.g. on Inherit the Earth demo dmg st_mode ends up being 0 on root which results in I/O error down the line when listing root directory. Enforce sane values on the root.

0x09 commented 1 year ago

Thanks @phcoder, it turns out this is a sort of bug/missing feature in hfsfuse. Apparently it's valid for any HFS+ record's file mode bits to be 0 like this, and Apple's HFS+ technical note explains how the macOS driver handles this:

If the S_IFMT field (upper 4 bits) of the fileMode field is zero, then Mac OS X assumes that the permissions structure is uninitialized, and internally uses default values for all of the fields. The default user and group IDs are 99, but can be changed at the time the volume is mounted. This default ownerID is then subject to substitution as described above.

It doesn't say specifically, but the default used for the permission bits seem to be based on the current umask value, and the Linux kernel HFS+ driver behaves this way as well. The defaults that macOS applies for user and group are more complicated:

Mac OS X version 10.3[+] treats user ID 99 as if it was the user ID of the process making the call (in effect, making it owned by everyone simultaneously). These substitutions happen at run time.

By comparison, the Linux kernel HFS+ driver just uses the owner and group id provided in the record and doesn't attempt to substitute them with those of the accessing user. I think this behavior makes sense for hfsfuse too, especially since FUSE already allows access from other users by default.

I'd prefer to try to handle this according to the TN rather than overwrite the root permissions unconditionally, just in case anyone is using FUSE's default_permissions option and relying on these being enforced. It seems like the best thing here would be to have hfs_stat handle this for any record by checking if bits 12-16 of st_mode are not set, and in that case set it to the current umask plus S_IFREG or S_IFDIR depending on whether the key provided is for a file or directory (HFS_REC_FILE/HFS_REC_FLDR)

This should be a fairly small change; if you'd be interested in incorporating that into this PR that would be great, otherwise I'd be happy to add this as well.

phcoder commented 1 year ago

Thank you for the insight. Moved here: https://github.com/0x09/hfsfuse/pull/26