Re: [RESEND PATCH] bcachefs: Annotate struct bucket_gens with __counted_by()

From: Kent Overstreet
Date: Sat Oct 26 2024 - 20:30:49 EST


On Sat, Oct 26, 2024 at 05:47:04PM +0200, Thorsten Blum wrote:
> Add the __counted_by compiler attribute to the flexible array member b
> to improve access bounds-checking via CONFIG_UBSAN_BOUNDS and
> CONFIG_FORTIFY_SOURCE.
>
> Use struct_size() to calculate the number of bytes to be allocated.
>
> Update bucket_gens->nbuckets and bucket_gens->nbuckets_minus_first when
> resizing.
>
> Compile-tested only.
>
> Signed-off-by: Thorsten Blum <thorsten.blum@xxxxxxxxx>

I can take this patch without it being tested, but please have a look at
ktest:
https://evilpiepirate.org/git/ktest.git/

that's where all the bcachefs tests live, and it's a nice testing and
debugging tool. The CI runs the same tests, and I can give you an
account there as well.

> ---
> fs/bcachefs/buckets.c | 13 ++++++++-----
> fs/bcachefs/buckets_types.h | 2 +-
> 2 files changed, 9 insertions(+), 6 deletions(-)
>
> diff --git a/fs/bcachefs/buckets.c b/fs/bcachefs/buckets.c
> index ec7d9a59bea9..8bd17667e243 100644
> --- a/fs/bcachefs/buckets.c
> +++ b/fs/bcachefs/buckets.c
> @@ -1266,8 +1266,9 @@ int bch2_dev_buckets_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets)
>
> BUG_ON(resize && ca->buckets_nouse);
>
> - if (!(bucket_gens = kvmalloc(sizeof(struct bucket_gens) + nbuckets,
> - GFP_KERNEL|__GFP_ZERO))) {
> + bucket_gens = kvmalloc(struct_size(bucket_gens, b, nbuckets),
> + GFP_KERNEL|__GFP_ZERO);
> + if (!bucket_gens) {
> ret = -BCH_ERR_ENOMEM_bucket_gens;
> goto err;
> }
> @@ -1285,11 +1286,13 @@ int bch2_dev_buckets_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets)
> old_bucket_gens = rcu_dereference_protected(ca->bucket_gens, 1);
>
> if (resize) {
> - size_t n = min(bucket_gens->nbuckets, old_bucket_gens->nbuckets);
> -
> + bucket_gens->nbuckets = min(bucket_gens->nbuckets,
> + old_bucket_gens->nbuckets);
> + bucket_gens->nbuckets_minus_first =
> + bucket_gens->nbuckets - bucket_gens->first_bucket;
> memcpy(bucket_gens->b,
> old_bucket_gens->b,
> - n);
> + bucket_gens->nbuckets);
> }
>
> rcu_assign_pointer(ca->bucket_gens, bucket_gens);
> diff --git a/fs/bcachefs/buckets_types.h b/fs/bcachefs/buckets_types.h
> index 28bd09a253c8..7174047b8e92 100644
> --- a/fs/bcachefs/buckets_types.h
> +++ b/fs/bcachefs/buckets_types.h
> @@ -24,7 +24,7 @@ struct bucket_gens {
> u16 first_bucket;
> size_t nbuckets;
> size_t nbuckets_minus_first;
> - u8 b[];
> + u8 b[] __counted_by(nbuckets);
> };
>
> struct bch_dev_usage {
> --
> 2.47.0
>