Skip to content

zfs_vnops_os.c: Do not allow a duplicate attribute of same name#17593

Closed
rmacklem wants to merge 1 commit intoopenzfs:masterfrom
rmacklem:master
Closed

zfs_vnops_os.c: Do not allow a duplicate attribute of same name#17593
rmacklem wants to merge 1 commit intoopenzfs:masterfrom
rmacklem:master

Conversation

@rmacklem
Copy link
Copy Markdown
Contributor

@rmacklem rmacklem commented Aug 5, 2025

Without this patch, if an attribute in user namespace is created while xattr=sa, it is possible to create an attribute of the same name via named attribute when xattr=dir.

This patch adds code to check for the duplicate in the sa block and deleted it when an attribute of the same name is created in the named attribute directory.

Fixes: #17540

Motivation and Context

Without this patch, if an attribute in user namespace is created while the xattr property is set to "sa", it is possible to create an attribute of the same name via named attributes after the xattr property is changed to "dir".

Description

The code in zfs_deleteextattr_sa() was factored out into zfs_deleteextattr_sa_impl(), so that it could be called without the vop_deleteextattr_args argument. Then zfs_deleteextattr_sa_impl() is used by a new function called zfs_delxattr_sa_dircreate() to delete any "sa" attribute of the same name. Then zfs_delxattr_sa_dircreate() is called from zfs_freebsd_create() when a named attribute is being created.

How Has This Been Tested?

On an up-to-date FreeBSD system with #17540 applied, an attribute was created via setextattr(1) when the file system's
xattr property was set to xattr=sa.

$ setextattr user <attribute-name> XXX <file>

Then, the xattr property was switched to "dir" and creation of a named attribute of the same name was done via:

$ runat <file> cp /etc/hosts <attribute-name>
$ lsextattr user <file>

Without this patch, <attribute-name> is listed twice, whereas it is only listed once if the above is done with this patch applied.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Performance enhancement (non-breaking change which improves efficiency)
  • Code cleanup (non-breaking change which makes code smaller or more readable)
  • Quality assurance (non-breaking change which makes the code more robust against bugs)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Library ABI change (libzfs, libzfs_core, libnvpair, libuutil and libzfsbootenv)
  • Documentation (a change to man pages or other documentation)

Checklist:

Without this patch, if an attribute in user namespace is created
while xattr=sa, it is possible to create an attribute of the
same name via named attributes after xattr=dir.

This patch adds code to check for the duplicate in the sa block
and deleted it when an attribute of the same name is created
in the named attribute directory.

Fixes:	2957eab

Signed-off-by: Rick Macklem <rmacklem@uoguelph.ca>
Copy link
Copy Markdown
Member

@amotin amotin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One possible issue I have noticed is that unlike other extattr operations doing similar things, here you are taking the z_xattr_lock inside zfs_delxattr_sa_dircreate() after zfs_create() succeeded. I can see that it is better than nothing, but it seems not atomic, and some other thread may still see two copies of the attribute for a short time. But I am not deep/fresh enough on this code to say if anything better can be done. I approve this if there is no other way, but take it with a grain of salt.

@amotin amotin added the Status: Code Review Needed Ready for review and testing label Aug 5, 2025
@rmacklem
Copy link
Copy Markdown
Contributor Author

rmacklem commented Aug 5, 2025 via email

@amotin
Copy link
Copy Markdown
Member

amotin commented Aug 5, 2025

Is it ok to leave this for a separate commit?

If you have a good reason to hurry with this, then I don't have strong objections. Sure I would would prefer a proper patch from the beginning, but the world is not perfect.

@rmacklem
Copy link
Copy Markdown
Contributor Author

rmacklem commented Aug 5, 2025 via email

@rmacklem
Copy link
Copy Markdown
Contributor Author

rmacklem commented Aug 5, 2025

I am going to close this pull request. It was lucky you
mentioned the z_xattr_lock. It turns out that acquiring
it in zfs_freebsd_create() is not safe, because zfs_freebsd_create()
might be called with a locked named attribute directory.

In zfs_listextattr_dir(), it locks z_xattr_lock first and then the
named attribute dir (via namei() for ".").
--> This LOR could result in a deadlock.

I can't think of a way to handle this safely, so I think the
possibility of duplicate names (one in the "sa" and the
other in the "dir) will just have to be a "quirk" for now.
(So long as users set "xattr=dir" when they create the
file system, there won't be any duplicates.)

It is safe for the old extattr stuff because those VOPs
are always called with a regular vnode locked and never a
named attribute directory vnode locked.

I will keep looking for a "safe" way to avoid duplicates,
but I am not convinced it is doable?

@rmacklem rmacklem closed this Aug 5, 2025
@rmacklem
Copy link
Copy Markdown
Contributor Author

rmacklem commented Aug 6, 2025 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Status: Code Review Needed Ready for review and testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants