Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ocfs2: annotate flexible array members with __counted_by_le()

Annotate flexible array members of 'struct ocfs2_extent_list',
'struct ocfs2_chain_list', 'struct ocfs2_truncate_log',
'struct ocfs2_dx_entry_list', 'ocfs2_refcount_list' and
'struct ocfs2_xattr_header' with '__counted_by_le()'
attribute to improve array bounds checking when
CONFIG_UBSAN_BOUNDS is enabled.

[dmantipov@yandex.ru: fix __counted_by_le() usage in ocfs2_expand_inline_dx_root()]
Link: https://lkml.kernel.org/r/20251014070324.130313-1-dmantipov@yandex.ru
Link: https://lkml.kernel.org/r/20251007123526.213150-1-dmantipov@yandex.ru
Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Reviewed-by: Heming Zhao <heming.zhao@suse.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Jun Piao <piaojun@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Dmitry Antipov and committed by
Andrew Morton
2f26f58d cd4eaccc

+21 -10
+7 -2
fs/ocfs2/dir.c
··· 4104 4104 } 4105 4105 4106 4106 dx_root->dr_flags &= ~OCFS2_DX_FLAG_INLINE; 4107 - memset(&dx_root->dr_list, 0, osb->sb->s_blocksize - 4108 - offsetof(struct ocfs2_dx_root_block, dr_list)); 4107 + 4108 + dx_root->dr_list.l_tree_depth = 0; 4109 4109 dx_root->dr_list.l_count = 4110 4110 cpu_to_le16(ocfs2_extent_recs_per_dx_root(osb->sb)); 4111 + dx_root->dr_list.l_next_free_rec = 0; 4112 + memset(&dx_root->dr_list.l_recs, 0, 4113 + osb->sb->s_blocksize - 4114 + (offsetof(struct ocfs2_dx_root_block, dr_list) + 4115 + offsetof(struct ocfs2_extent_list, l_recs))); 4111 4116 4112 4117 /* This should never fail considering we start with an empty 4113 4118 * dx_root. */
+14 -8
fs/ocfs2/ocfs2_fs.h
··· 468 468 __le16 l_reserved1; 469 469 __le64 l_reserved2; /* Pad to 470 470 sizeof(ocfs2_extent_rec) */ 471 - /*10*/ struct ocfs2_extent_rec l_recs[]; /* Extent records */ 471 + /* Extent records */ 472 + /*10*/ struct ocfs2_extent_rec l_recs[] __counted_by_le(l_count); 472 473 }; 473 474 474 475 /* ··· 483 482 __le16 cl_count; /* Total chains in this list */ 484 483 __le16 cl_next_free_rec; /* Next unused chain slot */ 485 484 __le64 cl_reserved1; 486 - /*10*/ struct ocfs2_chain_rec cl_recs[]; /* Chain records */ 485 + /* Chain records */ 486 + /*10*/ struct ocfs2_chain_rec cl_recs[] __counted_by_le(cl_count); 487 487 }; 488 488 489 489 /* ··· 496 494 /*00*/ __le16 tl_count; /* Total records in this log */ 497 495 __le16 tl_used; /* Number of records in use */ 498 496 __le32 tl_reserved1; 499 - /*08*/ struct ocfs2_truncate_rec tl_recs[]; /* Truncate records */ 497 + /* Truncate records */ 498 + /*08*/ struct ocfs2_truncate_rec tl_recs[] __counted_by_le(tl_count); 500 499 }; 501 500 502 501 /* ··· 799 796 * possible in de_entries */ 800 797 __le16 de_num_used; /* Current number of 801 798 * de_entries entries */ 802 - struct ocfs2_dx_entry de_entries[]; /* Indexed dir entries 803 - * in a packed array of 804 - * length de_num_used */ 799 + /* Indexed dir entries in a packed 800 + * array of length de_num_used. 801 + */ 802 + struct ocfs2_dx_entry de_entries[] __counted_by_le(de_count); 805 803 }; 806 804 807 805 #define OCFS2_DX_FLAG_INLINE 0x01 ··· 938 934 __le16 rl_used; /* Current number of used records */ 939 935 __le32 rl_reserved2; 940 936 __le64 rl_reserved1; /* Pad to sizeof(ocfs2_refcount_record) */ 941 - /*10*/ struct ocfs2_refcount_rec rl_recs[]; /* Refcount records */ 937 + /* Refcount records */ 938 + /*10*/ struct ocfs2_refcount_rec rl_recs[] __counted_by_le(rl_count); 942 939 }; 943 940 944 941 ··· 1025 1020 buckets. A block uses 1026 1021 xb_check and sets 1027 1022 this field to zero.) */ 1028 - struct ocfs2_xattr_entry xh_entries[]; /* xattr entry list. */ 1023 + /* xattr entry list. */ 1024 + struct ocfs2_xattr_entry xh_entries[] __counted_by_le(xh_count); 1029 1025 }; 1030 1026 1031 1027 /*