aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/dummy.c2
-rw-r--r--security/selinux/hooks.c46
2 files changed, 33 insertions, 15 deletions
diff --git a/security/dummy.c b/security/dummy.c
index 3d34f3de7e82..2a0337a52d32 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -377,7 +377,7 @@ static int dummy_inode_removexattr (struct dentry *dentry, char *name)
377 return 0; 377 return 0;
378} 378}
379 379
380static int dummy_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size) 380static int dummy_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
381{ 381{
382 return -EOPNOTSUPP; 382 return -EOPNOTSUPP;
383} 383}
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 8cd33b2cd865..d9ec85292e1c 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2208,9 +2208,6 @@ static int selinux_inode_getxattr (struct dentry *dentry, char *name)
2208 struct inode *inode = dentry->d_inode; 2208 struct inode *inode = dentry->d_inode;
2209 struct superblock_security_struct *sbsec = inode->i_sb->s_security; 2209 struct superblock_security_struct *sbsec = inode->i_sb->s_security;
2210 2210
2211 if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)
2212 return -EOPNOTSUPP;
2213
2214 return dentry_has_perm(current, NULL, dentry, FILE__GETATTR); 2211 return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
2215} 2212}
2216 2213
@@ -2241,33 +2238,54 @@ static int selinux_inode_removexattr (struct dentry *dentry, char *name)
2241 return -EACCES; 2238 return -EACCES;
2242} 2239}
2243 2240
2244static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size) 2241/*
2242 * Copy the in-core inode security context value to the user. If the
2243 * getxattr() prior to this succeeded, check to see if we need to
2244 * canonicalize the value to be finally returned to the user.
2245 *
2246 * Permission check is handled by selinux_inode_getxattr hook.
2247 */
2248static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
2245{ 2249{
2246 struct inode_security_struct *isec = inode->i_security; 2250 struct inode_security_struct *isec = inode->i_security;
2247 char *context; 2251 char *context;
2248 unsigned len; 2252 unsigned len;
2249 int rc; 2253 int rc;
2250 2254
2251 /* Permission check handled by selinux_inode_getxattr hook.*/ 2255 if (strcmp(name, XATTR_SELINUX_SUFFIX)) {
2252 2256 rc = -EOPNOTSUPP;
2253 if (strcmp(name, XATTR_SELINUX_SUFFIX)) 2257 goto out;
2254 return -EOPNOTSUPP; 2258 }
2255 2259
2256 rc = security_sid_to_context(isec->sid, &context, &len); 2260 rc = security_sid_to_context(isec->sid, &context, &len);
2257 if (rc) 2261 if (rc)
2258 return rc; 2262 goto out;
2259 2263
2264 /* Probe for required buffer size */
2260 if (!buffer || !size) { 2265 if (!buffer || !size) {
2261 kfree(context); 2266 rc = len;
2262 return len; 2267 goto out_free;
2263 } 2268 }
2269
2264 if (size < len) { 2270 if (size < len) {
2265 kfree(context); 2271 rc = -ERANGE;
2266 return -ERANGE; 2272 goto out_free;
2273 }
2274
2275 if (err > 0) {
2276 if ((len == err) && !(memcmp(context, buffer, len))) {
2277 /* Don't need to canonicalize value */
2278 rc = err;
2279 goto out_free;
2280 }
2281 memset(buffer, 0, size);
2267 } 2282 }
2268 memcpy(buffer, context, len); 2283 memcpy(buffer, context, len);
2284 rc = len;
2285out_free:
2269 kfree(context); 2286 kfree(context);
2270 return len; 2287out:
2288 return rc;
2271} 2289}
2272 2290
2273static int selinux_inode_setsecurity(struct inode *inode, const char *name, 2291static int selinux_inode_setsecurity(struct inode *inode, const char *name,