@@ -250,6 +250,9 @@ verify_data_block(struct inode *inode, struct fsverity_info *vi,
data_pos, level - 1,
params->hash_alg->name, hsize, want_hash,
params->hash_alg->name, hsize, real_hash);
+ trace_fsverity_file_corrupt(inode, data_pos, params->block_size);
+ if (vops->file_corrupt)
+ vops->file_corrupt(inode, data_pos, params->block_size);
error:
for (; level > 0; level--)
fsverity_drop_merkle_tree_block(inode, &hblocks[level - 1].block);
@@ -228,6 +228,20 @@ struct fsverity_operations {
* be implemented.
*/
void (*drop_merkle_tree_block)(struct fsverity_blockbuf *block);
+
+ /**
+ * Notify the filesystem that file data is corrupt.
+ *
+ * @inode: the inode being validated
+ * @pos: the file position of the invalid data
+ * @len: the length of the invalid data
+ *
+ * This function is called when fs-verity detects that a portion of a
+ * file's data is inconsistent with the Merkle tree, or a Merkle tree
+ * block needed to validate the data is inconsistent with the level
+ * above it.
+ */
+ void (*file_corrupt)(struct inode *inode, loff_t pos, size_t len);
};
#ifdef CONFIG_FS_VERITY
@@ -137,6 +137,25 @@ TRACE_EVENT(fsverity_verify_merkle_block,
__entry->hidx)
);
+TRACE_EVENT(fsverity_file_corrupt,
+ TP_PROTO(const struct inode *inode, loff_t pos, size_t len),
+ TP_ARGS(inode, pos, len),
+ TP_STRUCT__entry(
+ __field(ino_t, ino)
+ __field(loff_t, pos)
+ __field(size_t, len)
+ ),
+ TP_fast_assign(
+ __entry->ino = inode->i_ino;
+ __entry->pos = pos;
+ __entry->len = len;
+ ),
+ TP_printk("ino %lu pos %llu len %zu",
+ (unsigned long) __entry->ino,
+ __entry->pos,
+ __entry->len)
+);
+
#endif /* _TRACE_FSVERITY_H */
/* This part must be outside protection */