Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

evm: posix acls modify i_mode

The posix xattr acls are 'system' prefixed, which normally would not
affect security.evm. An interesting side affect of writing posix xattr
acls is their modifying of the i_mode, which is included in security.evm.

This patch updates security.evm when posix xattr acls are written.

Signed-off-by: Mimi Zohar <zohar@us.ibm.com>

+59 -5
+8
include/linux/evm.h
··· 33 33 extern int evm_inode_init_security(struct inode *inode, 34 34 const struct xattr *xattr_array, 35 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 44 #else 37 45 #ifdef CONFIG_INTEGRITY 38 46 static inline enum integrity_status evm_verifyxattr(struct dentry *dentry,
+5
include/linux/xattr.h
··· 52 52 #define XATTR_CAPS_SUFFIX "capability" 53 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 60 #ifdef __KERNEL__ 56 61 57 62 #include <linux/types.h>
+1
security/integrity/evm/Makefile
··· 4 4 obj-$(CONFIG_EVM) += evm.o 5 5 6 6 evm-y := evm_main.o evm_crypto.o evm_secfs.o 7 + evm-$(CONFIG_FS_POSIX_ACL) += evm_posix_acl.o
+19 -5
security/integrity/evm/evm_main.c
··· 177 177 /* 178 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 189 static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name, 183 190 const void *xattr_value, size_t xattr_value_len) ··· 194 187 if (strcmp(xattr_name, XATTR_NAME_EVM) == 0) { 195 188 if (!capable(CAP_SYS_ADMIN)) 196 189 return -EPERM; 197 - } else if (!evm_protected_xattr(xattr_name)) 198 - return 0; 199 - 190 + } else if (!evm_protected_xattr(xattr_name)) { 191 + if (!posix_xattr_acl(xattr_name)) 192 + return 0; 193 + evm_status = evm_verify_current_integrity(dentry); 194 + if ((evm_status == INTEGRITY_PASS) || 195 + (evm_status == INTEGRITY_NOLABEL)) 196 + return 0; 197 + return -EPERM; 198 + } 200 199 evm_status = evm_verify_current_integrity(dentry); 201 200 return evm_status == INTEGRITY_PASS ? 0 : -EPERM; 202 201 } ··· 253 240 void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name, 254 241 const void *xattr_value, size_t xattr_value_len) 255 242 { 256 - if (!evm_initialized || !evm_protected_xattr(xattr_name)) 243 + if (!evm_initialized || (!evm_protected_xattr(xattr_name) 244 + && !posix_xattr_acl(xattr_name))) 257 245 return; 258 246 259 247 evm_update_evmxattr(dentry, xattr_name, xattr_value, xattr_value_len);
+26
security/integrity/evm/evm_posix_acl.c
··· 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 + }