fs/bcachefs/buckets.c | 13 ++++++++----- fs/bcachefs/buckets_types.h | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-)
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@linux.dev>
---
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
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@linux.dev>
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
>
© 2016 - 2026 Red Hat, Inc.