diff options
-rw-r--r-- | include/linux/evm.h | 8 | ||||
-rw-r--r-- | include/linux/xattr.h | 5 | ||||
-rw-r--r-- | security/integrity/evm/Makefile | 1 | ||||
-rw-r--r-- | security/integrity/evm/evm_main.c | 24 | ||||
-rw-r--r-- | security/integrity/evm/evm_posix_acl.c | 26 |
5 files changed, 59 insertions, 5 deletions
diff --git a/include/linux/evm.h b/include/linux/evm.h index ea603c9e775d..9fc13a760928 100644 --- a/include/linux/evm.h +++ b/include/linux/evm.h | |||
@@ -33,6 +33,14 @@ extern void evm_inode_post_removexattr(struct dentry *dentry, | |||
33 | extern int evm_inode_init_security(struct inode *inode, | 33 | extern int evm_inode_init_security(struct inode *inode, |
34 | const struct xattr *xattr_array, | 34 | const struct xattr *xattr_array, |
35 | struct xattr *evm); | 35 | struct xattr *evm); |
36 | #ifdef CONFIG_FS_POSIX_ACL | ||
37 | extern int posix_xattr_acl(const char *xattrname); | ||
38 | #else | ||
39 | static inline int posix_xattr_acl(const char *xattrname) | ||
40 | { | ||
41 | return 0; | ||
42 | } | ||
43 | #endif | ||
36 | #else | 44 | #else |
37 | #ifdef CONFIG_INTEGRITY | 45 | #ifdef CONFIG_INTEGRITY |
38 | static inline enum integrity_status evm_verifyxattr(struct dentry *dentry, | 46 | static inline enum integrity_status evm_verifyxattr(struct dentry *dentry, |
diff --git a/include/linux/xattr.h b/include/linux/xattr.h index b20cb965c322..e5d122031542 100644 --- a/include/linux/xattr.h +++ b/include/linux/xattr.h | |||
@@ -52,6 +52,11 @@ | |||
52 | #define XATTR_CAPS_SUFFIX "capability" | 52 | #define XATTR_CAPS_SUFFIX "capability" |
53 | #define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX | 53 | #define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX |
54 | 54 | ||
55 | #define XATTR_POSIX_ACL_ACCESS "posix_acl_access" | ||
56 | #define XATTR_NAME_POSIX_ACL_ACCESS XATTR_SYSTEM_PREFIX XATTR_POSIX_ACL_ACCESS | ||
57 | #define XATTR_POSIX_ACL_DEFAULT "posix_acl_default" | ||
58 | #define XATTR_NAME_POSIX_ACL_DEFAULT XATTR_SYSTEM_PREFIX XATTR_POSIX_ACL_DEFAULT | ||
59 | |||
55 | #ifdef __KERNEL__ | 60 | #ifdef __KERNEL__ |
56 | 61 | ||
57 | #include <linux/types.h> | 62 | #include <linux/types.h> |
diff --git a/security/integrity/evm/Makefile b/security/integrity/evm/Makefile index 0787d262b9e3..7393c415a066 100644 --- a/security/integrity/evm/Makefile +++ b/security/integrity/evm/Makefile | |||
@@ -4,3 +4,4 @@ | |||
4 | obj-$(CONFIG_EVM) += evm.o | 4 | obj-$(CONFIG_EVM) += evm.o |
5 | 5 | ||
6 | evm-y := evm_main.o evm_crypto.o evm_secfs.o | 6 | evm-y := evm_main.o evm_crypto.o evm_secfs.o |
7 | evm-$(CONFIG_FS_POSIX_ACL) += evm_posix_acl.o | ||
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c index 7d4247535f9e..73c008d047c7 100644 --- a/security/integrity/evm/evm_main.c +++ b/security/integrity/evm/evm_main.c | |||
@@ -177,7 +177,14 @@ static enum integrity_status evm_verify_current_integrity(struct dentry *dentry) | |||
177 | /* | 177 | /* |
178 | * evm_protect_xattr - protect the EVM extended attribute | 178 | * evm_protect_xattr - protect the EVM extended attribute |
179 | * | 179 | * |
180 | * Prevent security.evm from being modified or removed. | 180 | * Prevent security.evm from being modified or removed without the |
181 | * necessary permissions or when the existing value is invalid. | ||
182 | * | ||
183 | * The posix xattr acls are 'system' prefixed, which normally would not | ||
184 | * affect security.evm. An interesting side affect of writing posix xattr | ||
185 | * acls is their modifying of the i_mode, which is included in security.evm. | ||
186 | * For posix xattr acls only, permit security.evm, even if it currently | ||
187 | * doesn't exist, to be updated. | ||
181 | */ | 188 | */ |
182 | static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name, | 189 | static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name, |
183 | const void *xattr_value, size_t xattr_value_len) | 190 | const void *xattr_value, size_t xattr_value_len) |
@@ -187,9 +194,15 @@ static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name, | |||
187 | if (strcmp(xattr_name, XATTR_NAME_EVM) == 0) { | 194 | if (strcmp(xattr_name, XATTR_NAME_EVM) == 0) { |
188 | if (!capable(CAP_SYS_ADMIN)) | 195 | if (!capable(CAP_SYS_ADMIN)) |
189 | return -EPERM; | 196 | return -EPERM; |
190 | } else if (!evm_protected_xattr(xattr_name)) | 197 | } else if (!evm_protected_xattr(xattr_name)) { |
191 | return 0; | 198 | if (!posix_xattr_acl(xattr_name)) |
192 | 199 | return 0; | |
200 | evm_status = evm_verify_current_integrity(dentry); | ||
201 | if ((evm_status == INTEGRITY_PASS) || | ||
202 | (evm_status == INTEGRITY_NOLABEL)) | ||
203 | return 0; | ||
204 | return -EPERM; | ||
205 | } | ||
193 | evm_status = evm_verify_current_integrity(dentry); | 206 | evm_status = evm_verify_current_integrity(dentry); |
194 | return evm_status == INTEGRITY_PASS ? 0 : -EPERM; | 207 | return evm_status == INTEGRITY_PASS ? 0 : -EPERM; |
195 | } | 208 | } |
@@ -240,7 +253,8 @@ int evm_inode_removexattr(struct dentry *dentry, const char *xattr_name) | |||
240 | void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name, | 253 | void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name, |
241 | const void *xattr_value, size_t xattr_value_len) | 254 | const void *xattr_value, size_t xattr_value_len) |
242 | { | 255 | { |
243 | if (!evm_initialized || !evm_protected_xattr(xattr_name)) | 256 | if (!evm_initialized || (!evm_protected_xattr(xattr_name) |
257 | && !posix_xattr_acl(xattr_name))) | ||
244 | return; | 258 | return; |
245 | 259 | ||
246 | evm_update_evmxattr(dentry, xattr_name, xattr_value, xattr_value_len); | 260 | evm_update_evmxattr(dentry, xattr_name, xattr_value, xattr_value_len); |
diff --git a/security/integrity/evm/evm_posix_acl.c b/security/integrity/evm/evm_posix_acl.c new file mode 100644 index 000000000000..b1753e98bf9a --- /dev/null +++ b/security/integrity/evm/evm_posix_acl.c | |||
@@ -0,0 +1,26 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011 IBM Corporation | ||
3 | * | ||
4 | * Author: | ||
5 | * Mimi Zohar <zohar@us.ibm.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation, version 2 of the License. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/xattr.h> | ||
14 | |||
15 | int posix_xattr_acl(char *xattr) | ||
16 | { | ||
17 | int xattr_len = strlen(xattr); | ||
18 | |||
19 | if ((strlen(XATTR_NAME_POSIX_ACL_ACCESS) == xattr_len) | ||
20 | && (strncmp(XATTR_NAME_POSIX_ACL_ACCESS, xattr, xattr_len) == 0)) | ||
21 | return 1; | ||
22 | if ((strlen(XATTR_NAME_POSIX_ACL_DEFAULT) == xattr_len) | ||
23 | && (strncmp(XATTR_NAME_POSIX_ACL_DEFAULT, xattr, xattr_len) == 0)) | ||
24 | return 1; | ||
25 | return 0; | ||
26 | } | ||