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

md/md-linear: Annotate struct linear_conf with __counted_by

Prepare for the coming implementation by GCC and Clang of the __counted_by
attribute. Flexible array members annotated with __counted_by can have
their accesses bounds-checked at run-time checking via CONFIG_UBSAN_BOUNDS
(for array indexing) and CONFIG_FORTIFY_SOURCE (for strcpy/memcpy-family
functions).

As found with Coccinelle[1], add __counted_by for struct linear_conf.
Additionally, since the element count member must be set before accessing
the annotated flexible array member, move its initialization earlier.

[1] https://github.com/kees/kernel-tools/blob/trunk/coccinelle/examples/counted_by.cocci

Cc: Song Liu <song@kernel.org>
Cc: linux-raid@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Gustavo A. R. Silva <gustavoars@kernel.org>
Signed-off-by: Song Liu <song@kernel.org>
Link: https://lore.kernel.org/r/20230915200328.never.064-kees@kernel.org

authored by

Kees Cook and committed by
Song Liu
e887544d 54d21eb6

+14 -14
+13 -13
drivers/md/md-linear.c
··· 69 69 if (!conf) 70 70 return NULL; 71 71 72 + /* 73 + * conf->raid_disks is copy of mddev->raid_disks. The reason to 74 + * keep a copy of mddev->raid_disks in struct linear_conf is, 75 + * mddev->raid_disks may not be consistent with pointers number of 76 + * conf->disks[] when it is updated in linear_add() and used to 77 + * iterate old conf->disks[] earray in linear_congested(). 78 + * Here conf->raid_disks is always consitent with number of 79 + * pointers in conf->disks[] array, and mddev->private is updated 80 + * with rcu_assign_pointer() in linear_addr(), such race can be 81 + * avoided. 82 + */ 83 + conf->raid_disks = raid_disks; 84 + 72 85 cnt = 0; 73 86 conf->array_sectors = 0; 74 87 ··· 124 111 conf->disks[i].end_sector = 125 112 conf->disks[i-1].end_sector + 126 113 conf->disks[i].rdev->sectors; 127 - 128 - /* 129 - * conf->raid_disks is copy of mddev->raid_disks. The reason to 130 - * keep a copy of mddev->raid_disks in struct linear_conf is, 131 - * mddev->raid_disks may not be consistent with pointers number of 132 - * conf->disks[] when it is updated in linear_add() and used to 133 - * iterate old conf->disks[] earray in linear_congested(). 134 - * Here conf->raid_disks is always consitent with number of 135 - * pointers in conf->disks[] array, and mddev->private is updated 136 - * with rcu_assign_pointer() in linear_addr(), such race can be 137 - * avoided. 138 - */ 139 - conf->raid_disks = raid_disks; 140 114 141 115 return conf; 142 116
+1 -1
drivers/md/md-linear.h
··· 12 12 struct rcu_head rcu; 13 13 sector_t array_sectors; 14 14 int raid_disks; /* a copy of mddev->raid_disks */ 15 - struct dev_info disks[]; 15 + struct dev_info disks[] __counted_by(raid_disks); 16 16 }; 17 17 #endif