/* * Iterate through each Merkle tree page in the requested range and copy * the requested portion to userspace. Note that the Merkle tree block * size isn't important here, as we are returning a byte stream; i.e., * we can just work with pages even if the tree block size != PAGE_SIZE.
*/ for (index = offset >> PAGE_SHIFT; index <= last_index; index++) { unsignedlong num_ra_pages =
min_t(unsignedlong, last_index - index + 1,
inode->i_sb->s_bdi->io_pages); unsignedint bytes_to_copy = min_t(u64, end_offset - offset,
PAGE_SIZE - offs_in_page); struct page *page; constvoid *virt;
/* Copy the requested portion of the buffer to userspace. */ staticint fsverity_read_buffer(void __user *dst, u64 offset, int length, constvoid *src, size_t src_length)
{ if (offset >= src_length) return 0;
src += offset;
src_length -= offset;
length = min_t(size_t, length, src_length);
if (copy_to_user(dst, src, length)) return -EFAULT;
return length;
}
staticint fsverity_read_descriptor(struct inode *inode, void __user *buf, u64 offset, int length)
{ struct fsverity_descriptor *desc;
size_t desc_size; int res;
res = fsverity_get_descriptor(inode, &desc); if (res) return res;
/* don't include the builtin signature */
desc_size = offsetof(struct fsverity_descriptor, signature);
desc->sig_size = 0;
res = fsverity_read_buffer(buf, offset, length, desc, desc_size);
kfree(desc); return res;
}
staticint fsverity_read_signature(struct inode *inode, void __user *buf, u64 offset, int length)
{ struct fsverity_descriptor *desc; int res;
res = fsverity_get_descriptor(inode, &desc); if (res) return res;
if (desc->sig_size == 0) {
res = -ENODATA; goto out;
}
/* * Include only the builtin signature. fsverity_get_descriptor() * already verified that sig_size is in-bounds.
*/
res = fsverity_read_buffer(buf, offset, length, desc->signature,
le32_to_cpu(desc->sig_size));
out:
kfree(desc); return res;
}
/** * fsverity_ioctl_read_metadata() - read verity metadata from a file * @filp: file to read the metadata from * @uarg: user pointer to fsverity_read_metadata_arg * * Return: length read on success, 0 on EOF, -errno on failure
*/ int fsverity_ioctl_read_metadata(struct file *filp, constvoid __user *uarg)
{ struct inode *inode = file_inode(filp); conststruct fsverity_info *vi; struct fsverity_read_metadata_arg arg; int length; void __user *buf;
vi = fsverity_get_info(inode); if (!vi) return -ENODATA; /* not a verity file */ /* * Note that we don't have to explicitly check that the file is open for * reading, since verity files can only be opened for reading.
*/
if (copy_from_user(&arg, uarg, sizeof(arg))) return -EFAULT;
if (arg.__reserved) return -EINVAL;
/* offset + length must not overflow. */ if (arg.offset + arg.length < arg.offset) return -EINVAL;
/* Ensure that the return value will fit in INT_MAX. */
length = min_t(u64, arg.length, INT_MAX);
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.