diff options
Diffstat (limited to 'security/selinux')
-rw-r--r-- | security/selinux/hooks.c | 46 |
1 files changed, 32 insertions, 14 deletions
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 | ||
2244 | static 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 | */ | ||
2248 | static 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; | ||
2285 | out_free: | ||
2269 | kfree(context); | 2286 | kfree(context); |
2270 | return len; | 2287 | out: |
2288 | return rc; | ||
2271 | } | 2289 | } |
2272 | 2290 | ||
2273 | static int selinux_inode_setsecurity(struct inode *inode, const char *name, | 2291 | static int selinux_inode_setsecurity(struct inode *inode, const char *name, |