Skip to contentSkip to conversation

md/md-linear: Annotate struct linear_conf with __counted_by

PATCH Applied Kees Cook 3 participants 6 messages Sep 15, 2023 – Sep 29, 2023 MD RAID

lore
Share & tools
lore

Kees Cook

author
#0 lore raw

PATCH 1/1 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

---
 drivers/md/md-linear.c | 26 +++++++++++++-------------
 drivers/md/md-linear.h |  2 +-
 2 files changed, 14 insertions(+), 14 deletions(-)
drivers/md/md-linear.c +13 -13
index 71ac99646827..ae2826e9645b 100644
@@ -69,6 +69,19 @@ static struct linear_conf *linear_conf(struct mddev *mddev, int raid_disks)
 	if (!conf)
 		return NULL;
 
+	/*
+	 * conf->raid_disks is copy of mddev->raid_disks. The reason to
+	 * keep a copy of mddev->raid_disks in struct linear_conf is,
+	 * mddev->raid_disks may not be consistent with pointers number of
+	 * conf->disks[] when it is updated in linear_add() and used to
+	 * iterate old conf->disks[] earray in linear_congested().
+	 * Here conf->raid_disks is always consitent with number of
+	 * pointers in conf->disks[] array, and mddev->private is updated
+	 * with rcu_assign_pointer() in linear_addr(), such race can be
+	 * avoided.
+	 */
+	conf->raid_disks = raid_disks;
+
 	cnt = 0;
 	conf->array_sectors = 0;
 
@@ -112,19 +125,6 @@ static struct linear_conf *linear_conf(struct mddev *mddev, int raid_disks)
 			conf->disks[i-1].end_sector +
 			conf->disks[i].rdev->sectors;
 
-	/*
-	 * conf->raid_disks is copy of mddev->raid_disks. The reason to
-	 * keep a copy of mddev->raid_disks in struct linear_conf is,
-	 * mddev->raid_disks may not be consistent with pointers number of
-	 * conf->disks[] when it is updated in linear_add() and used to
-	 * iterate old conf->disks[] earray in linear_congested().
-	 * Here conf->raid_disks is always consitent with number of
-	 * pointers in conf->disks[] array, and mddev->private is updated
-	 * with rcu_assign_pointer() in linear_addr(), such race can be
-	 * avoided.
-	 */
-	conf->raid_disks = raid_disks;
-
 	return conf;
 
 out:
drivers/md/md-linear.h +1 -1
index 24e97db50ebb..5587eeedb882 100644
@@ -12,6 +12,6 @@ struct linear_conf
 	struct rcu_head		rcu;
 	sector_t		array_sectors;
 	int			raid_disks; /* a copy of mddev->raid_disks */
-	struct dev_info		disks[];
+	struct dev_info		disks[] __counted_by(raid_disks);
 };
 #endif
Signature · 1 line
2.34.1
Reviewed-by on v1 1/1
#1 lore raw
Quoted 10 lines · Kees Cook

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.

Quoted 5 lines

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

Thanks

Signature · 1 line
Gustavo
Quoted 61 lines
---
  drivers/md/md-linear.c | 26 +++++++++++++-------------
  drivers/md/md-linear.h |  2 +-
  2 files changed, 14 insertions(+), 14 deletions(-)
drivers/md/md-linear.c +13 -13
index 71ac99646827..ae2826e9645b 100644
@@ -69,6 +69,19 @@ static struct linear_conf *linear_conf(struct mddev *mddev, int raid_disks)
  	if (!conf)
  		return NULL;
 
+	/*
+	 * conf->raid_disks is copy of mddev->raid_disks. The reason to
+	 * keep a copy of mddev->raid_disks in struct linear_conf is,
+	 * mddev->raid_disks may not be consistent with pointers number of
+	 * conf->disks[] when it is updated in linear_add() and used to
+	 * iterate old conf->disks[] earray in linear_congested().
+	 * Here conf->raid_disks is always consitent with number of
+	 * pointers in conf->disks[] array, and mddev->private is updated
+	 * with rcu_assign_pointer() in linear_addr(), such race can be
+	 * avoided.
+	 */
+	conf->raid_disks = raid_disks;
+
  	cnt = 0;
  	conf->array_sectors = 0;
 
@@ -112,19 +125,6 @@ static struct linear_conf *linear_conf(struct mddev *mddev, int raid_disks)
  			conf->disks[i-1].end_sector +
  			conf->disks[i].rdev->sectors;
 
-	/*
-	 * conf->raid_disks is copy of mddev->raid_disks. The reason to
-	 * keep a copy of mddev->raid_disks in struct linear_conf is,
-	 * mddev->raid_disks may not be consistent with pointers number of
-	 * conf->disks[] when it is updated in linear_add() and used to
-	 * iterate old conf->disks[] earray in linear_congested().
-	 * Here conf->raid_disks is always consitent with number of
-	 * pointers in conf->disks[] array, and mddev->private is updated
-	 * with rcu_assign_pointer() in linear_addr(), such race can be
-	 * avoided.
-	 */
-	conf->raid_disks = raid_disks;
-
  	return conf;
 
  out:
drivers/md/md-linear.h +1 -1
index 24e97db50ebb..5587eeedb882 100644
@@ -12,6 +12,6 @@ struct linear_conf
  	struct rcu_head		rcu;
  	sector_t		array_sectors;
  	int			raid_disks; /* a copy of mddev->raid_disks */
-	struct dev_info		disks[];
+	struct dev_info		disks[] __counted_by(raid_disks);
  };
  #endif
maintainer Applied
#2 lore raw
Quoted 14 lines · Gustavo A. R. Silva
Quoted 10 lines · Kees Cook

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.

Quoted 7 lines
Quoted 5 lines

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

Applied to md-next. Thanks!
Song

author Applied
#3 lore raw
In reply to Kees Cook
Quoted 11 lines · Kees Cook

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.

[...]

Applied to for-next/hardening, thanks!

[1/1] md/md-linear: Annotate struct linear_conf with __counted_by

      https://git.kernel.org/kees/c/9add7681e09b

Take care,

Signature · 1 line
Kees Cook
maintainer
#4 lore raw
Quoted 12 lines · Kees Cook
Quoted 10 lines · Kees Cook

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.

Quoted 6 lines
Quoted 1 line

[...]

Applied to for-next/hardening, thanks!

[1/1] md/md-linear: Annotate struct linear_conf with __counted_by

      https://git.kernel.org/kees/c/9add7681e09b

Hmm..

Jens pulled this into his for-next branch and for-6.7/block branch earlier today:

https://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git/commit/?h=for-next&id=e887544d7620f1d3cef017e45df7bc625182caff

Do we need to do anything about this (drop one of them)?

Thanks,
Song

author
#5 lore raw
Quoted 20 lines · Song Liu
Quoted 12 lines · Kees Cook
Quoted 10 lines · Kees Cook

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.

Quoted 6 lines
Quoted 1 line

[...]

Applied to for-next/hardening, thanks!

[1/1] md/md-linear: Annotate struct linear_conf with __counted_by

      https://git.kernel.org/kees/c/9add7681e09b
Quoted 8 lines

Hmm..

Jens pulled this into his for-next branch and for-6.7/block branch earlier today:

https://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git/commit/?h=for-next&id=e887544d7620f1d3cef017e45df7bc625182caff

Do we need to do anything about this (drop one of them)?

Whoops! Sorry, I hadn't seen it picked up. I'll drop it from my tree. Thanks!

-Kees

Signature · 1 line
Kees Cook