/** * evm_set_key() - set EVM HMAC key from the kernel * @key: pointer to a buffer with the key data * @keylen: length of the key data * * This function allows setting the EVM HMAC key from the kernel * without using the "encrypted" key subsystem keys. It can be used * by the crypto HW kernel module which has its own way of managing * keys. * * key length should be between 32 and 128 bytes long
*/ int evm_set_key(void *key, size_t keylen)
{ int rc;
/* Protect against 'cutting & pasting' security.evm xattr, include inode * specific info. * * (Additional directory/file metadata needs to be added for more complete * protection.)
*/ staticvoid hmac_add_misc(struct shash_desc *desc, struct inode *inode, char type, char *digest)
{ struct h_misc { unsignedlong ino;
__u32 generation;
uid_t uid;
gid_t gid;
umode_t mode;
} hmac_misc;
memset(&hmac_misc, 0, sizeof(hmac_misc)); /* Don't include the inode or generation number in portable * signatures
*/ if (type != EVM_XATTR_PORTABLE_DIGSIG) {
hmac_misc.ino = inode->i_ino;
hmac_misc.generation = inode->i_generation;
} /* The hmac uid and gid must be encoded in the initial user * namespace (not the filesystems user namespace) as encoding * them in the filesystems user namespace allows an attack * where first they are written in an unprivileged fuse mount * of a filesystem and then the system is tricked to mount the * filesystem for real on next boot and trust it because * everything is signed.
*/
hmac_misc.uid = from_kuid(&init_user_ns, inode->i_uid);
hmac_misc.gid = from_kgid(&init_user_ns, inode->i_gid);
hmac_misc.mode = inode->i_mode;
crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof(hmac_misc)); if ((evm_hmac_attrs & EVM_ATTR_FSUUID) &&
type != EVM_XATTR_PORTABLE_DIGSIG)
crypto_shash_update(desc, (u8 *)&inode->i_sb->s_uuid, UUID_SIZE);
crypto_shash_final(desc, digest);
if (inode != d_backing_inode(dentry) && iint) { if (IS_I_VERSION(inode))
i_version = inode_query_iversion(inode);
integrity_inode_attrs_store(&iint->metadata_inode, i_version,
inode);
}
/* Portable EVM signatures must include an IMA hash */ if (type == EVM_XATTR_PORTABLE_DIGSIG && !ima_present)
error = -EPERM;
out:
kfree(xattr_value);
kfree(desc); return error;
}
/* Do this the hard way */
rc = vfs_getxattr_alloc(&nop_mnt_idmap, dentry, XATTR_NAME_EVM,
(char **)&xattr_data, 0, GFP_NOFS); if (rc <= 0) { if (rc == -ENODATA)
rc = 0; goto out;
} if (xattr_data->type == EVM_XATTR_PORTABLE_DIGSIG)
rc = 1; else
rc = 0;
out:
kfree(xattr_data); return rc;
}
/* * Calculate the hmac and update security.evm xattr * * Expects to be called with i_mutex locked.
*/ int evm_update_evmxattr(struct dentry *dentry, constchar *xattr_name, constchar *xattr_value, size_t xattr_value_len)
{ struct inode *inode = d_backing_inode(dentry); struct evm_iint_cache *iint = evm_iint_inode(inode); struct evm_digest data; int rc = 0;
/* * Don't permit any transformation of the EVM xattr if the signature * is of an immutable type
*/
rc = evm_is_immutable(dentry, inode); if (rc < 0) return rc; if (rc) return -EPERM;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.