@@ -255,6 +255,15 @@ verify_data_block(struct inode *inode, struct fsverity_info *vi,
return false;
}
+static void fsverity_fail_validation(struct inode *inode, loff_t pos,
+ size_t len)
+{
+ const struct fsverity_operations *vops = inode->i_sb->s_vop;
+
+ if (vops->fail_validation)
+ vops->fail_validation(inode, pos, len);
+}
+
static bool
verify_data_blocks(struct folio *data_folio, size_t len, size_t offset,
unsigned long max_ra_bytes)
@@ -277,8 +286,11 @@ verify_data_blocks(struct folio *data_folio, size_t len, size_t offset,
valid = verify_data_block(inode, vi, data, pos + offset,
max_ra_bytes);
kunmap_local(data);
- if (!valid)
+ if (!valid) {
+ fsverity_fail_validation(inode, pos + offset,
+ block_size);
return false;
+ }
offset += block_size;
len -= block_size;
} while (len);
@@ -236,6 +236,17 @@ struct fsverity_operations {
* be implemented.
*/
void (*drop_merkle_tree_block)(struct fsverity_blockbuf *block);
+
+ /**
+ * Notify the filesystem that file data validation failed
+ *
+ * @inode: the inode being validated
+ * @pos: the file position of the invalid data
+ * @len: the length of the invalid data
+ *
+ * This is called when fs-verity cannot validate the file contents.
+ */
+ void (*fail_validation)(struct inode *inode, loff_t pos, size_t len);
};
#ifdef CONFIG_FS_VERITY