aboutsummaryrefslogtreecommitdiffstats
path: root/security/security.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-10-25 03:45:31 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-10-25 03:45:31 -0400
commit36b8d186e6cc8e32cb5227f5645a58e1bc0af190 (patch)
tree1000ad26e189e6ff2c53fb7eeff605f59c7ad94e /security/security.c
parentcd85b557414fe4cd44ea6608825e96612a5fe2b2 (diff)
parentc45ed235abf1b0b6666417e3c394f18717976acd (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.c76
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 */
22static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] = 26static __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 */
26extern void __init security_fixup_ops(struct security_operations *ops);
27
28static struct security_operations *security_ops; 29static struct security_operations *security_ops;
29static struct security_operations default_security_ops = { 30static 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
335void security_inode_free(struct inode *inode) 336void 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
341int security_inode_init_security(struct inode *inode, struct inode *dir, 342int 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);
370out:
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}
377EXPORT_SYMBOL(security_inode_init_security);
378
379int 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}
350EXPORT_SYMBOL(security_inode_init_security); 388EXPORT_SYMBOL(security_old_inode_init_security);
351 389
352#ifdef CONFIG_SECURITY_PATH 390#ifdef CONFIG_SECURITY_PATH
353int security_path_mknod(struct path *dir, struct dentry *dentry, int mode, 391int 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
524int security_inode_setattr(struct dentry *dentry, struct iattr *attr) 562int 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}
530EXPORT_SYMBOL_GPL(security_inode_setattr); 573EXPORT_SYMBOL_GPL(security_inode_setattr);
531 574
@@ -539,9 +582,14 @@ int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
539int security_inode_setxattr(struct dentry *dentry, const char *name, 582int 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
547void security_inode_post_setxattr(struct dentry *dentry, const char *name, 595void 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
555int security_inode_getxattr(struct dentry *dentry, const char *name) 604int security_inode_getxattr(struct dentry *dentry, const char *name)
@@ -568,9 +617,14 @@ int security_inode_listxattr(struct dentry *dentry)
568 617
569int security_inode_removexattr(struct dentry *dentry, const char *name) 618int 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
576int security_inode_need_killpriv(struct dentry *dentry) 630int security_inode_need_killpriv(struct dentry *dentry)