mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-12 13:55:32 +00:00
![Mimi Zohar](/assets/img/avatar_default.png)
EVM protects a file's security extended attributes(xattrs) against integrity attacks. This patchset provides the framework and an initial method. The initial method maintains an HMAC-sha1 value across the security extended attributes, storing the HMAC value as the extended attribute 'security.evm'. Other methods of validating the integrity of a file's metadata will be posted separately (eg. EVM-digital-signatures). While this patchset does authenticate the security xattrs, and cryptographically binds them to the inode, coming extensions will bind other directory and inode metadata for more complete protection. To help simplify the review and upstreaming process, each extension will be posted separately (eg. IMA-appraisal, IMA-appraisal-directory). For a general overview of the proposed Linux integrity subsystem, refer to Dave Safford's whitepaper: http://downloads.sf.net/project/linux-ima/linux-ima/Integrity_overview.pdf. EVM depends on the Kernel Key Retention System to provide it with a trusted/encrypted key for the HMAC-sha1 operation. The key is loaded onto the root's keyring using keyctl. Until EVM receives notification that the key has been successfully loaded onto the keyring (echo 1 > <securityfs>/evm), EVM can not create or validate the 'security.evm' xattr, but returns INTEGRITY_UNKNOWN. Loading the key and signaling EVM should be done as early as possible. Normally this is done in the initramfs, which has already been measured as part of the trusted boot. For more information on creating and loading existing trusted/encrypted keys, refer to Documentation/keys-trusted-encrypted.txt. A sample dracut patch, which loads the trusted/encrypted key and enables EVM, is available from http://linux-ima.sourceforge.net/#EVM. Based on the LSMs enabled, the set of EVM protected security xattrs is defined at compile. EVM adds the following three calls to the existing security hooks: evm_inode_setxattr(), evm_inode_post_setxattr(), and evm_inode_removexattr. To initialize and update the 'security.evm' extended attribute, EVM defines three calls: evm_inode_post_init(), evm_inode_post_setattr() and evm_inode_post_removexattr() hooks. To verify the integrity of a security xattr, EVM exports evm_verifyxattr(). Changelog v7: - Fixed URL in EVM ABI documentation Changelog v6: (based on Serge Hallyn's review) - fix URL in patch description - remove evm_hmac_size definition - use SHA1_DIGEST_SIZE (removed both MAX_DIGEST_SIZE and evm_hmac_size) - moved linux include before other includes - test for crypto_hash_setkey failure - fail earlier for invalid key - clear entire encrypted key, even on failure - check xattr name length before comparing xattr names Changelog: - locking based on i_mutex, remove evm_mutex - using trusted/encrypted keys for storing the EVM key used in the HMAC-sha1 operation. - replaced crypto hash with shash (Dmitry Kasatkin) - support for additional methods of verifying the security xattrs (Dmitry Kasatkin) - iint not allocated for all regular files, but only for those appraised - Use cap_sys_admin in lieu of cap_mac_admin - Use __vfs_setxattr_noperm(), without permission checks, from EVM Signed-off-by: Mimi Zohar <zohar@us.ibm.com> Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
96 lines
3.6 KiB
C
96 lines
3.6 KiB
C
/*
|
|
File: linux/xattr.h
|
|
|
|
Extended attributes handling.
|
|
|
|
Copyright (C) 2001 by Andreas Gruenbacher <a.gruenbacher@computer.org>
|
|
Copyright (c) 2001-2002 Silicon Graphics, Inc. All Rights Reserved.
|
|
Copyright (c) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com>
|
|
*/
|
|
#ifndef _LINUX_XATTR_H
|
|
#define _LINUX_XATTR_H
|
|
|
|
#define XATTR_CREATE 0x1 /* set value, fail if attr already exists */
|
|
#define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */
|
|
|
|
/* Namespaces */
|
|
#define XATTR_OS2_PREFIX "os2."
|
|
#define XATTR_OS2_PREFIX_LEN (sizeof (XATTR_OS2_PREFIX) - 1)
|
|
|
|
#define XATTR_SECURITY_PREFIX "security."
|
|
#define XATTR_SECURITY_PREFIX_LEN (sizeof (XATTR_SECURITY_PREFIX) - 1)
|
|
|
|
#define XATTR_SYSTEM_PREFIX "system."
|
|
#define XATTR_SYSTEM_PREFIX_LEN (sizeof (XATTR_SYSTEM_PREFIX) - 1)
|
|
|
|
#define XATTR_TRUSTED_PREFIX "trusted."
|
|
#define XATTR_TRUSTED_PREFIX_LEN (sizeof (XATTR_TRUSTED_PREFIX) - 1)
|
|
|
|
#define XATTR_USER_PREFIX "user."
|
|
#define XATTR_USER_PREFIX_LEN (sizeof (XATTR_USER_PREFIX) - 1)
|
|
|
|
/* Security namespace */
|
|
#define XATTR_EVM_SUFFIX "evm"
|
|
#define XATTR_NAME_EVM XATTR_SECURITY_PREFIX XATTR_EVM_SUFFIX
|
|
|
|
#define XATTR_SELINUX_SUFFIX "selinux"
|
|
#define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX
|
|
|
|
#define XATTR_SMACK_SUFFIX "SMACK64"
|
|
#define XATTR_SMACK_IPIN "SMACK64IPIN"
|
|
#define XATTR_SMACK_IPOUT "SMACK64IPOUT"
|
|
#define XATTR_SMACK_EXEC "SMACK64EXEC"
|
|
#define XATTR_SMACK_TRANSMUTE "SMACK64TRANSMUTE"
|
|
#define XATTR_SMACK_MMAP "SMACK64MMAP"
|
|
#define XATTR_NAME_SMACK XATTR_SECURITY_PREFIX XATTR_SMACK_SUFFIX
|
|
#define XATTR_NAME_SMACKIPIN XATTR_SECURITY_PREFIX XATTR_SMACK_IPIN
|
|
#define XATTR_NAME_SMACKIPOUT XATTR_SECURITY_PREFIX XATTR_SMACK_IPOUT
|
|
#define XATTR_NAME_SMACKEXEC XATTR_SECURITY_PREFIX XATTR_SMACK_EXEC
|
|
#define XATTR_NAME_SMACKTRANSMUTE XATTR_SECURITY_PREFIX XATTR_SMACK_TRANSMUTE
|
|
#define XATTR_NAME_SMACKMMAP XATTR_SECURITY_PREFIX XATTR_SMACK_MMAP
|
|
|
|
#define XATTR_CAPS_SUFFIX "capability"
|
|
#define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX
|
|
|
|
#ifdef __KERNEL__
|
|
|
|
#include <linux/types.h>
|
|
|
|
struct inode;
|
|
struct dentry;
|
|
|
|
struct xattr_handler {
|
|
const char *prefix;
|
|
int flags; /* fs private flags passed back to the handlers */
|
|
size_t (*list)(struct dentry *dentry, char *list, size_t list_size,
|
|
const char *name, size_t name_len, int handler_flags);
|
|
int (*get)(struct dentry *dentry, const char *name, void *buffer,
|
|
size_t size, int handler_flags);
|
|
int (*set)(struct dentry *dentry, const char *name, const void *buffer,
|
|
size_t size, int flags, int handler_flags);
|
|
};
|
|
|
|
struct xattr {
|
|
char *name;
|
|
void *value;
|
|
size_t value_len;
|
|
};
|
|
|
|
ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t);
|
|
ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t);
|
|
ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
|
|
int __vfs_setxattr_noperm(struct dentry *, const char *, const void *, size_t, int);
|
|
int vfs_setxattr(struct dentry *, const char *, const void *, size_t, int);
|
|
int vfs_removexattr(struct dentry *, const char *);
|
|
|
|
ssize_t generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size);
|
|
ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size);
|
|
int generic_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags);
|
|
int generic_removexattr(struct dentry *dentry, const char *name);
|
|
ssize_t vfs_getxattr_alloc(struct dentry *dentry, const char *name,
|
|
char **xattr_value, size_t size, gfp_t flags);
|
|
int vfs_xattr_cmp(struct dentry *dentry, const char *xattr_name,
|
|
const char *value, size_t size, gfp_t flags);
|
|
#endif /* __KERNEL__ */
|
|
|
|
#endif /* _LINUX_XATTR_H */
|