diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-25 03:45:31 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-25 03:45:31 -0400 |
commit | 36b8d186e6cc8e32cb5227f5645a58e1bc0af190 (patch) | |
tree | 1000ad26e189e6ff2c53fb7eeff605f59c7ad94e /security/security.c | |
parent | cd85b557414fe4cd44ea6608825e96612a5fe2b2 (diff) | |
parent | c45ed235abf1b0b6666417e3c394f18717976acd (diff) |
Merge branch 'next' of git://selinuxproject.org/~jmorris/linux-security
* 'next' of git://selinuxproject.org/~jmorris/linux-security: (95 commits)
TOMOYO: Fix incomplete read after seek.
Smack: allow to access /smack/access as normal user
TOMOYO: Fix unused kernel config option.
Smack: fix: invalid length set for the result of /smack/access
Smack: compilation fix
Smack: fix for /smack/access output, use string instead of byte
Smack: domain transition protections (v3)
Smack: Provide information for UDS getsockopt(SO_PEERCRED)
Smack: Clean up comments
Smack: Repair processing of fcntl
Smack: Rule list lookup performance
Smack: check permissions from user space (v2)
TOMOYO: Fix quota and garbage collector.
TOMOYO: Remove redundant tasklist_lock.
TOMOYO: Fix domain transition failure warning.
TOMOYO: Remove tomoyo_policy_memory_lock spinlock.
TOMOYO: Simplify garbage collector.
TOMOYO: Fix make namespacecheck warnings.
target: check hex2bin result
encrypted-keys: check hex2bin result
...
Diffstat (limited to 'security/security.c')
-rw-r--r-- | security/security.c | 76 |
1 files changed, 65 insertions, 11 deletions
diff --git a/security/security.c b/security/security.c index d9e153390926..0c6cc69c8f86 100644 --- a/security/security.c +++ b/security/security.c | |||
@@ -16,15 +16,16 @@ | |||
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/security.h> | 18 | #include <linux/security.h> |
19 | #include <linux/integrity.h> | ||
19 | #include <linux/ima.h> | 20 | #include <linux/ima.h> |
21 | #include <linux/evm.h> | ||
22 | |||
23 | #define MAX_LSM_EVM_XATTR 2 | ||
20 | 24 | ||
21 | /* Boot-time LSM user choice */ | 25 | /* Boot-time LSM user choice */ |
22 | static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] = | 26 | static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] = |
23 | CONFIG_DEFAULT_SECURITY; | 27 | CONFIG_DEFAULT_SECURITY; |
24 | 28 | ||
25 | /* things that live in capability.c */ | ||
26 | extern void __init security_fixup_ops(struct security_operations *ops); | ||
27 | |||
28 | static struct security_operations *security_ops; | 29 | static struct security_operations *security_ops; |
29 | static struct security_operations default_security_ops = { | 30 | static struct security_operations default_security_ops = { |
30 | .name = "default", | 31 | .name = "default", |
@@ -334,20 +335,57 @@ int security_inode_alloc(struct inode *inode) | |||
334 | 335 | ||
335 | void security_inode_free(struct inode *inode) | 336 | void security_inode_free(struct inode *inode) |
336 | { | 337 | { |
337 | ima_inode_free(inode); | 338 | integrity_inode_free(inode); |
338 | security_ops->inode_free_security(inode); | 339 | security_ops->inode_free_security(inode); |
339 | } | 340 | } |
340 | 341 | ||
341 | int security_inode_init_security(struct inode *inode, struct inode *dir, | 342 | int security_inode_init_security(struct inode *inode, struct inode *dir, |
342 | const struct qstr *qstr, char **name, | 343 | const struct qstr *qstr, |
343 | void **value, size_t *len) | 344 | const initxattrs initxattrs, void *fs_data) |
344 | { | 345 | { |
346 | struct xattr new_xattrs[MAX_LSM_EVM_XATTR + 1]; | ||
347 | struct xattr *lsm_xattr, *evm_xattr, *xattr; | ||
348 | int ret; | ||
349 | |||
345 | if (unlikely(IS_PRIVATE(inode))) | 350 | if (unlikely(IS_PRIVATE(inode))) |
346 | return -EOPNOTSUPP; | 351 | return 0; |
352 | |||
353 | memset(new_xattrs, 0, sizeof new_xattrs); | ||
354 | if (!initxattrs) | ||
355 | return security_ops->inode_init_security(inode, dir, qstr, | ||
356 | NULL, NULL, NULL); | ||
357 | lsm_xattr = new_xattrs; | ||
358 | ret = security_ops->inode_init_security(inode, dir, qstr, | ||
359 | &lsm_xattr->name, | ||
360 | &lsm_xattr->value, | ||
361 | &lsm_xattr->value_len); | ||
362 | if (ret) | ||
363 | goto out; | ||
364 | |||
365 | evm_xattr = lsm_xattr + 1; | ||
366 | ret = evm_inode_init_security(inode, lsm_xattr, evm_xattr); | ||
367 | if (ret) | ||
368 | goto out; | ||
369 | ret = initxattrs(inode, new_xattrs, fs_data); | ||
370 | out: | ||
371 | for (xattr = new_xattrs; xattr->name != NULL; xattr++) { | ||
372 | kfree(xattr->name); | ||
373 | kfree(xattr->value); | ||
374 | } | ||
375 | return (ret == -EOPNOTSUPP) ? 0 : ret; | ||
376 | } | ||
377 | EXPORT_SYMBOL(security_inode_init_security); | ||
378 | |||
379 | int security_old_inode_init_security(struct inode *inode, struct inode *dir, | ||
380 | const struct qstr *qstr, char **name, | ||
381 | void **value, size_t *len) | ||
382 | { | ||
383 | if (unlikely(IS_PRIVATE(inode))) | ||
384 | return 0; | ||
347 | return security_ops->inode_init_security(inode, dir, qstr, name, value, | 385 | return security_ops->inode_init_security(inode, dir, qstr, name, value, |
348 | len); | 386 | len); |
349 | } | 387 | } |
350 | EXPORT_SYMBOL(security_inode_init_security); | 388 | EXPORT_SYMBOL(security_old_inode_init_security); |
351 | 389 | ||
352 | #ifdef CONFIG_SECURITY_PATH | 390 | #ifdef CONFIG_SECURITY_PATH |
353 | int security_path_mknod(struct path *dir, struct dentry *dentry, int mode, | 391 | int security_path_mknod(struct path *dir, struct dentry *dentry, int mode, |
@@ -523,9 +561,14 @@ int security_inode_permission(struct inode *inode, int mask) | |||
523 | 561 | ||
524 | int security_inode_setattr(struct dentry *dentry, struct iattr *attr) | 562 | int security_inode_setattr(struct dentry *dentry, struct iattr *attr) |
525 | { | 563 | { |
564 | int ret; | ||
565 | |||
526 | if (unlikely(IS_PRIVATE(dentry->d_inode))) | 566 | if (unlikely(IS_PRIVATE(dentry->d_inode))) |
527 | return 0; | 567 | return 0; |
528 | return security_ops->inode_setattr(dentry, attr); | 568 | ret = security_ops->inode_setattr(dentry, attr); |
569 | if (ret) | ||
570 | return ret; | ||
571 | return evm_inode_setattr(dentry, attr); | ||
529 | } | 572 | } |
530 | EXPORT_SYMBOL_GPL(security_inode_setattr); | 573 | EXPORT_SYMBOL_GPL(security_inode_setattr); |
531 | 574 | ||
@@ -539,9 +582,14 @@ int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) | |||
539 | int security_inode_setxattr(struct dentry *dentry, const char *name, | 582 | int security_inode_setxattr(struct dentry *dentry, const char *name, |
540 | const void *value, size_t size, int flags) | 583 | const void *value, size_t size, int flags) |
541 | { | 584 | { |
585 | int ret; | ||
586 | |||
542 | if (unlikely(IS_PRIVATE(dentry->d_inode))) | 587 | if (unlikely(IS_PRIVATE(dentry->d_inode))) |
543 | return 0; | 588 | return 0; |
544 | return security_ops->inode_setxattr(dentry, name, value, size, flags); | 589 | ret = security_ops->inode_setxattr(dentry, name, value, size, flags); |
590 | if (ret) | ||
591 | return ret; | ||
592 | return evm_inode_setxattr(dentry, name, value, size); | ||
545 | } | 593 | } |
546 | 594 | ||
547 | void security_inode_post_setxattr(struct dentry *dentry, const char *name, | 595 | void security_inode_post_setxattr(struct dentry *dentry, const char *name, |
@@ -550,6 +598,7 @@ void security_inode_post_setxattr(struct dentry *dentry, const char *name, | |||
550 | if (unlikely(IS_PRIVATE(dentry->d_inode))) | 598 | if (unlikely(IS_PRIVATE(dentry->d_inode))) |
551 | return; | 599 | return; |
552 | security_ops->inode_post_setxattr(dentry, name, value, size, flags); | 600 | security_ops->inode_post_setxattr(dentry, name, value, size, flags); |
601 | evm_inode_post_setxattr(dentry, name, value, size); | ||
553 | } | 602 | } |
554 | 603 | ||
555 | int security_inode_getxattr(struct dentry *dentry, const char *name) | 604 | int security_inode_getxattr(struct dentry *dentry, const char *name) |
@@ -568,9 +617,14 @@ int security_inode_listxattr(struct dentry *dentry) | |||
568 | 617 | ||
569 | int security_inode_removexattr(struct dentry *dentry, const char *name) | 618 | int security_inode_removexattr(struct dentry *dentry, const char *name) |
570 | { | 619 | { |
620 | int ret; | ||
621 | |||
571 | if (unlikely(IS_PRIVATE(dentry->d_inode))) | 622 | if (unlikely(IS_PRIVATE(dentry->d_inode))) |
572 | return 0; | 623 | return 0; |
573 | return security_ops->inode_removexattr(dentry, name); | 624 | ret = security_ops->inode_removexattr(dentry, name); |
625 | if (ret) | ||
626 | return ret; | ||
627 | return evm_inode_removexattr(dentry, name); | ||
574 | } | 628 | } |
575 | 629 | ||
576 | int security_inode_need_killpriv(struct dentry *dentry) | 630 | int security_inode_need_killpriv(struct dentry *dentry) |