ima: Define new template fields xattrnames, xattrlengths and xattrvalues

This patch defines the new template fields xattrnames, xattrlengths and
xattrvalues, which contain respectively a list of xattr names (strings,
separated by |), lengths (u32, hex) and values (hex). If an xattr is not
present, the name and length are not displayed in the measurement list.

Reported-by: kernel test robot <lkp@intel.com> (Missing prototype def)
Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
This commit is contained in:
Roberto Sassu
2021-06-01 10:23:38 +02:00
committed by Mimi Zohar
parent 8c7a703ec9
commit 8314b6732a
6 changed files with 162 additions and 0 deletions

View File

@@ -317,6 +317,75 @@ int evm_protected_xattr_if_enabled(const char *req_xattr_name)
return evm_protected_xattr_common(req_xattr_name, true);
}
/**
* evm_read_protected_xattrs - read EVM protected xattr names, lengths, values
* @dentry: dentry of the read xattrs
* @inode: inode of the read xattrs
* @buffer: buffer xattr names, lengths or values are copied to
* @buffer_size: size of buffer
* @type: n: names, l: lengths, v: values
* @canonical_fmt: data format (true: little endian, false: native format)
*
* Read protected xattr names (separated by |), lengths (u32) or values for a
* given dentry and return the total size of copied data. If buffer is NULL,
* just return the total size.
*
* Returns the total size on success, a negative value on error.
*/
int evm_read_protected_xattrs(struct dentry *dentry, u8 *buffer,
int buffer_size, char type, bool canonical_fmt)
{
struct xattr_list *xattr;
int rc, size, total_size = 0;
list_for_each_entry_lockless(xattr, &evm_config_xattrnames, list) {
rc = __vfs_getxattr(dentry, d_backing_inode(dentry),
xattr->name, NULL, 0);
if (rc < 0 && rc == -ENODATA)
continue;
else if (rc < 0)
return rc;
switch (type) {
case 'n':
size = strlen(xattr->name) + 1;
if (buffer) {
if (total_size)
*(buffer + total_size - 1) = '|';
memcpy(buffer + total_size, xattr->name, size);
}
break;
case 'l':
size = sizeof(u32);
if (buffer) {
if (canonical_fmt)
rc = cpu_to_le32(rc);
*(u32 *)(buffer + total_size) = rc;
}
break;
case 'v':
size = rc;
if (buffer) {
rc = __vfs_getxattr(dentry,
d_backing_inode(dentry), xattr->name,
buffer + total_size,
buffer_size - total_size);
if (rc < 0)
return rc;
}
break;
default:
return -EINVAL;
}
total_size += size;
}
return total_size;
}
/**
* evm_verifyxattr - verify the integrity of the requested xattr
* @dentry: object of the verify xattr