summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/nfs4proc.c7
-rw-r--r--fs/xattr.c11
-rw-r--r--include/linux/lsm_hook_defs.h4
-rw-r--r--include/linux/security.h5
-rw-r--r--security/security.c16
-rw-r--r--security/selinux/hooks.c10
-rw-r--r--security/smack/smack_lsm.c13
7 files changed, 29 insertions, 37 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 0715a6745d1f..c48281db3868 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -10564,13 +10564,10 @@ static ssize_t nfs4_listxattr(struct dentry *dentry, char *list, size_t size)
left -= error;
}
- error2 = security_inode_listsecurity(d_inode(dentry), list, left);
+ error2 = security_inode_listsecurity(d_inode(dentry), &list, &left);
if (error2 < 0)
return error2;
- if (list) {
- list += error2;
- left -= error2;
- }
+ error2 = size - error - left;
error3 = nfs4_listxattr_nfs4_user(d_inode(dentry), list, left);
if (error3 < 0)
diff --git a/fs/xattr.c b/fs/xattr.c
index e1fc688158eb..d58979115200 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -515,9 +515,12 @@ vfs_listxattr(struct dentry *dentry, char *list, size_t size)
if (inode->i_op->listxattr) {
error = inode->i_op->listxattr(dentry, list, size);
} else {
- error = security_inode_listsecurity(inode, list, size);
- if (size && error > size)
- error = -ERANGE;
+ ssize_t remaining = size;
+
+ error = security_inode_listsecurity(inode, &list, &remaining);
+ if (error)
+ return error;
+ error = size - remaining;
}
return error;
}
@@ -1612,7 +1615,7 @@ ssize_t simple_xattr_list(struct inode *inode, struct list_head *xattrs,
if (err)
return err;
- err = security_inode_listsecurity(inode, buffer, remaining_size);
+ err = security_inode_listsecurity(inode, &buffer, &remaining_size);
if (err < 0)
return err;
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 2b8dfb35caed..65c9609ec207 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -176,8 +176,8 @@ LSM_HOOK(int, -EOPNOTSUPP, inode_getsecurity, struct mnt_idmap *idmap,
struct inode *inode, const char *name, void **buffer, bool alloc)
LSM_HOOK(int, -EOPNOTSUPP, inode_setsecurity, struct inode *inode,
const char *name, const void *value, size_t size, int flags)
-LSM_HOOK(int, 0, inode_listsecurity, struct inode *inode, char *buffer,
- size_t buffer_size)
+LSM_HOOK(int, 0, inode_listsecurity, struct inode *inode, char **buffer,
+ ssize_t *remaining_size)
LSM_HOOK(void, LSM_RET_VOID, inode_getlsmprop, struct inode *inode,
struct lsm_prop *prop)
LSM_HOOK(int, 0, inode_copy_up, struct dentry *src, struct cred **new)
diff --git a/include/linux/security.h b/include/linux/security.h
index 41d7367cf403..153e9043058f 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -459,7 +459,7 @@ int security_inode_getsecurity(struct mnt_idmap *idmap,
struct inode *inode, const char *name,
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_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);
int security_inode_copy_up(struct dentry *src, struct cred **new);
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;
}
-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;
}
diff --git a/security/security.c b/security/security.c
index 4e999f023651..71aea8fdf014 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2258,22 +2258,22 @@ int security_inode_setsecurity(struct inode *inode, const char *name,
/**
* security_inode_listsecurity() - List the xattr security label names
* @inode: inode
- * @buffer: buffer
- * @buffer_size: size of buffer
+ * @buffer: pointer to buffer
+ * @remaining_size: pointer to remaining size of buffer
*
* Copy the extended attribute names for the security labels associated with
- * @inode into @buffer. The maximum size of @buffer is specified by
- * @buffer_size. @buffer may be NULL to request the size of the buffer
- * required.
+ * @inode into *(@buffer). The remaining size of @buffer is specified by
+ * *(@remaining_size). *(@buffer) may be NULL to request the size of the
+ * 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,
- char *buffer, size_t buffer_size)
+ char **buffer, ssize_t *remaining_size)
{
if (unlikely(IS_PRIVATE(inode)))
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);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 0f704380a8c8..1a713d96206f 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3680,16 +3680,12 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name,
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())
return 0;
-
- if (buffer && len <= buffer_size)
- memcpy(buffer, XATTR_NAME_SELINUX, len);
- return len;
+ return xattr_list_one(buffer, remaining_size, XATTR_NAME_SELINUX);
}
static void selinux_inode_getlsmprop(struct inode *inode, struct lsm_prop *prop)
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 3f9ae05039a2..ff115068c5c0 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -1665,17 +1665,12 @@ static int smack_inode_getsecurity(struct mnt_idmap *idmap,
* smack_inode_listsecurity - list the Smack attributes
* @inode: the object
* @buffer: where they go
- * @buffer_size: size of buffer
+ * @remaining_size: size of buffer
*/
-static int smack_inode_listsecurity(struct inode *inode, char *buffer,
- size_t buffer_size)
+static int smack_inode_listsecurity(struct inode *inode, char **buffer,
+ ssize_t *remaining_size)
{
- int len = sizeof(XATTR_NAME_SMACK);
-
- if (buffer != NULL && len <= buffer_size)
- memcpy(buffer, XATTR_NAME_SMACK, len);
-
- return len;
+ return xattr_list_one(buffer, remaining_size, XATTR_NAME_SMACK);
}
/**