Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extended attributes of symlinks #31

Closed
sbond75 opened this issue Apr 18, 2024 · 11 comments
Closed

Extended attributes of symlinks #31

sbond75 opened this issue Apr 18, 2024 · 11 comments

Comments

@sbond75
Copy link

sbond75 commented Apr 18, 2024

Running getfattr --no-dereference -d -m '' -- file, where file is the symlink to test and it has no attributes, will output the following:

file: user.com.apple.FinderInfo: No such attribute
file: user.hfsfuse.record.date_created: No such attribute

I think the correct behavior should be no output. Symlinks are allowed to have extended attributes (I used xattr on macOS to test this), but this particular symlink doesn't have the above attributes. Maybe these attribute names are somehow built into hfsfuse as attribute names it checks for, like in hfsfuse_getxattr_offset. Looking at the code for getfattr, hfsfuse might be returning these attributes as built-in attribute names, but they return ENODATA when queried for an attribute value. lgetxattr, when called on user.com.apple.FinderInfo, returns ENODATA since there is no such attribute on the symlink anyway, but llistxattr is returning those two attributes extraneously.

@sbond75
Copy link
Author

sbond75 commented Apr 18, 2024

Additionally, I did a test on macOS to find file creation time of a symlink using GetFileInfo -P -d file, and it was reported properly. However, hfsfuse doesn't report the user.hfsfuse.record.date_created attribute for symlinks as indicated by my initial comment, saying it has no value.

@0x09
Copy link
Owner

0x09 commented Apr 18, 2024

Yeah, something's going on here. All records (files/folders/links/etc) should have hfsfuse.record.date_created available at least as this comes from the record structure itself (the same is technically true of FinderInfo but by convention that one isn't listed as an xattr if it's empty.) I'll take a look.

@0x09
Copy link
Owner

0x09 commented Apr 18, 2024

This ended up being pretty simple. The Linux kernel actually disallows user extended attributes on anything but regular files.
The filesystem still receives llistxattr calls since symlinks can contain ACLs, etc, which is why hfsfuse is able to even tell getfattr that these exist, but getfattr is never able to access them. The subsequent lgetxattr calls are never even passed to FUSE, the kernel just sends ENODATA back.

I think the only way around this is for hfsfuse_listxattr to stop returning attribute names under Linux for things that aren't regular files. At least that info will still be available via hfsdump.

Using a different non-user namespace (like hfsfuse.) for these does seem to work, but as far as I can tell programs aren't intended to define their own top level xattr namespaces.

I pushed the former change in 2ab526c so this should be resolved if you pull master.

@sbond75
Copy link
Author

sbond75 commented Apr 18, 2024

I would suggest allowing it for directories as well since those are allowed to have user extended attributes in Linux.

As for the possibility of using a non-user namespace, I would suggest making a mount option for that or just having it by default. Since the program runs as root and is involved with filesystems I would imagine it better to use a non-user namespace, but this is up to you of course.

@0x09
Copy link
Owner

0x09 commented Apr 19, 2024

You're right thanks, directories should be included in the allowed types. That's now fixed.

Unfortunately with custom namespaces it seems that user tools (including rsync) are unable to copy these even for regular files, which is kind of expected, but makes this hard to do in a way that's not confusing to use (e.g. only symlinks get a custom namespace) or results in unexpectedly missing something when moving data around.

I considered while working on xattr support a bit ago adding an xattr mount mode similar to -o rsrc_only which would offer a consistent way to access these on any system, so this may be an option (this would be useful on Haiku as well for different reasons.) I'll try to think a bit more about what makes sense to do here. Thank you for the suggestions and these detailed bug reports.

@sbond75
Copy link
Author

sbond75 commented Apr 19, 2024

I found that it is possible if you use "security", "system", or "trusted" namespaces which all have different purposes, mentioned on the same man page you sent earlier. On Linux the program must run as root or have CAP_SYS_ADMIN to view, set, or copy "trusted" namespaced attributes. More information from that man page is as follows:

Trusted extended attributes are visible and accessible only to
processes that have the CAP_SYS_ADMIN capability. Attributes in
this class are used to implement mechanisms in user space (i.e.,
outside the kernel) which keep information in extended attributes
to which ordinary processes should not have access.

Notably, the only difference to hfsfuse's use-case would be the "ordinary processes should not have access" part mentioned at the end. It would be preferable for them to have access to these.

Example usage of the trusted namespace: touch test.txt && sudo setfattr -n trusted.example -v example test.txt && sudo getfattr --no-dereference -d -m '' -- test.txt will work, ln -s test.txt testSym && sudo setfattr -n trusted.example -v example2 testSym && sudo getfattr --no-dereference -d -m '' -- testSym will show the example2 value on the symlink, and finally sudo cp -a testSym testSym2 && sudo getfattr --no-dereference -d -m '' -- testSym2 also prints the copied example xattr. Note that running cp as a non-root user causes it to silently not copy the xattrs in these namespaces. Furthermore, it seems getfattr must be run as root or else No such attribute error shows for any attribute under these namespaces.

I also set this up as a prefix in my local hfsfuse.c and it works there.

@0x09
Copy link
Owner

0x09 commented Apr 20, 2024

I tried a few combinations myself, it seems to vary a lot between the 4 (+ custom) as far as what can be read vs written by root and non root and the type of file.
I think at minimum making the namespace a build option would be a good idea, since this is OS dependent anyway. That would allow this to be set globally with a make arg or in config.mak. Let me know if this would be more or less sufficient for the use case here.

Otherwise I'm still a bit split on letting this be changed with a runtime option vs coming up with another interface for accessing these, but I'd like to have something to cover these inconsistencies. I wonder how other Linux filesystem drivers even outside of FUSE handle this, since HFS+ is definitely not the only filesystem that supports extended attributes on symlinks.

@sbond75
Copy link
Author

sbond75 commented Apr 20, 2024

Yes I would say a Makefile option makes sense. I haven't used config.mak (is it autotools-related?)

@0x09
Copy link
Owner

0x09 commented Apr 20, 2024

For hfsfuse it's just something for convenience to rebuild without specifying options to make every time. It can be created with make config, there's some info on how it gets used in https://github.com/0x09/hfsfuse?tab=readme-ov-file#configuring
Using the config file is no different from specifying make args directly, but if you want to always build with a particular namespace you'd be able to set it there instead of remembering to use make XATTR_PREFIXXATTR_NAMESPACE=theprefix (once this option is added.)

@0x09
Copy link
Owner

0x09 commented Apr 20, 2024

These should do it 9a8ff0b / 5fe04ec.

make XATTR_NAMESPACE=namespace.

or the same setting in config.mak now changes this for all xattrs. Defaults to empty on macOS and user. on all other systems.
Edit: updated with a change to actually allow the config.mak override mentioned.

@0x09
Copy link
Owner

0x09 commented May 11, 2024

After experimenting with some more involved ways of displaying these on the filesystem, I decided to go with the simplest and just add an option to mount with symlinks as regular files as a fallback means for viewing these in c528f3c.
This and the other various system specific xattr quirks are now under OS-specific extended attribute behavior in the README.

Between this and the namespace option there are now at least a few alternative ways to access these, so I'll go ahead and close this. Thanks again for these reports.

@0x09 0x09 closed this as completed May 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants