[RFC PATCH 3/9] smb: client: support trusted xattrs over EAs
Ze Tan <[email protected]> Wed, 15 Jul 2026 15:48:44 +0800
| Newsgroups | gmane.linux.kernel,gmane.linux.kernel.cifs,gmane.network.samba.internals |
|---|---|
| Message-ID | <[email protected]> |
generic/093 uses setfattr and getfattr to check that a write does not clear trusted.name. The CIFS client does not have a trusted xattr handler, so these commands cannot set or read trusted xattrs through SMB EAs. Register a trusted xattr handler and build the complete trusted EA name for SET_INFO and QUERY_INFO. Keep the trusted prefix in EA lists. Signed-off-by: Ze Tan <[email protected]> --- fs/smb/client/smb2ops.c | 4 ++++ fs/smb/client/xattr.c | 40 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index bfa089511b9b..e1f88a0c6842 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -1046,6 +1046,10 @@ static int smb2_query_file_info(const unsigned int xid, struct cifs_tcon *tcon, #ifdef CONFIG_CIFS_XATTR static bool cifs_passthrough(const char *name, size_t name_len) { + if (name_len > XATTR_TRUSTED_PREFIX_LEN && + !memcmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) + return true; + if (name_len == sizeof(XATTR_NAME_CAPS) - 1 && !memcmp(name, XATTR_NAME_CAPS, name_len)) return true; diff --git a/fs/smb/client/xattr.c b/fs/smb/client/xattr.c index 42db6920901e..3dae8b23aca7 100644 --- a/fs/smb/client/xattr.c +++ b/fs/smb/client/xattr.c @@ -36,7 +36,7 @@ #define SMB3_XATTR_CIFS_NTSD_FULL "system.smb3_ntsd_full" /* owner/DACL/SACL */ #define SMB3_XATTR_ATTRIB "smb3.dosattrib" /* full name: user.smb3.dosattrib */ #define SMB3_XATTR_CREATETIME "smb3.creationtime" /* user.smb3.creationtime */ -enum { XATTR_USER, XATTR_SECURITY, +enum { XATTR_USER, XATTR_TRUSTED, XATTR_SECURITY, XATTR_CIFS_ACL, XATTR_ACL_ACCESS, XATTR_ACL_DEFAULT, XATTR_CIFS_NTSD_SACL, XATTR_CIFS_NTSD_OWNER, XATTR_CIFS_NTSD, XATTR_CIFS_NTSD_FULL }; @@ -64,6 +64,16 @@ static int cifs_build_ea_name(int xattr_flag, const char *name, char *ea_name, memcpy(ea_name + XATTR_SECURITY_PREFIX_LEN, name, name_len + 1); return XATTR_SECURITY_PREFIX_LEN + name_len; + case XATTR_TRUSTED: + name_len = strlen(name); + if (ea_name_size <= XATTR_TRUSTED_PREFIX_LEN || + name_len > ea_name_size - XATTR_TRUSTED_PREFIX_LEN - 1) + return -ERANGE; + memcpy(ea_name, XATTR_TRUSTED_PREFIX, + XATTR_TRUSTED_PREFIX_LEN); + memcpy(ea_name + XATTR_TRUSTED_PREFIX_LEN, name, + name_len + 1); + return XATTR_TRUSTED_PREFIX_LEN + name_len; default: return -EOPNOTSUPP; } @@ -160,6 +170,16 @@ static int cifs_xattr_set(const struct xattr_handler *handler, } switch (handler->flags) { + case XATTR_TRUSTED: + rc = cifs_build_ea_name(handler->flags, name, ea_name, + sizeof(ea_name)); + if (rc < 0) + goto out; + server_ea_name = ea_name; + cifs_dbg(FYI, "%s: setting trusted xattr %s\n", + __func__, name); + goto set_ea; + case XATTR_SECURITY: rc = cifs_build_ea_name(handler->flags, name, ea_name, sizeof(ea_name)); @@ -339,6 +359,16 @@ static int cifs_xattr_get(const struct xattr_handler *handler, /* return alt name if available as pseudo attr */ switch (handler->flags) { + case XATTR_TRUSTED: + rc = cifs_build_ea_name(handler->flags, name, ea_name, + sizeof(ea_name)); + if (rc < 0) + goto out; + server_ea_name = ea_name; + cifs_dbg(FYI, "%s: querying trusted xattr %s\n", + __func__, name); + goto query_ea; + case XATTR_SECURITY: rc = cifs_build_ea_name(handler->flags, name, ea_name, sizeof(ea_name)); @@ -491,6 +521,13 @@ static const struct xattr_handler cifs_user_xattr_handler = { .set = cifs_xattr_set, }; +static const struct xattr_handler cifs_trusted_xattr_handler = { + .prefix = XATTR_TRUSTED_PREFIX, + .flags = XATTR_TRUSTED, + .get = cifs_xattr_get, + .set = cifs_xattr_set, +}; + static const struct xattr_handler cifs_security_xattr_handler = { .prefix = XATTR_SECURITY_PREFIX, .flags = XATTR_SECURITY, @@ -582,6 +619,7 @@ static const struct xattr_handler smb3_ntsd_full_xattr_handler = { const struct xattr_handler * const cifs_xattr_handlers[] = { &cifs_user_xattr_handler, + &cifs_trusted_xattr_handler, &cifs_security_xattr_handler, &cifs_os2_xattr_handler, &cifs_cifs_acl_xattr_handler, -- 2.43.0