aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJames Morris <jmorris@namei.org>2005-10-30 17:59:22 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-10-30 20:37:11 -0500
commitd381d8a9a08cac9824096213069159be17fd2e2f (patch)
tree0c19722b8f67c29b7c08c6ab8776a9c146395d03 /fs
parent89d155ef62e5e0c10e4b37aaa5056f0beafe10e6 (diff)
[PATCH] SELinux: canonicalize getxattr()
This patch allows SELinux to canonicalize the value returned from getxattr() via the security_inode_getsecurity() hook, which is called after the fs level getxattr() function. The purpose of this is to allow the in-core security context for an inode to override the on-disk value. This could happen in cases such as upgrading a system to a different labeling form (e.g. standard SELinux to MLS) without needing to do a full relabel of the filesystem. In such cases, we want getxattr() to return the canonical security context that the kernel is using rather than what is stored on disk. The implementation hooks into the inode_getsecurity(), adding another parameter to indicate the result of the preceding fs-level getxattr() call, so that SELinux knows whether to compare a value obtained from disk with the kernel value. We also now allow getxattr() to work for mountpoint labeled filesystems (i.e. mount with option context=foo_t), as we are able to return the kernel value to the user. Signed-off-by: James Morris <jmorris@namei.org> Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/xattr.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/fs/xattr.c b/fs/xattr.c
index 3f9c64bea151..f6e00c0e114f 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -143,7 +143,7 @@ getxattr(struct dentry *d, char __user *name, void __user *value, size_t size)
143 if (size) { 143 if (size) {
144 if (size > XATTR_SIZE_MAX) 144 if (size > XATTR_SIZE_MAX)
145 size = XATTR_SIZE_MAX; 145 size = XATTR_SIZE_MAX;
146 kvalue = kmalloc(size, GFP_KERNEL); 146 kvalue = kzalloc(size, GFP_KERNEL);
147 if (!kvalue) 147 if (!kvalue)
148 return -ENOMEM; 148 return -ENOMEM;
149 } 149 }
@@ -154,11 +154,15 @@ getxattr(struct dentry *d, char __user *name, void __user *value, size_t size)
154 error = -EOPNOTSUPP; 154 error = -EOPNOTSUPP;
155 if (d->d_inode->i_op && d->d_inode->i_op->getxattr) 155 if (d->d_inode->i_op && d->d_inode->i_op->getxattr)
156 error = d->d_inode->i_op->getxattr(d, kname, kvalue, size); 156 error = d->d_inode->i_op->getxattr(d, kname, kvalue, size);
157 else if (!strncmp(kname, XATTR_SECURITY_PREFIX, 157
158 sizeof XATTR_SECURITY_PREFIX - 1)) { 158 if (!strncmp(kname, XATTR_SECURITY_PREFIX,
159 sizeof XATTR_SECURITY_PREFIX - 1)) {
159 const char *suffix = kname + sizeof XATTR_SECURITY_PREFIX - 1; 160 const char *suffix = kname + sizeof XATTR_SECURITY_PREFIX - 1;
160 error = security_inode_getsecurity(d->d_inode, suffix, kvalue, 161 int rv = security_inode_getsecurity(d->d_inode, suffix, kvalue,
161 size); 162 size, error);
163 /* Security module active: overwrite error value */
164 if (rv != -EOPNOTSUPP)
165 error = rv;
162 } 166 }
163 if (error > 0) { 167 if (error > 0) {
164 if (size && copy_to_user(value, kvalue, error)) 168 if (size && copy_to_user(value, kvalue, error))