Bug 266112 - Capsicum extended attributes test failing on ZFS
Summary: Capsicum extended attributes test failing on ZFS
Status: In Progress
Alias: None
Product: Base System
Classification: Unclassified
Component: tests (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Only Me
Assignee: Ed Maste
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-08-30 04:46 UTC by sigsys
Modified: 2022-09-13 17:43 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description sigsys 2022-08-30 04:46:09 UTC
sys/capsicum/functional:test_unprivileged (internal test Capability.ExtendedAttributesIfAvailableForked) fails when running with a ZFS /tmp since OpenZFS started rejecting attribute names with certain prefixes.

It uses compatibility wrappers for the Linux syscalls.  They're only ever called with "user.*" attribute names, and they always assume that the user namespace is to be used, but they don't bother stripping the prefix from the name passed the FreeBSD syscalls.

diff --git i/contrib/capsicum-test/syscalls.h w/contrib/capsicum-test/syscalls.h
index 592a1677e1f1..3ea8803c2f64 100644
--- i/contrib/capsicum-test/syscalls.h
+++ w/contrib/capsicum-test/syscalls.h
@@ -47,16 +47,29 @@ inline int bogus_mount_() {
 
 /* Mappings for extended attribute functions */
 #include <sys/extattr.h>
+#include <errno.h>
+static const char *fbsd_extattr_skip_prefix(const char *p) {
+  if (*p++ == 'u' && *p++ == 's' && *p++ == 'e' && *p++ == 'r' && *p++ == '.')
+    return p;
+  errno = EINVAL;
+  return NULL;
+}
 inline ssize_t flistxattr_(int fd, char *list, size_t size) {
   return extattr_list_fd(fd, EXTATTR_NAMESPACE_USER, list, size);
 }
 inline ssize_t fgetxattr_(int fd, const char *name, void *value, size_t size) {
+  if (!(name = fbsd_extattr_skip_prefix(name)))
+    return -1;
   return extattr_get_fd(fd, EXTATTR_NAMESPACE_USER, name, value, size);
 }
 inline int fsetxattr_(int fd, const char *name, const void *value, size_t size, int) {
+  if (!(name = fbsd_extattr_skip_prefix(name)))
+    return -1;
   return extattr_set_fd(fd, EXTATTR_NAMESPACE_USER, name, value, size);
 }
 inline int fremovexattr_(int fd, const char *name) {
+  if (!(name = fbsd_extattr_skip_prefix(name)))
+    return -1;
   return extattr_delete_fd(fd, EXTATTR_NAMESPACE_USER, name);
 }
Comment 1 Ed Maste freebsd_committer freebsd_triage 2022-08-30 16:08:43 UTC
Related commit:

commit 5c0061345b824eebe7a6578528f873ffcaae1cdd
Author: Ryan Moeller <ryan@iXsystems.com>
Date:   Tue Feb 15 19:35:30 2022 -0500

    Cross-platform xattr user namespace compatibility

    ZFS on Linux originally implemented xattr namespaces in a way that is
    incompatible with other operating systems.  On illumos, xattrs do not
    have namespaces.  Every xattr name is visible.  FreeBSD has two
    universally defined namespaces: EXTATTR_NAMESPACE_USER and
    EXTATTR_NAMESPACE_SYSTEM.  The system namespace is used for protected
    FreeBSD-specific attributes such as MAC labels and pnfs state.  These
    attributes have the namespace string "freebsd:system:" prefixed to the
    name in the encoding scheme used by ZFS.  The user namespace is used
    for general purpose user attributes and obeys normal access control
    mechanisms.  These attributes have no namespace string prefixed, so
    xattrs written on illumos are accessible in the user namespace on
    FreeBSD, and xattrs written to the user namespace on FreeBSD are
    accessible by the same name on illumos.
    
    Linux has several xattr namespaces.  On Linux, ZFS encodes the
    namespace in the xattr name for every namespace, including the user
    namespace.  As a consequence, an xattr in the user namespace with the
    name "foo" is stored by ZFS with the name "user.foo" and therefore
    appears on FreeBSD and illumos to have the name "user.foo" rather than
    "foo".  Conversely, none of the xattrs written on FreeBSD or illumos
    are accessible on Linux unless the name happens to be prefixed with one
    of the Linux xattr namespaces, in which case the namespace is stripped
    from the name.  This makes xattrs entirely incompatible between Linux
    and other platforms.
    
    We want to make the encoding of user namespace xattrs compatible across
    platforms.  A critical requirement of this compatibility is for xattrs
    from existing pools from FreeBSD and illumos to be accessible by the
    same names in the user namespace on Linux.  It is also necessary that
    existing pools with xattrs written by Linux retain access to those
    xattrs by the same names on Linux.  Making user namespace xattrs from
    Linux accessible by the correct names on other platforms is important.
    The handling of other namespaces is not required to be consistent.
    
    Add a fallback mechanism for listing and getting xattrs to treat xattrs
    as being in the user namespace if they do not match a known prefix.
    
    Do not allow setting or getting xattrs with a name that is prefixed
    with one of the namespace names used by ZFS on supported platforms.
    
    Allow choosing between legacy illumos and FreeBSD compatibility and
    legacy Linux compatibility with a new tunable.  This facilitates
    replication and migration of pools between hosts with different
    compatibility needs.
    
    The tunable controls whether or not to prefix the namespace to the
    name.  If the xattr is already present with the alternate prefix,
    remove it so only the new version persists.  By default the platform's
    existing convention is used.
Comment 2 Ed Maste freebsd_committer freebsd_triage 2022-08-30 16:31:52 UTC
Would you be able to open a pull request at https://github.com/google/capsicum-test?
Comment 3 sigsys 2022-08-30 22:17:41 UTC
(In reply to Ed Maste from comment #2)

Alright, done!

https://github.com/google/capsicum-test/pull/58

Man this is a lot more trouble than just pasting a patch...