From 0e6b7eae1fded85f94a357d6132f07d64c614cfa Mon Sep 17 00:00:00 2001 From: Andrey Albershteyn Date: Mon, 26 Jan 2026 12:56:57 +0100 Subject: fs: add FS_XFLAG_VERITY for fs-verity files fs-verity introduced inode flag for inodes with enabled fs-verity on them. This patch adds FS_XFLAG_VERITY file attribute which can be retrieved with FS_IOC_FSGETXATTR ioctl() and file_getattr() syscall. This flag is read-only and can not be set with corresponding set ioctl() and file_setattr(). The FS_IOC_SETFLAGS requires file to be opened for writing which is not allowed for verity files. The FS_IOC_FSSETXATTR and file_setattr() clears this flag from the user input. As this is now common flag for both flag interfaces (flags/xflags) add it to overlapping flags list to exclude it from overwrite. Signed-off-by: Andrey Albershteyn Link: https://patch.msgid.link/20260126115658.27656-2-aalbersh@kernel.org Reviewed-by: Darrick J. Wong Signed-off-by: Christian Brauner --- include/linux/fileattr.h | 6 +++--- include/uapi/linux/fs.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/linux/fileattr.h b/include/linux/fileattr.h index f89dcfad3f8f..3780904a63a6 100644 --- a/include/linux/fileattr.h +++ b/include/linux/fileattr.h @@ -7,16 +7,16 @@ #define FS_COMMON_FL \ (FS_SYNC_FL | FS_IMMUTABLE_FL | FS_APPEND_FL | \ FS_NODUMP_FL | FS_NOATIME_FL | FS_DAX_FL | \ - FS_PROJINHERIT_FL) + FS_PROJINHERIT_FL | FS_VERITY_FL) #define FS_XFLAG_COMMON \ (FS_XFLAG_SYNC | FS_XFLAG_IMMUTABLE | FS_XFLAG_APPEND | \ FS_XFLAG_NODUMP | FS_XFLAG_NOATIME | FS_XFLAG_DAX | \ - FS_XFLAG_PROJINHERIT) + FS_XFLAG_PROJINHERIT | FS_XFLAG_VERITY) /* Read-only inode flags */ #define FS_XFLAG_RDONLY_MASK \ - (FS_XFLAG_PREALLOC | FS_XFLAG_HASATTR) + (FS_XFLAG_PREALLOC | FS_XFLAG_HASATTR | FS_XFLAG_VERITY) /* Flags to indicate valid value of fsx_ fields */ #define FS_XFLAG_VALUES_MASK \ diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h index 66ca526cf786..70b2b661f42c 100644 --- a/include/uapi/linux/fs.h +++ b/include/uapi/linux/fs.h @@ -253,6 +253,7 @@ struct file_attr { #define FS_XFLAG_FILESTREAM 0x00004000 /* use filestream allocator */ #define FS_XFLAG_DAX 0x00008000 /* use DAX for IO */ #define FS_XFLAG_COWEXTSIZE 0x00010000 /* CoW extent size allocator hint */ +#define FS_XFLAG_VERITY 0x00020000 /* fs-verity enabled */ #define FS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */ /* the read-only stuff doesn't really belong here, but any other place is -- cgit v1.2.3 From fa19d42cc7915226db416999866171a456dac657 Mon Sep 17 00:00:00 2001 From: Andrey Albershteyn Date: Mon, 26 Jan 2026 12:56:58 +0100 Subject: fsverity: add tracepoints fs-verity previously had debug printk but it was removed. This patch adds trace points to similar places, as a better alternative. Signed-off-by: Andrey Albershteyn Reviewed-by: Darrick J. Wong [djwong: fix formatting] Signed-off-by: Darrick J. Wong Link: https://patch.msgid.link/20260126115658.27656-3-aalbersh@kernel.org Signed-off-by: Christian Brauner --- include/trace/events/fsverity.h | 146 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 include/trace/events/fsverity.h (limited to 'include') diff --git a/include/trace/events/fsverity.h b/include/trace/events/fsverity.h new file mode 100644 index 000000000000..a8c52f21cbd5 --- /dev/null +++ b/include/trace/events/fsverity.h @@ -0,0 +1,146 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM fsverity + +#if !defined(_TRACE_FSVERITY_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_FSVERITY_H + +#include + +struct fsverity_descriptor; +struct merkle_tree_params; +struct fsverity_info; + +TRACE_EVENT(fsverity_enable, + TP_PROTO(const struct inode *inode, + const struct merkle_tree_params *params), + TP_ARGS(inode, params), + TP_STRUCT__entry( + __field(ino_t, ino) + __field(u64, data_size) + __field(u64, tree_size) + __field(unsigned int, merkle_block) + __field(unsigned int, num_levels) + ), + TP_fast_assign( + __entry->ino = inode->i_ino; + __entry->data_size = i_size_read(inode); + __entry->tree_size = params->tree_size; + __entry->merkle_block = params->block_size; + __entry->num_levels = params->num_levels; + ), + TP_printk("ino %lu data_size %llu tree_size %llu merkle_block %u levels %u", + (unsigned long) __entry->ino, + __entry->data_size, + __entry->tree_size, + __entry->merkle_block, + __entry->num_levels) +); + +TRACE_EVENT(fsverity_tree_done, + TP_PROTO(const struct inode *inode, const struct fsverity_info *vi, + const struct merkle_tree_params *params), + TP_ARGS(inode, vi, params), + TP_STRUCT__entry( + __field(ino_t, ino) + __field(u64, data_size) + __field(u64, tree_size) + __field(unsigned int, merkle_block) + __field(unsigned int, levels) + __dynamic_array(u8, root_hash, params->digest_size) + __dynamic_array(u8, file_digest, params->digest_size) + ), + TP_fast_assign( + __entry->ino = inode->i_ino; + __entry->data_size = i_size_read(inode); + __entry->tree_size = params->tree_size; + __entry->merkle_block = params->block_size; + __entry->levels = params->num_levels; + memcpy(__get_dynamic_array(root_hash), vi->root_hash, __get_dynamic_array_len(root_hash)); + memcpy(__get_dynamic_array(file_digest), vi->file_digest, __get_dynamic_array_len(file_digest)); + ), + TP_printk("ino %lu data_size %llu tree_size %lld merkle_block %u levels %u root_hash %s digest %s", + (unsigned long) __entry->ino, + __entry->data_size, + __entry->tree_size, + __entry->merkle_block, + __entry->levels, + __print_hex_str(__get_dynamic_array(root_hash), __get_dynamic_array_len(root_hash)), + __print_hex_str(__get_dynamic_array(file_digest), __get_dynamic_array_len(file_digest))) +); + +TRACE_EVENT(fsverity_verify_data_block, + TP_PROTO(const struct inode *inode, + const struct merkle_tree_params *params, + u64 data_pos), + TP_ARGS(inode, params, data_pos), + TP_STRUCT__entry( + __field(ino_t, ino) + __field(u64, data_pos) + __field(unsigned int, merkle_block) + ), + TP_fast_assign( + __entry->ino = inode->i_ino; + __entry->data_pos = data_pos; + __entry->merkle_block = params->block_size; + ), + TP_printk("ino %lu data_pos %llu merkle_block %u", + (unsigned long) __entry->ino, + __entry->data_pos, + __entry->merkle_block) +); + +TRACE_EVENT(fsverity_merkle_hit, + TP_PROTO(const struct inode *inode, u64 data_pos, + unsigned long hblock_idx, unsigned int level, + unsigned int hidx), + TP_ARGS(inode, data_pos, hblock_idx, level, hidx), + TP_STRUCT__entry( + __field(ino_t, ino) + __field(u64, data_pos) + __field(unsigned long, hblock_idx) + __field(unsigned int, level) + __field(unsigned int, hidx) + ), + TP_fast_assign( + __entry->ino = inode->i_ino; + __entry->data_pos = data_pos; + __entry->hblock_idx = hblock_idx; + __entry->level = level; + __entry->hidx = hidx; + ), + TP_printk("ino %lu data_pos %llu hblock_idx %lu level %u hidx %u", + (unsigned long) __entry->ino, + __entry->data_pos, + __entry->hblock_idx, + __entry->level, + __entry->hidx) +); + +TRACE_EVENT(fsverity_verify_merkle_block, + TP_PROTO(const struct inode *inode, unsigned long hblock_idx, + unsigned int level, unsigned int hidx), + TP_ARGS(inode, hblock_idx, level, hidx), + TP_STRUCT__entry( + __field(ino_t, ino) + __field(unsigned long, hblock_idx) + __field(unsigned int, level) + __field(unsigned int, hidx) + ), + TP_fast_assign( + __entry->ino = inode->i_ino; + __entry->hblock_idx = hblock_idx; + __entry->level = level; + __entry->hidx = hidx; + ), + TP_printk("ino %lu hblock_idx %lu level %u hidx %u", + (unsigned long) __entry->ino, + __entry->hblock_idx, + __entry->level, + __entry->hidx) +); + +#endif /* _TRACE_FSVERITY_H */ + +/* This part must be outside protection */ +#include -- cgit v1.2.3