Pull lsm update from Paul Moore: "A single LSM update the security_inode_listsecurity() hook to be able to leverage the xattr_list_one() helper function. We wanted to do this for a while, but we needed to fixup the callers in the NFS code first. With the NFS code changes shipping in Linux v7.0 and no one complaining, it seemed a good time to complete the shift" * tag 'lsm-pr-20260615' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm: security,fs,nfs,net: update security_inode_listsecurity() interface
Unified · Split
| @@ -10564,13 +10564,10 @@ static ssize_t nfs4_listxattr(struct dentry *dentry, char *list, size_t size) · 10563 unmodified lines | |||
| 10564 | left -= error; | 10564 | left -= error; |
| 10565 | } | 10565 | } |
| 10566 | 10566 | ||
| 10567 | error2 = security_inode_listsecurity(d_inode(dentry), list, left); | 10567 | error2 = security_inode_listsecurity(d_inode(dentry), &list, &left); |
| 10568 | if (error2 < 0) | 10568 | if (error2 < 0) |
| 10569 | return error2; | 10569 | return error2; |
| 10570 | if (list) { | 10570 | error2 = size - error - left; |
| 10571 | list += error2; | ||
| 10572 | left -= error2; | ||
| 10573 | } | ||
| 10574 | 10571 | ||
| 10575 | error3 = nfs4_listxattr_nfs4_user(d_inode(dentry), list, left); | 10572 | error3 = nfs4_listxattr_nfs4_user(d_inode(dentry), list, left); |
| 10576 | if (error3 < 0) | 10573 | if (error3 < 0) |
| @@ -515,9 +515,12 @@ vfs_listxattr(struct dentry *dentry, char *list, size_t size) · 514 unmodified lines | |||
| 515 | if (inode->i_op->listxattr) { | 515 | if (inode->i_op->listxattr) { |
| 516 | error = inode->i_op->listxattr(dentry, list, size); | 516 | error = inode->i_op->listxattr(dentry, list, size); |
| 517 | } else { | 517 | } else { |
| 518 | error = security_inode_listsecurity(inode, list, size); | 518 | ssize_t remaining = size; |
| 519 | if (size && error > size) | 519 | |
| 520 | error = -ERANGE; | 520 | error = security_inode_listsecurity(inode, &list, &remaining); |
| 521 | if (error) | ||
| 522 | return error; | ||
| 523 | error = size - remaining; | ||
| 521 | } | 524 | } |
| 522 | return error; | 525 | return error; |
| 523 | } | 526 | } |
| @@ -1612,7 +1615,7 @@ ssize_t simple_xattr_list(struct inode *inode, struct list_head *xattrs, · 1088 unmodified lines | |||
| 1612 | if (err) | 1615 | if (err) |
| 1613 | return err; | 1616 | return err; |
| 1614 | 1617 | ||
| 1615 | err = security_inode_listsecurity(inode, buffer, remaining_size); | 1618 | err = security_inode_listsecurity(inode, &buffer, &remaining_size); |
| 1616 | if (err < 0) | 1619 | if (err < 0) |
| 1617 | return err; | 1620 | return err; |
| 1618 | 1621 | ||
| @@ -176,8 +176,8 @@ LSM_HOOK(int, -EOPNOTSUPP, inode_getsecurity, struct mnt_idmap *idmap, · 175 unmodified lines | |||
| 176 | struct inode *inode, const char *name, void **buffer, bool alloc) | 176 | struct inode *inode, const char *name, void **buffer, bool alloc) |
| 177 | LSM_HOOK(int, -EOPNOTSUPP, inode_setsecurity, struct inode *inode, | 177 | LSM_HOOK(int, -EOPNOTSUPP, inode_setsecurity, struct inode *inode, |
| 178 | const char *name, const void *value, size_t size, int flags) | 178 | const char *name, const void *value, size_t size, int flags) |
| 179 | LSM_HOOK(int, 0, inode_listsecurity, struct inode *inode, char *buffer, | 179 | LSM_HOOK(int, 0, inode_listsecurity, struct inode *inode, char **buffer, |
| 180 | size_t buffer_size) | 180 | ssize_t *remaining_size) |
| 181 | LSM_HOOK(void, LSM_RET_VOID, inode_getlsmprop, struct inode *inode, | 181 | LSM_HOOK(void, LSM_RET_VOID, inode_getlsmprop, struct inode *inode, |
| 182 | struct lsm_prop *prop) | 182 | struct lsm_prop *prop) |
| 183 | LSM_HOOK(int, 0, inode_copy_up, struct dentry *src, struct cred **new) | 183 | LSM_HOOK(int, 0, inode_copy_up, struct dentry *src, struct cred **new) |
| @@ -459,7 +459,7 @@ int security_inode_getsecurity(struct mnt_idmap *idmap, · 458 unmodified lines | |||
| 459 | struct inode *inode, const char *name, | 459 | struct inode *inode, const char *name, |
| 460 | void **buffer, bool alloc); | 460 | void **buffer, bool alloc); |
| 461 | int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags); | 461 | int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags); |
| 462 | int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size); | 462 | int security_inode_listsecurity(struct inode *inode, char **buffer, ssize_t *remaining_size); |
| 463 | void security_inode_getlsmprop(struct inode *inode, struct lsm_prop *prop); | 463 | void security_inode_getlsmprop(struct inode *inode, struct lsm_prop *prop); |
| 464 | int security_inode_copy_up(struct dentry *src, struct cred **new); | 464 | int security_inode_copy_up(struct dentry *src, struct cred **new); |
| 465 | int security_inode_copy_up_xattr(struct dentry *src, const char *name); | 465 | 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 · 631 unmodified lines | |||
| 1097 | return -EOPNOTSUPP; | 1097 | return -EOPNOTSUPP; |
| 1098 | } | 1098 | } |
| 1099 | 1099 | ||
| 1100 | static inline int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size) | 1100 | static inline int security_inode_listsecurity(struct inode *inode, |
| 1101 | char **buffer, ssize_t *remaining_size) | ||
| 1101 | { | 1102 | { |
| 1102 | return 0; | 1103 | return 0; |
| 1103 | } | 1104 | } |
| @@ -2258,22 +2258,22 @@ int security_inode_setsecurity(struct inode *inode, const char *name, · 2257 unmodified lines | |||
| 2258 | /** | 2258 | /** |
| 2259 | * security_inode_listsecurity() - List the xattr security label names | 2259 | * security_inode_listsecurity() - List the xattr security label names |
| 2260 | * @inode: inode | 2260 | * @inode: inode |
| 2261 | * @buffer: buffer | 2261 | * @buffer: pointer to buffer |
| 2262 | * @buffer_size: size of buffer | 2262 | * @remaining_size: pointer to remaining size of buffer |
| 2263 | * | 2263 | * |
| 2264 | * Copy the extended attribute names for the security labels associated with | 2264 | * Copy the extended attribute names for the security labels associated with |
| 2265 | * @inode into @buffer. The maximum size of @buffer is specified by | 2265 | * @inode into *(@buffer). The remaining size of @buffer is specified by |
| 2266 | * @buffer_size. @buffer may be NULL to request the size of the buffer | 2266 | * *(@remaining_size). *(@buffer) may be NULL to request the size of the |
| 2267 | * required. | 2267 | * buffer required. Updates *(@buffer) and *(@remaining_size). |
| 2268 | * | 2268 | * |
| 2269 | * Return: Returns number of bytes used/required on success. | 2269 | * Return: Returns 0 on success, or -errno on failure. |
| 2270 | */ | 2270 | */ |
| 2271 | int security_inode_listsecurity(struct inode *inode, | 2271 | int security_inode_listsecurity(struct inode *inode, |
| 2272 | char *buffer, size_t buffer_size) | 2272 | char **buffer, ssize_t *remaining_size) |
| 2273 | { | 2273 | { |
| 2274 | if (unlikely(IS_PRIVATE(inode))) | 2274 | if (unlikely(IS_PRIVATE(inode))) |
| 2275 | return 0; | 2275 | return 0; |
| 2276 | return call_int_hook(inode_listsecurity, inode, buffer, buffer_size); | 2276 | return call_int_hook(inode_listsecurity, inode, buffer, remaining_size); |
| 2277 | } | 2277 | } |
| 2278 | EXPORT_SYMBOL(security_inode_listsecurity); | 2278 | EXPORT_SYMBOL(security_inode_listsecurity); |
| 2279 | 2279 | ||
| @@ -3680,16 +3680,12 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name, · 3679 unmodified lines | |||
| 3680 | return 0; | 3680 | return 0; |
| 3681 | } | 3681 | } |
| 3682 | 3682 | ||
| 3683 | static int selinux_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size) | 3683 | static int selinux_inode_listsecurity(struct inode *inode, char **buffer, |
| 3684 | ssize_t *remaining_size) | ||
| 3684 | { | 3685 | { |
| 3685 | const int len = sizeof(XATTR_NAME_SELINUX); | ||
| 3686 | |||
| 3687 | if (!selinux_initialized()) | 3686 | if (!selinux_initialized()) |
| 3688 | return 0; | 3687 | return 0; |
| 3689 | 3688 | return xattr_list_one(buffer, remaining_size, XATTR_NAME_SELINUX); | |
| 3690 | if (buffer && len <= buffer_size) | ||
| 3691 | memcpy(buffer, XATTR_NAME_SELINUX, len); | ||
| 3692 | return len; | ||
| 3693 | } | 3689 | } |
| 3694 | 3690 | ||
| 3695 | static void selinux_inode_getlsmprop(struct inode *inode, struct lsm_prop *prop) | 3691 | static void selinux_inode_getlsmprop(struct inode *inode, struct lsm_prop *prop) |
| @@ -1665,17 +1665,12 @@ static int smack_inode_getsecurity(struct mnt_idmap *idmap, · 1664 unmodified lines | |||
| 1665 | * smack_inode_listsecurity - list the Smack attributes | 1665 | * smack_inode_listsecurity - list the Smack attributes |
| 1666 | * @inode: the object | 1666 | * @inode: the object |
| 1667 | * @buffer: where they go | 1667 | * @buffer: where they go |
| 1668 | * @buffer_size: size of buffer | 1668 | * @remaining_size: size of buffer |
| 1669 | */ | 1669 | */ |
| 1670 | static int smack_inode_listsecurity(struct inode *inode, char *buffer, | 1670 | static int smack_inode_listsecurity(struct inode *inode, char **buffer, |
| 1671 | size_t buffer_size) | 1671 | ssize_t *remaining_size) |
| 1672 | { | 1672 | { |
| 1673 | int len = sizeof(XATTR_NAME_SMACK); | 1673 | return xattr_list_one(buffer, remaining_size, XATTR_NAME_SMACK); |
| 1674 | |||
| 1675 | if (buffer != NULL && len <= buffer_size) | ||
| 1676 | memcpy(buffer, XATTR_NAME_SMACK, len); | ||
| 1677 | |||
| 1678 | return len; | ||
| 1679 | } | 1674 | } |
| 1680 | 1675 | ||
| 1681 | /** | 1676 | /** |