drivers/iio/industrialio-gts-helper.c | 4 ++-- include/linux/iio/iio-gts-helper.h | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-)
The compiler attribute __counted_by_ptr can be used by KASAN and UBSAN
to detect out-of-bounds accesses to pointer fields in structs where a
corresponding element count field is available.
In "struct iio_gts", there are multiple pointer fields associated with
an element count. This patch annotates these pointer fields with
"__counted_by_ptr" to improve runtime safety:
- 'hwgain_table': counted by 'num_hwgain'
- 'itime_table': counted by 'num_itime'
- 'per_time_avail_scale_tables': counted by 'num_itime'
- 'avail_all_scales_table': counted by 'num_avail_all_scales'
- 'avail_time_tables': counted by 'num_avail_time_tables'
To ensure that the count is set correctly before any pointer is
accessed or assigned, we update "iio_init_iio_gts()" to set the counts
prior to assigning the pointers.
Cc: codemender-patching+linux@google.com
Assisted-by: LLM
Signed-off-by: Bill Wendling <morbo@google.com>
---
drivers/iio/industrialio-gts-helper.c | 4 ++--
include/linux/iio/iio-gts-helper.h | 10 +++++-----
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/iio/industrialio-gts-helper.c b/drivers/iio/industrialio-gts-helper.c
index 4f52dc373abf..4de6324fd923 100644
--- a/drivers/iio/industrialio-gts-helper.c
+++ b/drivers/iio/industrialio-gts-helper.c
@@ -652,10 +652,10 @@ static int iio_init_iio_gts(int max_scale_int, int max_scale_nano,
if (ret)
return ret;
- gts->hwgain_table = gain_tbl;
gts->num_hwgain = num_gain;
- gts->itime_table = tim_tbl;
+ gts->hwgain_table = gain_tbl;
gts->num_itime = num_times;
+ gts->itime_table = tim_tbl;
return iio_gts_sanity_check(gts);
}
diff --git a/include/linux/iio/iio-gts-helper.h b/include/linux/iio/iio-gts-helper.h
index 66f830ab9b49..7e7d3396ff1a 100644
--- a/include/linux/iio/iio-gts-helper.h
+++ b/include/linux/iio/iio-gts-helper.h
@@ -58,14 +58,14 @@ struct iio_itime_sel_mul {
struct iio_gts {
u64 max_scale;
- const struct iio_gain_sel_pair *hwgain_table;
+ const struct iio_gain_sel_pair *hwgain_table __counted_by_ptr(num_hwgain);
int num_hwgain;
- const struct iio_itime_sel_mul *itime_table;
+ const struct iio_itime_sel_mul *itime_table __counted_by_ptr(num_itime);
int num_itime;
- int **per_time_avail_scale_tables;
- int *avail_all_scales_table;
+ int **per_time_avail_scale_tables __counted_by_ptr(num_itime);
+ int *avail_all_scales_table __counted_by_ptr(num_avail_all_scales);
int num_avail_all_scales;
- int *avail_time_tables;
+ int *avail_time_tables __counted_by_ptr(num_avail_time_tables);
int num_avail_time_tables;
};
--
2.55.0.1082.g2b9226bbc0-goog
On Wed, Sep 23, 2026 at 04:16:30AM +0000, Bill Wendling wrote: > The compiler attribute __counted_by_ptr can be used by KASAN and UBSAN > to detect out-of-bounds accesses to pointer fields in structs where a > corresponding element count field is available. > > In "struct iio_gts", there are multiple pointer fields associated with > an element count. This patch annotates these pointer fields with > "__counted_by_ptr" to improve runtime safety: > > - 'hwgain_table': counted by 'num_hwgain' > - 'itime_table': counted by 'num_itime' > - 'per_time_avail_scale_tables': counted by 'num_itime' > - 'avail_all_scales_table': counted by 'num_avail_all_scales' > - 'avail_time_tables': counted by 'num_avail_time_tables' > > To ensure that the count is set correctly before any pointer is > accessed or assigned, we update "iio_init_iio_gts()" to set the counts > prior to assigning the pointers. "Accessed" yes, "assigned" no. :) Let's not churn on assignment ordering unless there is some problem I'm not seeing. The only time this should ever matter is if there is multithread visibility on the object already, but that would require both counter and pointer be set, so that'd be a general locking issue, but ordering during initialization doesn't matter. -- Kees Cook
On Wed, Sep 23, 2026 at 12:26 AM Kees Cook <kees@kernel.org> wrote: > On Wed, Sep 23, 2026 at 04:16:30AM +0000, Bill Wendling wrote: > > The compiler attribute __counted_by_ptr can be used by KASAN and UBSAN > > to detect out-of-bounds accesses to pointer fields in structs where a > > corresponding element count field is available. > > > > In "struct iio_gts", there are multiple pointer fields associated with > > an element count. This patch annotates these pointer fields with > > "__counted_by_ptr" to improve runtime safety: > > > > - 'hwgain_table': counted by 'num_hwgain' > > - 'itime_table': counted by 'num_itime' > > - 'per_time_avail_scale_tables': counted by 'num_itime' > > - 'avail_all_scales_table': counted by 'num_avail_all_scales' > > - 'avail_time_tables': counted by 'num_avail_time_tables' > > > > To ensure that the count is set correctly before any pointer is > > accessed or assigned, we update "iio_init_iio_gts()" to set the counts > > prior to assigning the pointers. > > "Accessed" yes, "assigned" no. :) Let's not churn on assignment ordering > unless there is some problem I'm not seeing. The only time this should > ever matter is if there is multithread visibility on the object already, > but that would require both counter and pointer be set, so that'd be a > general locking issue, but ordering during initialization doesn't > matter. > In a separate patch, Sashiko flagged the assignments being "out of order". It's not an error, but I did submit a "v2" that reordered the assignments (that Sashiko is still complaining about, but I think it's a pre-existing issue). I can weed out the needless reordering changes from the patches, however, I like the idea of people thinking about the ordering of such assignments. It's a small thing I know, but I need something to hold on to. :-D -bw
On 9/23/26 13:16, Bill Wendling wrote:
> The compiler attribute __counted_by_ptr can be used by KASAN and UBSAN
> to detect out-of-bounds accesses to pointer fields in structs where a
> corresponding element count field is available.
>
> In "struct iio_gts", there are multiple pointer fields associated with
> an element count. This patch annotates these pointer fields with
> "__counted_by_ptr" to improve runtime safety:
>
> - 'hwgain_table': counted by 'num_hwgain'
> - 'itime_table': counted by 'num_itime'
> - 'per_time_avail_scale_tables': counted by 'num_itime'
> - 'avail_all_scales_table': counted by 'num_avail_all_scales'
> - 'avail_time_tables': counted by 'num_avail_time_tables'
>
> To ensure that the count is set correctly before any pointer is
> accessed or assigned, we update "iio_init_iio_gts()" to set the counts
> prior to assigning the pointers.
>
> Cc: codemender-patching+linux@google.com
> Assisted-by: LLM
> Signed-off-by: Bill Wendling <morbo@google.com>
Reviewed-by: Gustavo A. R. Silva <gustavoars@kernel.org>
Thanks
-Gustavo
> ---
> drivers/iio/industrialio-gts-helper.c | 4 ++--
> include/linux/iio/iio-gts-helper.h | 10 +++++-----
> 2 files changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/iio/industrialio-gts-helper.c b/drivers/iio/industrialio-gts-helper.c
> index 4f52dc373abf..4de6324fd923 100644
> --- a/drivers/iio/industrialio-gts-helper.c
> +++ b/drivers/iio/industrialio-gts-helper.c
> @@ -652,10 +652,10 @@ static int iio_init_iio_gts(int max_scale_int, int max_scale_nano,
> if (ret)
> return ret;
>
> - gts->hwgain_table = gain_tbl;
> gts->num_hwgain = num_gain;
> - gts->itime_table = tim_tbl;
> + gts->hwgain_table = gain_tbl;
> gts->num_itime = num_times;
> + gts->itime_table = tim_tbl;
>
> return iio_gts_sanity_check(gts);
> }
> diff --git a/include/linux/iio/iio-gts-helper.h b/include/linux/iio/iio-gts-helper.h
> index 66f830ab9b49..7e7d3396ff1a 100644
> --- a/include/linux/iio/iio-gts-helper.h
> +++ b/include/linux/iio/iio-gts-helper.h
> @@ -58,14 +58,14 @@ struct iio_itime_sel_mul {
>
> struct iio_gts {
> u64 max_scale;
> - const struct iio_gain_sel_pair *hwgain_table;
> + const struct iio_gain_sel_pair *hwgain_table __counted_by_ptr(num_hwgain);
> int num_hwgain;
> - const struct iio_itime_sel_mul *itime_table;
> + const struct iio_itime_sel_mul *itime_table __counted_by_ptr(num_itime);
> int num_itime;
> - int **per_time_avail_scale_tables;
> - int *avail_all_scales_table;
> + int **per_time_avail_scale_tables __counted_by_ptr(num_itime);
> + int *avail_all_scales_table __counted_by_ptr(num_avail_all_scales);
> int num_avail_all_scales;
> - int *avail_time_tables;
> + int *avail_time_tables __counted_by_ptr(num_avail_time_tables);
> int num_avail_time_tables;
> };
>
On 23/09/2026 07:16, Bill Wendling wrote:
> The compiler attribute __counted_by_ptr can be used by KASAN and UBSAN
> to detect out-of-bounds accesses to pointer fields in structs where a
> corresponding element count field is available.
>
> In "struct iio_gts", there are multiple pointer fields associated with
> an element count. This patch annotates these pointer fields with
> "__counted_by_ptr" to improve runtime safety:
>
> - 'hwgain_table': counted by 'num_hwgain'
> - 'itime_table': counted by 'num_itime'
> - 'per_time_avail_scale_tables': counted by 'num_itime'
> - 'avail_all_scales_table': counted by 'num_avail_all_scales'
> - 'avail_time_tables': counted by 'num_avail_time_tables'
>
> To ensure that the count is set correctly before any pointer is
> accessed or assigned, we update "iio_init_iio_gts()" to set the counts
> prior to assigning the pointers.
>
> Cc: codemender-patching+linux@google.com
> Assisted-by: LLM
> Signed-off-by: Bill Wendling <morbo@google.com>
I like this! Thanks!
Acked-by: Matti Vaittinen <mazziesaccount@gmail.com>
> ---
> drivers/iio/industrialio-gts-helper.c | 4 ++--
> include/linux/iio/iio-gts-helper.h | 10 +++++-----
> 2 files changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/iio/industrialio-gts-helper.c b/drivers/iio/industrialio-gts-helper.c
> index 4f52dc373abf..4de6324fd923 100644
> --- a/drivers/iio/industrialio-gts-helper.c
> +++ b/drivers/iio/industrialio-gts-helper.c
> @@ -652,10 +652,10 @@ static int iio_init_iio_gts(int max_scale_int, int max_scale_nano,
> if (ret)
> return ret;
>
> - gts->hwgain_table = gain_tbl;
> gts->num_hwgain = num_gain;
> - gts->itime_table = tim_tbl;
> + gts->hwgain_table = gain_tbl;
> gts->num_itime = num_times;
> + gts->itime_table = tim_tbl;
>
> return iio_gts_sanity_check(gts);
> }
> diff --git a/include/linux/iio/iio-gts-helper.h b/include/linux/iio/iio-gts-helper.h
> index 66f830ab9b49..7e7d3396ff1a 100644
> --- a/include/linux/iio/iio-gts-helper.h
> +++ b/include/linux/iio/iio-gts-helper.h
> @@ -58,14 +58,14 @@ struct iio_itime_sel_mul {
>
> struct iio_gts {
> u64 max_scale;
> - const struct iio_gain_sel_pair *hwgain_table;
> + const struct iio_gain_sel_pair *hwgain_table __counted_by_ptr(num_hwgain);
> int num_hwgain;
> - const struct iio_itime_sel_mul *itime_table;
> + const struct iio_itime_sel_mul *itime_table __counted_by_ptr(num_itime);
> int num_itime;
> - int **per_time_avail_scale_tables;
> - int *avail_all_scales_table;
> + int **per_time_avail_scale_tables __counted_by_ptr(num_itime);
> + int *avail_all_scales_table __counted_by_ptr(num_avail_all_scales);
> int num_avail_all_scales;
> - int *avail_time_tables;
> + int *avail_time_tables __counted_by_ptr(num_avail_time_tables);
> int num_avail_time_tables;
> };
>
--
Matti Vaittinen
Linux kernel developer at ROHM Semiconductors
Oulu Finland
~~ When things go utterly wrong vim users can always type :help! ~~
The compiler attribute __counted_by_ptr can be used by KASAN and UBSAN
to detect out-of-bounds accesses to pointer fields in structs where a
corresponding element count field is available.
In "struct iio_gts", there are multiple pointer fields associated with
an element count. This patch annotates these pointer fields with
"__counted_by_ptr" to improve runtime safety:
- 'hwgain_table': counted by 'num_hwgain'
- 'itime_table': counted by 'num_itime'
- 'per_time_avail_scale_tables': counted by 'num_itime'
- 'avail_all_scales_table': counted by 'num_avail_all_scales'
- 'avail_time_tables': counted by 'num_avail_time_tables'
To ensure that the count is set correctly before any pointer is
accessed or assigned, we update "iio_init_iio_gts()" to set the counts
prior to assigning the pointers.
Cc: codemender-patching+linux@google.com
Assisted-by: LLM
Signed-off-by: Bill Wendling <morbo@google.com>
Acked-by: Matti Vaittinen <mazziesaccount@gmail.com>
Reviewed-by: Gustavo A. R. Silva <gustavoars@kernel.org>
---
v2: Remove reordering of assignments. It's not necessary as an assignment of
the pointer isn't an access that's checked by KASAN.
---
include/linux/iio/iio-gts-helper.h | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/include/linux/iio/iio-gts-helper.h b/include/linux/iio/iio-gts-helper.h
index 66f830ab9b49..7e7d3396ff1a 100644
--- a/include/linux/iio/iio-gts-helper.h
+++ b/include/linux/iio/iio-gts-helper.h
@@ -58,14 +58,14 @@ struct iio_itime_sel_mul {
struct iio_gts {
u64 max_scale;
- const struct iio_gain_sel_pair *hwgain_table;
+ const struct iio_gain_sel_pair *hwgain_table __counted_by_ptr(num_hwgain);
int num_hwgain;
- const struct iio_itime_sel_mul *itime_table;
+ const struct iio_itime_sel_mul *itime_table __counted_by_ptr(num_itime);
int num_itime;
- int **per_time_avail_scale_tables;
- int *avail_all_scales_table;
+ int **per_time_avail_scale_tables __counted_by_ptr(num_itime);
+ int *avail_all_scales_table __counted_by_ptr(num_avail_all_scales);
int num_avail_all_scales;
- int *avail_time_tables;
+ int *avail_time_tables __counted_by_ptr(num_avail_time_tables);
int num_avail_time_tables;
};
--
2.56.0.rc1.310.g51773c2048-goog
© 2016 - 2026 Red Hat, Inc.