aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xattr.c30
-rw-r--r--include/linux/security.h21
-rw-r--r--include/linux/xattr.h1
-rw-r--r--mm/shmem.c3
-rw-r--r--security/dummy.c2
-rw-r--r--security/security.c4
-rw-r--r--security/selinux/hooks.c43
7 files changed, 57 insertions, 47 deletions
diff --git a/fs/xattr.c b/fs/xattr.c
index 6645b7313b33..1858552a6a1a 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -105,6 +105,33 @@ out:
105EXPORT_SYMBOL_GPL(vfs_setxattr); 105EXPORT_SYMBOL_GPL(vfs_setxattr);
106 106
107ssize_t 107ssize_t
108xattr_getsecurity(struct inode *inode, const char *name, void *value,
109 size_t size)
110{
111 void *buffer = NULL;
112 ssize_t len;
113
114 if (!value || !size) {
115 len = security_inode_getsecurity(inode, name, &buffer, false);
116 goto out_noalloc;
117 }
118
119 len = security_inode_getsecurity(inode, name, &buffer, true);
120 if (len < 0)
121 return len;
122 if (size < len) {
123 len = -ERANGE;
124 goto out;
125 }
126 memcpy(value, buffer, len);
127out:
128 security_release_secctx(buffer, len);
129out_noalloc:
130 return len;
131}
132EXPORT_SYMBOL_GPL(xattr_getsecurity);
133
134ssize_t
108vfs_getxattr(struct dentry *dentry, char *name, void *value, size_t size) 135vfs_getxattr(struct dentry *dentry, char *name, void *value, size_t size)
109{ 136{
110 struct inode *inode = dentry->d_inode; 137 struct inode *inode = dentry->d_inode;
@@ -126,8 +153,7 @@ vfs_getxattr(struct dentry *dentry, char *name, void *value, size_t size)
126 if (!strncmp(name, XATTR_SECURITY_PREFIX, 153 if (!strncmp(name, XATTR_SECURITY_PREFIX,
127 XATTR_SECURITY_PREFIX_LEN)) { 154 XATTR_SECURITY_PREFIX_LEN)) {
128 const char *suffix = name + XATTR_SECURITY_PREFIX_LEN; 155 const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
129 int ret = security_inode_getsecurity(inode, suffix, value, 156 int ret = xattr_getsecurity(inode, suffix, value, size);
130 size, error);
131 /* 157 /*
132 * Only overwrite the return value if a security module 158 * Only overwrite the return value if a security module
133 * is actually active. 159 * is actually active.
diff --git a/include/linux/security.h b/include/linux/security.h
index d24974262dc6..9d289e726fd8 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -423,15 +423,12 @@ struct request_sock;
423 * identified by @name for @dentry. 423 * identified by @name for @dentry.
424 * Return 0 if permission is granted. 424 * Return 0 if permission is granted.
425 * @inode_getsecurity: 425 * @inode_getsecurity:
426 * Copy the extended attribute representation of the security label 426 * Retrieve a copy of the extended attribute representation of the
427 * associated with @name for @inode into @buffer. @buffer may be 427 * security label associated with @name for @inode via @buffer. Note that
428 * NULL to request the size of the buffer required. @size indicates 428 * @name is the remainder of the attribute name after the security prefix
429 * the size of @buffer in bytes. Note that @name is the remainder 429 * has been removed. @alloc is used to specify of the call should return a
430 * of the attribute name after the security. prefix has been removed. 430 * value via the buffer or just the value length Return size of buffer on
431 * @err is the return value from the preceding fs getxattr call, 431 * success.
432 * and can be used by the security module to determine whether it
433 * should try and canonicalize the attribute value.
434 * Return number of bytes used/required on success.
435 * @inode_setsecurity: 432 * @inode_setsecurity:
436 * Set the security label associated with @name for @inode from the 433 * Set the security label associated with @name for @inode from the
437 * extended attribute value @value. @size indicates the size of the 434 * extended attribute value @value. @size indicates the size of the
@@ -1304,7 +1301,7 @@ struct security_operations {
1304 int (*inode_removexattr) (struct dentry *dentry, char *name); 1301 int (*inode_removexattr) (struct dentry *dentry, char *name);
1305 int (*inode_need_killpriv) (struct dentry *dentry); 1302 int (*inode_need_killpriv) (struct dentry *dentry);
1306 int (*inode_killpriv) (struct dentry *dentry); 1303 int (*inode_killpriv) (struct dentry *dentry);
1307 int (*inode_getsecurity)(const struct inode *inode, const char *name, void *buffer, size_t size, int err); 1304 int (*inode_getsecurity)(const struct inode *inode, const char *name, void **buffer, bool alloc);
1308 int (*inode_setsecurity)(struct inode *inode, const char *name, const void *value, size_t size, int flags); 1305 int (*inode_setsecurity)(struct inode *inode, const char *name, const void *value, size_t size, int flags);
1309 int (*inode_listsecurity)(struct inode *inode, char *buffer, size_t buffer_size); 1306 int (*inode_listsecurity)(struct inode *inode, char *buffer, size_t buffer_size);
1310 1307
@@ -1565,7 +1562,7 @@ int security_inode_listxattr(struct dentry *dentry);
1565int security_inode_removexattr(struct dentry *dentry, char *name); 1562int security_inode_removexattr(struct dentry *dentry, char *name);
1566int security_inode_need_killpriv(struct dentry *dentry); 1563int security_inode_need_killpriv(struct dentry *dentry);
1567int security_inode_killpriv(struct dentry *dentry); 1564int security_inode_killpriv(struct dentry *dentry);
1568int security_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err); 1565int security_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc);
1569int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags); 1566int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags);
1570int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size); 1567int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size);
1571int security_file_permission(struct file *file, int mask); 1568int security_file_permission(struct file *file, int mask);
@@ -1967,7 +1964,7 @@ static inline int security_inode_killpriv(struct dentry *dentry)
1967 return cap_inode_killpriv(dentry); 1964 return cap_inode_killpriv(dentry);
1968} 1965}
1969 1966
1970static inline int security_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err) 1967static inline int security_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc)
1971{ 1968{
1972 return -EOPNOTSUPP; 1969 return -EOPNOTSUPP;
1973} 1970}
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index def131a5ac70..df6b95d2218e 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -46,6 +46,7 @@ struct xattr_handler {
46 size_t size, int flags); 46 size_t size, int flags);
47}; 47};
48 48
49ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t);
49ssize_t vfs_getxattr(struct dentry *, char *, void *, size_t); 50ssize_t vfs_getxattr(struct dentry *, char *, void *, size_t);
50ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size); 51ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
51int vfs_setxattr(struct dentry *, char *, void *, size_t, int); 52int vfs_setxattr(struct dentry *, char *, void *, size_t, int);
diff --git a/mm/shmem.c b/mm/shmem.c
index ee9024483f60..0f246c44a574 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1955,8 +1955,7 @@ static int shmem_xattr_security_get(struct inode *inode, const char *name,
1955{ 1955{
1956 if (strcmp(name, "") == 0) 1956 if (strcmp(name, "") == 0)
1957 return -EINVAL; 1957 return -EINVAL;
1958 return security_inode_getsecurity(inode, name, buffer, size, 1958 return xattr_getsecurity(inode, name, buffer, size);
1959 -EOPNOTSUPP);
1960} 1959}
1961 1960
1962static int shmem_xattr_security_set(struct inode *inode, const char *name, 1961static int shmem_xattr_security_set(struct inode *inode, const char *name,
diff --git a/security/dummy.c b/security/dummy.c
index 48d4b0a52737..c505122e22db 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -402,7 +402,7 @@ static int dummy_inode_killpriv(struct dentry *dentry)
402 return 0; 402 return 0;
403} 403}
404 404
405static int dummy_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err) 405static int dummy_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc)
406{ 406{
407 return -EOPNOTSUPP; 407 return -EOPNOTSUPP;
408} 408}
diff --git a/security/security.c b/security/security.c
index ca475ca206e4..b6c57a6b2ff5 100644
--- a/security/security.c
+++ b/security/security.c
@@ -493,11 +493,11 @@ int security_inode_killpriv(struct dentry *dentry)
493 return security_ops->inode_killpriv(dentry); 493 return security_ops->inode_killpriv(dentry);
494} 494}
495 495
496int security_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err) 496int security_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc)
497{ 497{
498 if (unlikely(IS_PRIVATE(inode))) 498 if (unlikely(IS_PRIVATE(inode)))
499 return 0; 499 return 0;
500 return security_ops->inode_getsecurity(inode, name, buffer, size, err); 500 return security_ops->inode_getsecurity(inode, name, buffer, alloc);
501} 501}
502 502
503int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags) 503int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index be6de0b8734f..e5ed07510309 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -136,32 +136,6 @@ static DEFINE_SPINLOCK(sb_security_lock);
136 136
137static struct kmem_cache *sel_inode_cache; 137static struct kmem_cache *sel_inode_cache;
138 138
139/* Return security context for a given sid or just the context
140 length if the buffer is null or length is 0 */
141static int selinux_getsecurity(u32 sid, void *buffer, size_t size)
142{
143 char *context;
144 unsigned len;
145 int rc;
146
147 rc = security_sid_to_context(sid, &context, &len);
148 if (rc)
149 return rc;
150
151 if (!buffer || !size)
152 goto getsecurity_exit;
153
154 if (size < len) {
155 len = -ERANGE;
156 goto getsecurity_exit;
157 }
158 memcpy(buffer, context, len);
159
160getsecurity_exit:
161 kfree(context);
162 return len;
163}
164
165/** 139/**
166 * selinux_secmark_enabled - Check to see if SECMARK is currently enabled 140 * selinux_secmark_enabled - Check to see if SECMARK is currently enabled
167 * 141 *
@@ -2675,14 +2649,27 @@ static int selinux_inode_removexattr (struct dentry *dentry, char *name)
2675 * 2649 *
2676 * Permission check is handled by selinux_inode_getxattr hook. 2650 * Permission check is handled by selinux_inode_getxattr hook.
2677 */ 2651 */
2678static int selinux_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err) 2652static int selinux_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc)
2679{ 2653{
2654 u32 size;
2655 int error;
2656 char *context = NULL;
2680 struct inode_security_struct *isec = inode->i_security; 2657 struct inode_security_struct *isec = inode->i_security;
2681 2658
2682 if (strcmp(name, XATTR_SELINUX_SUFFIX)) 2659 if (strcmp(name, XATTR_SELINUX_SUFFIX))
2683 return -EOPNOTSUPP; 2660 return -EOPNOTSUPP;
2684 2661
2685 return selinux_getsecurity(isec->sid, buffer, size); 2662 error = security_sid_to_context(isec->sid, &context, &size);
2663 if (error)
2664 return error;
2665 error = size;
2666 if (alloc) {
2667 *buffer = context;
2668 goto out_nofree;
2669 }
2670 kfree(context);
2671out_nofree:
2672 return error;
2686} 2673}
2687 2674
2688static int selinux_inode_setsecurity(struct inode *inode, const char *name, 2675static int selinux_inode_setsecurity(struct inode *inode, const char *name,