diff options
Diffstat (limited to 'security/security.c')
-rw-r--r-- | security/security.c | 77 |
1 files changed, 66 insertions, 11 deletions
diff --git a/security/security.c b/security/security.c index 0e4fccfef12c..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) |
@@ -1097,6 +1151,7 @@ void security_sk_clone(const struct sock *sk, struct sock *newsk) | |||
1097 | { | 1151 | { |
1098 | security_ops->sk_clone_security(sk, newsk); | 1152 | security_ops->sk_clone_security(sk, newsk); |
1099 | } | 1153 | } |
1154 | EXPORT_SYMBOL(security_sk_clone); | ||
1100 | 1155 | ||
1101 | void security_sk_classify_flow(struct sock *sk, struct flowi *fl) | 1156 | void security_sk_classify_flow(struct sock *sk, struct flowi *fl) |
1102 | { | 1157 | { |