security,fs,nfs,net: update security_inode_listsecurity() interface

Update the security_inode_listsecurity() interface to allow
use of the xattr_list_one() helper and update the hook
implementations.

Link: https://lore.kernel.org/selinux/20250424152822.2719-1-stephen.smalley.work@gmail.com
Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com>
[PM: forward porting to bring this patch up to v7.1-rc1+]
Signed-off-by: Paul Moore <paul@paul-moore.com>
This commit is contained in:
Stephen Smalley
2025-04-28 15:50:19 -04:00
committed by Paul Moore
parent 254f49634e
commit f71ece9712
7 changed files with 29 additions and 37 deletions

View File

@@ -10562,13 +10562,10 @@ static ssize_t nfs4_listxattr(struct dentry *dentry, char *list, size_t size)
left -= error; left -= error;
} }
error2 = security_inode_listsecurity(d_inode(dentry), list, left); error2 = security_inode_listsecurity(d_inode(dentry), &list, &left);
if (error2 < 0) if (error2 < 0)
return error2; return error2;
if (list) { error2 = size - error - left;
list += error2;
left -= error2;
}
error3 = nfs4_listxattr_nfs4_user(d_inode(dentry), list, left); error3 = nfs4_listxattr_nfs4_user(d_inode(dentry), list, left);
if (error3 < 0) if (error3 < 0)

View File

@@ -510,9 +510,12 @@ vfs_listxattr(struct dentry *dentry, char *list, size_t size)
if (inode->i_op->listxattr) { if (inode->i_op->listxattr) {
error = inode->i_op->listxattr(dentry, list, size); error = inode->i_op->listxattr(dentry, list, size);
} else { } else {
error = security_inode_listsecurity(inode, list, size); ssize_t remaining = size;
if (size && error > size)
error = -ERANGE; error = security_inode_listsecurity(inode, &list, &remaining);
if (error)
return error;
error = size - remaining;
} }
return error; return error;
} }
@@ -1540,7 +1543,7 @@ ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs,
if (err) if (err)
return err; return err;
err = security_inode_listsecurity(inode, buffer, remaining_size); err = security_inode_listsecurity(inode, &buffer, &remaining_size);
if (err < 0) if (err < 0)
return err; return err;

View File

@@ -176,8 +176,8 @@ LSM_HOOK(int, -EOPNOTSUPP, inode_getsecurity, struct mnt_idmap *idmap,
struct inode *inode, const char *name, void **buffer, bool alloc) struct inode *inode, const char *name, void **buffer, bool alloc)
LSM_HOOK(int, -EOPNOTSUPP, inode_setsecurity, struct inode *inode, LSM_HOOK(int, -EOPNOTSUPP, inode_setsecurity, struct inode *inode,
const char *name, const void *value, size_t size, int flags) const char *name, const void *value, size_t size, int flags)
LSM_HOOK(int, 0, inode_listsecurity, struct inode *inode, char *buffer, LSM_HOOK(int, 0, inode_listsecurity, struct inode *inode, char **buffer,
size_t buffer_size) ssize_t *remaining_size)
LSM_HOOK(void, LSM_RET_VOID, inode_getlsmprop, struct inode *inode, LSM_HOOK(void, LSM_RET_VOID, inode_getlsmprop, struct inode *inode,
struct lsm_prop *prop) struct lsm_prop *prop)
LSM_HOOK(int, 0, inode_copy_up, struct dentry *src, struct cred **new) LSM_HOOK(int, 0, inode_copy_up, struct dentry *src, struct cred **new)

View File

@@ -459,7 +459,7 @@ int security_inode_getsecurity(struct mnt_idmap *idmap,
struct inode *inode, const char *name, struct inode *inode, const char *name,
void **buffer, bool alloc); void **buffer, bool alloc);
int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags); int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags);
int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size); int security_inode_listsecurity(struct inode *inode, char **buffer, ssize_t *remaining_size);
void security_inode_getlsmprop(struct inode *inode, struct lsm_prop *prop); void security_inode_getlsmprop(struct inode *inode, struct lsm_prop *prop);
int security_inode_copy_up(struct dentry *src, struct cred **new); int security_inode_copy_up(struct dentry *src, struct cred **new);
int security_inode_copy_up_xattr(struct dentry *src, const char *name); int security_inode_copy_up_xattr(struct dentry *src, const char *name);
@@ -1097,7 +1097,8 @@ static inline int security_inode_setsecurity(struct inode *inode, const char *na
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static inline int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size) static inline int security_inode_listsecurity(struct inode *inode,
char **buffer, ssize_t *remaining_size)
{ {
return 0; return 0;
} }

View File

@@ -2258,22 +2258,22 @@ int security_inode_setsecurity(struct inode *inode, const char *name,
/** /**
* security_inode_listsecurity() - List the xattr security label names * security_inode_listsecurity() - List the xattr security label names
* @inode: inode * @inode: inode
* @buffer: buffer * @buffer: pointer to buffer
* @buffer_size: size of buffer * @remaining_size: pointer to remaining size of buffer
* *
* Copy the extended attribute names for the security labels associated with * Copy the extended attribute names for the security labels associated with
* @inode into @buffer. The maximum size of @buffer is specified by * @inode into *(@buffer). The remaining size of @buffer is specified by
* @buffer_size. @buffer may be NULL to request the size of the buffer * *(@remaining_size). *(@buffer) may be NULL to request the size of the
* required. * buffer required. Updates *(@buffer) and *(@remaining_size).
* *
* Return: Returns number of bytes used/required on success. * Return: Returns 0 on success, or -errno on failure.
*/ */
int security_inode_listsecurity(struct inode *inode, int security_inode_listsecurity(struct inode *inode,
char *buffer, size_t buffer_size) char **buffer, ssize_t *remaining_size)
{ {
if (unlikely(IS_PRIVATE(inode))) if (unlikely(IS_PRIVATE(inode)))
return 0; return 0;
return call_int_hook(inode_listsecurity, inode, buffer, buffer_size); return call_int_hook(inode_listsecurity, inode, buffer, remaining_size);
} }
EXPORT_SYMBOL(security_inode_listsecurity); EXPORT_SYMBOL(security_inode_listsecurity);

View File

@@ -3684,16 +3684,12 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name,
return 0; return 0;
} }
static int selinux_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size) static int selinux_inode_listsecurity(struct inode *inode, char **buffer,
ssize_t *remaining_size)
{ {
const int len = sizeof(XATTR_NAME_SELINUX);
if (!selinux_initialized()) if (!selinux_initialized())
return 0; return 0;
return xattr_list_one(buffer, remaining_size, XATTR_NAME_SELINUX);
if (buffer && len <= buffer_size)
memcpy(buffer, XATTR_NAME_SELINUX, len);
return len;
} }
static void selinux_inode_getlsmprop(struct inode *inode, struct lsm_prop *prop) static void selinux_inode_getlsmprop(struct inode *inode, struct lsm_prop *prop)

View File

@@ -1665,17 +1665,12 @@ static int smack_inode_getsecurity(struct mnt_idmap *idmap,
* smack_inode_listsecurity - list the Smack attributes * smack_inode_listsecurity - list the Smack attributes
* @inode: the object * @inode: the object
* @buffer: where they go * @buffer: where they go
* @buffer_size: size of buffer * @remaining_size: size of buffer
*/ */
static int smack_inode_listsecurity(struct inode *inode, char *buffer, static int smack_inode_listsecurity(struct inode *inode, char **buffer,
size_t buffer_size) ssize_t *remaining_size)
{ {
int len = sizeof(XATTR_NAME_SMACK); return xattr_list_one(buffer, remaining_size, XATTR_NAME_SMACK);
if (buffer != NULL && len <= buffer_size)
memcpy(buffer, XATTR_NAME_SMACK, len);
return len;
} }
/** /**