* [PATCH 1/2] vfs: Annotate struct fdtable's fd field with __counted_by_ptr
[not found] <20260810204118.1981755-1-morbo@google.com>
@ 2026-08-10 20:41 ` Bill Wendling
2026-08-11 0:18 ` Kees Cook
2026-08-10 20:41 ` [PATCH 2/2] vfs: Add KUnit tests for fdtable Bill Wendling
` (2 subsequent siblings)
3 siblings, 1 reply; 16+ messages in thread
From: Bill Wendling @ 2026-08-10 20:41 UTC (permalink / raw)
Cc: Bill Wendling, codemender-patching+linux, Alexander Viro,
Christian Brauner, Jan Kara, Kees Cook, Gustavo A. R. Silva,
linux-kernel, linux-fsdevel, linux-hardening
The 'struct fdtable' holds the file descriptor table information,
including the current file descriptor array 'fd' and its size 'max_fds'.
To harden the kernel against out-of-bounds accesses, we can annotate the
'fd' pointer field with the '__counted_by_ptr' attribute, referencing
'max_fds'.
The compiler uses the '__counted_by_ptr' attribute to track the
size of the memory allocated for the pointer field, enabling
runtime bounds checks under KASAN and fortified functions. There are
three places where a 'struct fdtable' is initialized, and in all of
them, 'max_fds' is set before the 'fd' pointer is accessed or assigned
in all allocation and initialization places.
No accesses to 'fd' occur before 'max_fds' is set, preventing any
potential runtime false-positives or panics due to uninitialized count
fields.
This patch was generated by CodeMender and checked by submitter.
Cc: codemender-patching+linux@google.com
Signed-off-by: Bill Wendling <morbo@google.com>
---
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Jan Kara <jack@suse.cz>
Cc: Kees Cook <kees@kernel.org>
Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
Cc: linux-kernel@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-hardening@vger.kernel.org
---
include/linux/fdtable.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h
index c45306a9f007..3a5c88291125 100644
--- a/include/linux/fdtable.h
+++ b/include/linux/fdtable.h
@@ -25,7 +25,7 @@
struct fdtable {
unsigned int max_fds;
- struct file __rcu **fd; /* current fd array */
+ struct file __rcu **fd __counted_by_ptr(max_fds); /* current fd array */
unsigned long *close_on_exec;
unsigned long *open_fds;
unsigned long *full_fds_bits;
--
2.55.0.679.g6767b8d81c-goog
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [PATCH 1/2] vfs: Annotate struct fdtable's fd field with __counted_by_ptr
2026-08-10 20:41 ` [PATCH 1/2] vfs: Annotate struct fdtable's fd field with __counted_by_ptr Bill Wendling
@ 2026-08-11 0:18 ` Kees Cook
2026-08-27 4:18 ` Bill Wendling
0 siblings, 1 reply; 16+ messages in thread
From: Kees Cook @ 2026-08-11 0:18 UTC (permalink / raw)
To: Bill Wendling
Cc: codemender-patching+linux, Alexander Viro, Christian Brauner,
Jan Kara, Gustavo A. R. Silva, linux-kernel, linux-fsdevel,
linux-hardening
On Mon, Aug 10, 2026 at 08:41:12PM +0000, Bill Wendling wrote:
> The 'struct fdtable' holds the file descriptor table information,
> including the current file descriptor array 'fd' and its size 'max_fds'.
> To harden the kernel against out-of-bounds accesses, we can annotate the
> 'fd' pointer field with the '__counted_by_ptr' attribute, referencing
> 'max_fds'.
>
> The compiler uses the '__counted_by_ptr' attribute to track the
> size of the memory allocated for the pointer field, enabling
> runtime bounds checks under KASAN and fortified functions. There are
> three places where a 'struct fdtable' is initialized, and in all of
> them, 'max_fds' is set before the 'fd' pointer is accessed or assigned
> in all allocation and initialization places.
>
> No accesses to 'fd' occur before 'max_fds' is set, preventing any
> potential runtime false-positives or panics due to uninitialized count
> fields.
>
> This patch was generated by CodeMender and checked by submitter.
>
> Cc: codemender-patching+linux@google.com
> Signed-off-by: Bill Wendling <morbo@google.com>
> ---
> Cc: Alexander Viro <viro@zeniv.linux.org.uk>
> Cc: Christian Brauner <brauner@kernel.org>
> Cc: Jan Kara <jack@suse.cz>
> Cc: Kees Cook <kees@kernel.org>
> Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-fsdevel@vger.kernel.org
> Cc: linux-hardening@vger.kernel.org
> ---
> include/linux/fdtable.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h
> index c45306a9f007..3a5c88291125 100644
> --- a/include/linux/fdtable.h
> +++ b/include/linux/fdtable.h
> @@ -25,7 +25,7 @@
>
> struct fdtable {
> unsigned int max_fds;
> - struct file __rcu **fd; /* current fd array */
> + struct file __rcu **fd __counted_by_ptr(max_fds); /* current fd array */
> unsigned long *close_on_exec;
> unsigned long *open_fds;
> unsigned long *full_fds_bits;
I see the alloc_fdtable test, that's one max_fds assignment, but I also
see dup_fd(), which does the assignment after the newf allocation, so
that looks safe too, but it might be nice to add that allocation path to
the tests too?
--
Kees Cook
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [PATCH 1/2] vfs: Annotate struct fdtable's fd field with __counted_by_ptr
2026-08-11 0:18 ` Kees Cook
@ 2026-08-27 4:18 ` Bill Wendling
0 siblings, 0 replies; 16+ messages in thread
From: Bill Wendling @ 2026-08-27 4:18 UTC (permalink / raw)
To: Kees Cook
Cc: codemender-patching+linux, Alexander Viro, Christian Brauner,
Jan Kara, Gustavo A. R. Silva, linux-kernel, linux-fsdevel,
linux-hardening
On Mon, Aug 10, 2026 at 5:18 PM Kees Cook <kees@kernel.org> wrote:
>
> On Mon, Aug 10, 2026 at 08:41:12PM +0000, Bill Wendling wrote:
> > The 'struct fdtable' holds the file descriptor table information,
> > including the current file descriptor array 'fd' and its size 'max_fds'.
> > To harden the kernel against out-of-bounds accesses, we can annotate the
> > 'fd' pointer field with the '__counted_by_ptr' attribute, referencing
> > 'max_fds'.
> >
> > The compiler uses the '__counted_by_ptr' attribute to track the
> > size of the memory allocated for the pointer field, enabling
> > runtime bounds checks under KASAN and fortified functions. There are
> > three places where a 'struct fdtable' is initialized, and in all of
> > them, 'max_fds' is set before the 'fd' pointer is accessed or assigned
> > in all allocation and initialization places.
> >
> > No accesses to 'fd' occur before 'max_fds' is set, preventing any
> > potential runtime false-positives or panics due to uninitialized count
> > fields.
> >
> > This patch was generated by CodeMender and checked by submitter.
> >
> > Cc: codemender-patching+linux@google.com
> > Signed-off-by: Bill Wendling <morbo@google.com>
> > ---
> > Cc: Alexander Viro <viro@zeniv.linux.org.uk>
> > Cc: Christian Brauner <brauner@kernel.org>
> > Cc: Jan Kara <jack@suse.cz>
> > Cc: Kees Cook <kees@kernel.org>
> > Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
> > Cc: linux-kernel@vger.kernel.org
> > Cc: linux-fsdevel@vger.kernel.org
> > Cc: linux-hardening@vger.kernel.org
> > ---
> > include/linux/fdtable.h | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h
> > index c45306a9f007..3a5c88291125 100644
> > --- a/include/linux/fdtable.h
> > +++ b/include/linux/fdtable.h
> > @@ -25,7 +25,7 @@
> >
> > struct fdtable {
> > unsigned int max_fds;
> > - struct file __rcu **fd; /* current fd array */
> > + struct file __rcu **fd __counted_by_ptr(max_fds); /* current fd array */
> > unsigned long *close_on_exec;
> > unsigned long *open_fds;
> > unsigned long *full_fds_bits;
>
> I see the alloc_fdtable test, that's one max_fds assignment, but I also
> see dup_fd(), which does the assignment after the newf allocation, so
> that looks safe too, but it might be nice to add that allocation path to
> the tests too?
>
Hi Kees,
I added a testcase for the 'dup_fd' path.
-bw
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 2/2] vfs: Add KUnit tests for fdtable
[not found] <20260810204118.1981755-1-morbo@google.com>
2026-08-10 20:41 ` [PATCH 1/2] vfs: Annotate struct fdtable's fd field with __counted_by_ptr Bill Wendling
@ 2026-08-10 20:41 ` Bill Wendling
2026-08-11 0:16 ` Kees Cook
2026-08-27 4:15 ` [PATCH 1/2] vfs: Annotate struct fdtable's fd field with __counted_by_ptr Bill Wendling
2026-08-27 4:17 ` [PATCH v3 1/2] vfs: Annotate struct fdtable's fd field with __counted_by_ptr Bill Wendling
3 siblings, 1 reply; 16+ messages in thread
From: Bill Wendling @ 2026-08-10 20:41 UTC (permalink / raw)
Cc: Bill Wendling, codemender-patching+linux, Alexander Viro,
Christian Brauner, Jan Kara, Kees Cook, Gustavo A. R. Silva,
linux-kernel, linux-fsdevel, linux-hardening
This adds a KUnit test suite for fdtable to verify correct allocation,
max_fds initialization, and dynamic object size of the fd array under
__counted_by_ptr when CONFIG_CC_HAS_COUNTED_BY_PTR is enabled.
This patch was generated by CodeMender and checked by submitter.
Cc: codemender-patching+linux@google.com
Signed-off-by: Bill Wendling <morbo@google.com>
---
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Jan Kara <jack@suse.cz>
Cc: Kees Cook <kees@kernel.org>
Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
Cc: linux-kernel@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-hardening@vger.kernel.org
---
fs/Kconfig | 8 ++++++++
fs/file.c | 4 ++++
fs/tests/.kunitconfig | 2 ++
fs/tests/fdtable_kunit.c | 40 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 54 insertions(+)
create mode 100644 fs/tests/.kunitconfig
create mode 100644 fs/tests/fdtable_kunit.c
diff --git a/fs/Kconfig b/fs/Kconfig
index cf6ae64776e6..f4b9235ab883 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -423,4 +423,12 @@ source "fs/unicode/Kconfig"
config IO_WQ
bool
+config FDTABLE_KUNIT_TEST
+ bool "KUnit test for fdtable" if !KUNIT_ALL_TESTS
+ depends on KUNIT=y
+ default KUNIT_ALL_TESTS
+ help
+ This builds the fdtable KUnit tests, which tests various aspects
+ of the fdtable structure and allocation.
+
endmenu
diff --git a/fs/file.c b/fs/file.c
index 628ca07dc4b1..9c7001b901cf 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -1529,3 +1529,7 @@ int iterate_fd(struct files_struct *files, unsigned n,
return res;
}
EXPORT_SYMBOL(iterate_fd);
+
+#ifdef CONFIG_FDTABLE_KUNIT_TEST
+#include "tests/fdtable_kunit.c"
+#endif
diff --git a/fs/tests/.kunitconfig b/fs/tests/.kunitconfig
new file mode 100644
index 000000000000..de67125a9421
--- /dev/null
+++ b/fs/tests/.kunitconfig
@@ -0,0 +1,2 @@
+CONFIG_KUNIT=y
+CONFIG_FDTABLE_KUNIT_TEST=y
diff --git a/fs/tests/fdtable_kunit.c b/fs/tests/fdtable_kunit.c
new file mode 100644
index 000000000000..41bae6b7400f
--- /dev/null
+++ b/fs/tests/fdtable_kunit.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <kunit/test.h>
+#include <linux/fdtable.h>
+#include <linux/file.h>
+
+static void fdtable_test_alloc(struct kunit *test)
+{
+ struct fdtable *fdt;
+ unsigned int slots = 64;
+
+ fdt = alloc_fdtable(slots);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fdt);
+
+ /* Check that max_fds is set correctly and is >= slots */
+ KUNIT_EXPECT_GE(test, fdt->max_fds, slots);
+
+ /* Check that fd is allocated */
+ KUNIT_EXPECT_NOT_ERR_OR_NULL(test, fdt->fd);
+
+ /* Check dynamic object size of fdt->fd if compiler supports __counted_by_ptr */
+#ifdef CONFIG_CC_HAS_COUNTED_BY_PTR
+ KUNIT_EXPECT_EQ(test, __builtin_dynamic_object_size(fdt->fd, 0),
+ fdt->max_fds * sizeof(struct file *));
+#endif
+
+ /* Free the fdtable */
+ __free_fdtable(fdt);
+}
+
+static struct kunit_case fdtable_test_cases[] = {
+ KUNIT_CASE(fdtable_test_alloc),
+ {}
+};
+
+static struct kunit_suite fdtable_test_suite = {
+ .name = "fdtable",
+ .test_cases = fdtable_test_cases,
+};
+
+kunit_test_suite(fdtable_test_suite);
--
2.55.0.679.g6767b8d81c-goog
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [PATCH 2/2] vfs: Add KUnit tests for fdtable
2026-08-10 20:41 ` [PATCH 2/2] vfs: Add KUnit tests for fdtable Bill Wendling
@ 2026-08-11 0:16 ` Kees Cook
2026-08-11 15:42 ` Jann Horn
0 siblings, 1 reply; 16+ messages in thread
From: Kees Cook @ 2026-08-11 0:16 UTC (permalink / raw)
To: Bill Wendling
Cc: codemender-patching+linux, Alexander Viro, Christian Brauner,
Jan Kara, Gustavo A. R. Silva, linux-kernel, linux-fsdevel,
linux-hardening
On Mon, Aug 10, 2026 at 08:41:13PM +0000, Bill Wendling wrote:
> +static void fdtable_test_alloc(struct kunit *test)
> +{
> + struct fdtable *fdt;
> + unsigned int slots = 64;
> +
> + fdt = alloc_fdtable(slots);
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fdt);
> +
> + /* Check that max_fds is set correctly and is >= slots */
> + KUNIT_EXPECT_GE(test, fdt->max_fds, slots);
> +
> + /* Check that fd is allocated */
> + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, fdt->fd);
Nice to add these tests! Can you add one for each of the conditionals
in alloc_fdtable (e.g. ENOMEM, EMFILE, and the power-of-two rounding-up
logic, etc)?
-Kees
--
Kees Cook
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [PATCH 2/2] vfs: Add KUnit tests for fdtable
2026-08-11 0:16 ` Kees Cook
@ 2026-08-11 15:42 ` Jann Horn
2026-08-12 0:22 ` Kees Cook
0 siblings, 1 reply; 16+ messages in thread
From: Jann Horn @ 2026-08-11 15:42 UTC (permalink / raw)
To: Kees Cook
Cc: Bill Wendling, codemender-patching+linux, Alexander Viro,
Christian Brauner, Jan Kara, Gustavo A. R. Silva, linux-kernel,
linux-fsdevel, linux-hardening
On Tue, Aug 11, 2026 at 2:16 AM Kees Cook <kees@kernel.org> wrote:
> On Mon, Aug 10, 2026 at 08:41:13PM +0000, Bill Wendling wrote:
> > +static void fdtable_test_alloc(struct kunit *test)
> > +{
> > + struct fdtable *fdt;
> > + unsigned int slots = 64;
> > +
> > + fdt = alloc_fdtable(slots);
> > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fdt);
> > +
> > + /* Check that max_fds is set correctly and is >= slots */
> > + KUNIT_EXPECT_GE(test, fdt->max_fds, slots);
> > +
> > + /* Check that fd is allocated */
> > + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, fdt->fd);
>
> Nice to add these tests! Can you add one for each of the conditionals
> in alloc_fdtable (e.g. ENOMEM, EMFILE, and the power-of-two rounding-up
> logic, etc)?
Wouldn't tests for stuff like the rounding-up logic get into
implementation details too much, and break if implementation choices
change?
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [PATCH 2/2] vfs: Add KUnit tests for fdtable
2026-08-11 15:42 ` Jann Horn
@ 2026-08-12 0:22 ` Kees Cook
2026-08-12 15:06 ` Jann Horn
0 siblings, 1 reply; 16+ messages in thread
From: Kees Cook @ 2026-08-12 0:22 UTC (permalink / raw)
To: Jann Horn
Cc: Bill Wendling, codemender-patching+linux, Alexander Viro,
Christian Brauner, Jan Kara, Gustavo A. R. Silva, linux-kernel,
linux-fsdevel, linux-hardening
On Tue, Aug 11, 2026 at 05:42:05PM +0200, Jann Horn wrote:
> On Tue, Aug 11, 2026 at 2:16 AM Kees Cook <kees@kernel.org> wrote:
> > On Mon, Aug 10, 2026 at 08:41:13PM +0000, Bill Wendling wrote:
> > > +static void fdtable_test_alloc(struct kunit *test)
> > > +{
> > > + struct fdtable *fdt;
> > > + unsigned int slots = 64;
> > > +
> > > + fdt = alloc_fdtable(slots);
> > > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fdt);
> > > +
> > > + /* Check that max_fds is set correctly and is >= slots */
> > > + KUNIT_EXPECT_GE(test, fdt->max_fds, slots);
> > > +
> > > + /* Check that fd is allocated */
> > > + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, fdt->fd);
> >
> > Nice to add these tests! Can you add one for each of the conditionals
> > in alloc_fdtable (e.g. ENOMEM, EMFILE, and the power-of-two rounding-up
> > logic, etc)?
>
> Wouldn't tests for stuff like the rounding-up logic get into
> implementation details too much, and break if implementation choices
> change?
It seemed to me like we'd want to notice if that behavior changed?
--
Kees Cook
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [PATCH 2/2] vfs: Add KUnit tests for fdtable
2026-08-12 0:22 ` Kees Cook
@ 2026-08-12 15:06 ` Jann Horn
2026-08-25 12:35 ` Christian Brauner
0 siblings, 1 reply; 16+ messages in thread
From: Jann Horn @ 2026-08-12 15:06 UTC (permalink / raw)
To: Kees Cook
Cc: Bill Wendling, codemender-patching+linux, Alexander Viro,
Christian Brauner, Jan Kara, Gustavo A. R. Silva, linux-kernel,
linux-fsdevel, linux-hardening
On Wed, Aug 12, 2026 at 2:22 AM Kees Cook <kees@kernel.org> wrote:
> On Tue, Aug 11, 2026 at 05:42:05PM +0200, Jann Horn wrote:
> > On Tue, Aug 11, 2026 at 2:16 AM Kees Cook <kees@kernel.org> wrote:
> > > On Mon, Aug 10, 2026 at 08:41:13PM +0000, Bill Wendling wrote:
> > > > +static void fdtable_test_alloc(struct kunit *test)
> > > > +{
> > > > + struct fdtable *fdt;
> > > > + unsigned int slots = 64;
> > > > +
> > > > + fdt = alloc_fdtable(slots);
> > > > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fdt);
> > > > +
> > > > + /* Check that max_fds is set correctly and is >= slots */
> > > > + KUNIT_EXPECT_GE(test, fdt->max_fds, slots);
> > > > +
> > > > + /* Check that fd is allocated */
> > > > + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, fdt->fd);
> > >
> > > Nice to add these tests! Can you add one for each of the conditionals
> > > in alloc_fdtable (e.g. ENOMEM, EMFILE, and the power-of-two rounding-up
> > > logic, etc)?
> >
> > Wouldn't tests for stuff like the rounding-up logic get into
> > implementation details too much, and break if implementation choices
> > change?
>
> It seemed to me like we'd want to notice if that behavior changed?
Why?
File descriptor tables are often power-of-two sized, but they aren't
always. That is an implementation choice that doesn't impact
correctness, it just affects performance somewhat. So I don't see what
the point of a test for this would be - it seems like it would just be
in the way of making changes, a "Change-Detector Test"?
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [PATCH 2/2] vfs: Add KUnit tests for fdtable
2026-08-12 15:06 ` Jann Horn
@ 2026-08-25 12:35 ` Christian Brauner
0 siblings, 0 replies; 16+ messages in thread
From: Christian Brauner @ 2026-08-25 12:35 UTC (permalink / raw)
To: Jann Horn
Cc: Kees Cook, Bill Wendling, codemender-patching+linux,
Alexander Viro, Jan Kara, Gustavo A. R. Silva, linux-kernel,
linux-fsdevel, linux-hardening
On Wed, Aug 12, 2026 at 05:06:37PM +0200, Jann Horn wrote:
> On Wed, Aug 12, 2026 at 2:22 AM Kees Cook <kees@kernel.org> wrote:
> > On Tue, Aug 11, 2026 at 05:42:05PM +0200, Jann Horn wrote:
> > > On Tue, Aug 11, 2026 at 2:16 AM Kees Cook <kees@kernel.org> wrote:
> > > > On Mon, Aug 10, 2026 at 08:41:13PM +0000, Bill Wendling wrote:
> > > > > +static void fdtable_test_alloc(struct kunit *test)
> > > > > +{
> > > > > + struct fdtable *fdt;
> > > > > + unsigned int slots = 64;
> > > > > +
> > > > > + fdt = alloc_fdtable(slots);
> > > > > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fdt);
> > > > > +
> > > > > + /* Check that max_fds is set correctly and is >= slots */
> > > > > + KUNIT_EXPECT_GE(test, fdt->max_fds, slots);
> > > > > +
> > > > > + /* Check that fd is allocated */
> > > > > + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, fdt->fd);
> > > >
> > > > Nice to add these tests! Can you add one for each of the conditionals
> > > > in alloc_fdtable (e.g. ENOMEM, EMFILE, and the power-of-two rounding-up
> > > > logic, etc)?
> > >
> > > Wouldn't tests for stuff like the rounding-up logic get into
> > > implementation details too much, and break if implementation choices
> > > change?
> >
> > It seemed to me like we'd want to notice if that behavior changed?
>
> Why?
> File descriptor tables are often power-of-two sized, but they aren't
> always. That is an implementation choice that doesn't impact
> correctness, it just affects performance somewhat. So I don't see what
> the point of a test for this would be - it seems like it would just be
> in the way of making changes, a "Change-Detector Test"?
Yeah, I don't think this makes much sense.
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 1/2] vfs: Annotate struct fdtable's fd field with __counted_by_ptr
[not found] <20260810204118.1981755-1-morbo@google.com>
2026-08-10 20:41 ` [PATCH 1/2] vfs: Annotate struct fdtable's fd field with __counted_by_ptr Bill Wendling
2026-08-10 20:41 ` [PATCH 2/2] vfs: Add KUnit tests for fdtable Bill Wendling
@ 2026-08-27 4:15 ` Bill Wendling
2026-08-27 4:15 ` [PATCH 2/2] vfs: Add KUnit tests for fdtable Bill Wendling
2026-08-27 4:17 ` [PATCH v3 1/2] vfs: Annotate struct fdtable's fd field with __counted_by_ptr Bill Wendling
3 siblings, 1 reply; 16+ messages in thread
From: Bill Wendling @ 2026-08-27 4:15 UTC (permalink / raw)
Cc: Bill Wendling, Alexander Viro, Christian Brauner, Jan Kara,
Kees Cook, Gustavo A. R. Silva, codemender-patching+linux,
linux-kernel, linux-fsdevel, linux-hardening
The 'struct fdtable' holds the file descriptor table information,
including the current file descriptor array 'fd' and its size 'max_fds'.
To harden the kernel against out-of-bounds accesses, we can annotate the
'fd' pointer field with the '__counted_by_ptr' attribute, referencing
'max_fds'.
The compiler uses the '__counted_by_ptr' attribute to track the
size of the memory allocated for the pointer field, enabling
runtime bounds checks under KASAN and fortified functions. There are
three places where a 'struct fdtable' is initialized, and in all of
them, 'max_fds' is set before the 'fd' pointer is accessed or assigned
in all allocation and initialization places.
No accesses to 'fd' occur before 'max_fds' is set, preventing any
potential runtime false-positives or panics due to uninitialized count
fields.
Assisted-by: Gemini:3.1-pro-preview
Signed-off-by: Bill Wendling <morbo@google.com>
---
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Jan Kara <jack@suse.cz>
Cc: Kees Cook <kees@kernel.org>
Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
Cc: codemender-patching+linux@google.com
Cc: linux-kernel@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-hardening@vger.kernel.org
---
include/linux/fdtable.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h
index c45306a9f007..3a5c88291125 100644
--- a/include/linux/fdtable.h
+++ b/include/linux/fdtable.h
@@ -25,7 +25,7 @@
struct fdtable {
unsigned int max_fds;
- struct file __rcu **fd; /* current fd array */
+ struct file __rcu **fd __counted_by_ptr(max_fds); /* current fd array */
unsigned long *close_on_exec;
unsigned long *open_fds;
unsigned long *full_fds_bits;
--
2.55.0.897.gb25b4bd76c-goog
^ permalink raw reply [flat|nested] 16+ messages in thread* [PATCH 2/2] vfs: Add KUnit tests for fdtable
2026-08-27 4:15 ` [PATCH 1/2] vfs: Annotate struct fdtable's fd field with __counted_by_ptr Bill Wendling
@ 2026-08-27 4:15 ` Bill Wendling
0 siblings, 0 replies; 16+ messages in thread
From: Bill Wendling @ 2026-08-27 4:15 UTC (permalink / raw)
Cc: Bill Wendling, Alexander Viro, Christian Brauner, Jan Kara,
Kees Cook, Gustavo A. R. Silva, codemender-patching+linux,
linux-kernel, linux-fsdevel, linux-hardening
This adds a KUnit test suite for fdtable to verify correct allocation,
max_fds initialization, and dynamic object size of the fd array under
__counted_by_ptr when CONFIG_CC_HAS_COUNTED_BY_PTR is enabled.
Assisted-by: Gemini:3.1-pro-preview
Signed-off-by: Bill Wendling <morbo@google.com>
---
v2 - Added 'test_dup_fd' testcase for separate allocation path.
---
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Jan Kara <jack@suse.cz>
Cc: Kees Cook <kees@kernel.org>
Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
Cc: codemender-patching+linux@google.com
Cc: linux-kernel@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-hardening@vger.kernel.org
---
fs/Kconfig | 8 +++++
fs/file.c | 4 +++
fs/tests/.kunitconfig | 2 ++
fs/tests/fdtable_kunit.c | 72 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 86 insertions(+)
create mode 100644 fs/tests/.kunitconfig
create mode 100644 fs/tests/fdtable_kunit.c
diff --git a/fs/Kconfig b/fs/Kconfig
index e05917adcd60..05b63f7506a7 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -421,4 +421,12 @@ source "fs/unicode/Kconfig"
config IO_WQ
bool
+config FDTABLE_KUNIT_TEST
+ bool "KUnit test for fdtable" if !KUNIT_ALL_TESTS
+ depends on KUNIT=y
+ default KUNIT_ALL_TESTS
+ help
+ This builds the fdtable KUnit tests, which tests various aspects
+ of the fdtable structure and allocation.
+
endmenu
diff --git a/fs/file.c b/fs/file.c
index 628ca07dc4b1..9c7001b901cf 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -1529,3 +1529,7 @@ int iterate_fd(struct files_struct *files, unsigned n,
return res;
}
EXPORT_SYMBOL(iterate_fd);
+
+#ifdef CONFIG_FDTABLE_KUNIT_TEST
+#include "tests/fdtable_kunit.c"
+#endif
diff --git a/fs/tests/.kunitconfig b/fs/tests/.kunitconfig
new file mode 100644
index 000000000000..de67125a9421
--- /dev/null
+++ b/fs/tests/.kunitconfig
@@ -0,0 +1,2 @@
+CONFIG_KUNIT=y
+CONFIG_FDTABLE_KUNIT_TEST=y
diff --git a/fs/tests/fdtable_kunit.c b/fs/tests/fdtable_kunit.c
new file mode 100644
index 000000000000..6abd2a8d8f5d
--- /dev/null
+++ b/fs/tests/fdtable_kunit.c
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <kunit/test.h>
+#include <linux/fdtable.h>
+#include <linux/file.h>
+
+static void test_alloc_fdtable(struct kunit *test)
+{
+ struct fdtable *fdt;
+ unsigned int slots = 64;
+
+ fdt = alloc_fdtable(slots);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fdt);
+
+ /* Check that max_fds is set correctly and is >= slots */
+ KUNIT_EXPECT_GE(test, fdt->max_fds, slots);
+
+ /* Check that fd is allocated */
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fdt->fd);
+
+ /*
+ * Check dynamic object size of fdt->fd if compiler supports
+ * __counted_by_ptr.
+ */
+#ifdef CONFIG_CC_HAS_COUNTED_BY_PTR
+ KUNIT_EXPECT_EQ(test, __builtin_dynamic_object_size(fdt->fd, 0),
+ fdt->max_fds * sizeof(struct file *));
+#endif
+
+ __free_fdtable(fdt);
+}
+
+static void test_dup_fd(struct kunit *test)
+{
+ struct files_struct *newf;
+ struct fdtable *fdt;
+
+ newf = dup_fd(&init_files, NULL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, newf);
+
+ fdt = rcu_dereference_raw(newf->fdt);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fdt);
+
+ /* Check that max_fds is set correctly and is >= NR_OPEN_DEFAULT */
+ KUNIT_EXPECT_GE(test, fdt->max_fds, NR_OPEN_DEFAULT);
+
+ /* Check that fd is allocated */
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fdt->fd);
+
+ /*
+ * Check dynamic object size of fdt->fd if compiler supports
+ * __counted_by_ptr.
+ */
+#ifdef CONFIG_CC_HAS_COUNTED_BY_PTR
+ KUNIT_EXPECT_EQ(test, __builtin_dynamic_object_size(fdt->fd, 0),
+ fdt->max_fds * sizeof(struct file *));
+#endif
+
+ put_files_struct(newf);
+}
+
+static struct kunit_case fdtable_test_cases[] = {
+ KUNIT_CASE(test_alloc_fdtable),
+ KUNIT_CASE(test_dup_fd),
+ {}
+};
+
+static struct kunit_suite fdtable_test_suite = {
+ .name = "fdtable",
+ .test_cases = fdtable_test_cases,
+};
+
+kunit_test_suite(fdtable_test_suite);
--
2.55.0.897.gb25b4bd76c-goog
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v3 1/2] vfs: Annotate struct fdtable's fd field with __counted_by_ptr
[not found] <20260810204118.1981755-1-morbo@google.com>
` (2 preceding siblings ...)
2026-08-27 4:15 ` [PATCH 1/2] vfs: Annotate struct fdtable's fd field with __counted_by_ptr Bill Wendling
@ 2026-08-27 4:17 ` Bill Wendling
2026-08-27 4:17 ` [PATCH v3 2/2] vfs: Add KUnit tests for fdtable Bill Wendling
` (2 more replies)
3 siblings, 3 replies; 16+ messages in thread
From: Bill Wendling @ 2026-08-27 4:17 UTC (permalink / raw)
Cc: Bill Wendling, Alexander Viro, Christian Brauner, Jan Kara,
Kees Cook, Gustavo A. R. Silva, codemender-patching+linux,
linux-kernel, linux-fsdevel, linux-hardening
The 'struct fdtable' holds the file descriptor table information,
including the current file descriptor array 'fd' and its size 'max_fds'.
To harden the kernel against out-of-bounds accesses, we can annotate the
'fd' pointer field with the '__counted_by_ptr' attribute, referencing
'max_fds'.
The compiler uses the '__counted_by_ptr' attribute to track the
size of the memory allocated for the pointer field, enabling
runtime bounds checks under KASAN and fortified functions. There are
three places where a 'struct fdtable' is initialized, and in all of
them, 'max_fds' is set before the 'fd' pointer is accessed or assigned
in all allocation and initialization places.
No accesses to 'fd' occur before 'max_fds' is set, preventing any
potential runtime false-positives or panics due to uninitialized count
fields.
Assisted-by: Gemini:3.1-pro-preview
Signed-off-by: Bill Wendling <morbo@google.com>
---
v3 - Add version to the PATCH subject line
---
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Jan Kara <jack@suse.cz>
Cc: Kees Cook <kees@kernel.org>
Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
Cc: codemender-patching+linux@google.com
Cc: linux-kernel@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-hardening@vger.kernel.org
---
include/linux/fdtable.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h
index c45306a9f007..3a5c88291125 100644
--- a/include/linux/fdtable.h
+++ b/include/linux/fdtable.h
@@ -25,7 +25,7 @@
struct fdtable {
unsigned int max_fds;
- struct file __rcu **fd; /* current fd array */
+ struct file __rcu **fd __counted_by_ptr(max_fds); /* current fd array */
unsigned long *close_on_exec;
unsigned long *open_fds;
unsigned long *full_fds_bits;
--
2.55.0.897.gb25b4bd76c-goog
^ permalink raw reply [flat|nested] 16+ messages in thread* [PATCH v3 2/2] vfs: Add KUnit tests for fdtable
2026-08-27 4:17 ` [PATCH v3 1/2] vfs: Annotate struct fdtable's fd field with __counted_by_ptr Bill Wendling
@ 2026-08-27 4:17 ` Bill Wendling
2026-08-27 11:16 ` Jan Kara
2026-08-27 11:12 ` [PATCH v3 1/2] vfs: Annotate struct fdtable's fd field with __counted_by_ptr Jan Kara
2026-09-10 7:33 ` Christian Brauner
2 siblings, 1 reply; 16+ messages in thread
From: Bill Wendling @ 2026-08-27 4:17 UTC (permalink / raw)
Cc: Bill Wendling, Alexander Viro, Christian Brauner, Jan Kara,
Kees Cook, Gustavo A. R. Silva, codemender-patching+linux,
linux-kernel, linux-fsdevel, linux-hardening
This adds a KUnit test suite for fdtable to verify correct allocation,
max_fds initialization, and dynamic object size of the fd array under
__counted_by_ptr when CONFIG_CC_HAS_COUNTED_BY_PTR is enabled.
Assisted-by: Gemini:3.1-pro-preview
Signed-off-by: Bill Wendling <morbo@google.com>
---
v2 - Added 'test_dup_fd' testcase for separate allocation path.
v3 - Add version to the PATCH subject line
---
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Jan Kara <jack@suse.cz>
Cc: Kees Cook <kees@kernel.org>
Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
Cc: codemender-patching+linux@google.com
Cc: linux-kernel@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-hardening@vger.kernel.org
---
fs/Kconfig | 8 +++++
fs/file.c | 4 +++
fs/tests/.kunitconfig | 2 ++
fs/tests/fdtable_kunit.c | 72 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 86 insertions(+)
create mode 100644 fs/tests/.kunitconfig
create mode 100644 fs/tests/fdtable_kunit.c
diff --git a/fs/Kconfig b/fs/Kconfig
index e05917adcd60..05b63f7506a7 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -421,4 +421,12 @@ source "fs/unicode/Kconfig"
config IO_WQ
bool
+config FDTABLE_KUNIT_TEST
+ bool "KUnit test for fdtable" if !KUNIT_ALL_TESTS
+ depends on KUNIT=y
+ default KUNIT_ALL_TESTS
+ help
+ This builds the fdtable KUnit tests, which tests various aspects
+ of the fdtable structure and allocation.
+
endmenu
diff --git a/fs/file.c b/fs/file.c
index 628ca07dc4b1..9c7001b901cf 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -1529,3 +1529,7 @@ int iterate_fd(struct files_struct *files, unsigned n,
return res;
}
EXPORT_SYMBOL(iterate_fd);
+
+#ifdef CONFIG_FDTABLE_KUNIT_TEST
+#include "tests/fdtable_kunit.c"
+#endif
diff --git a/fs/tests/.kunitconfig b/fs/tests/.kunitconfig
new file mode 100644
index 000000000000..de67125a9421
--- /dev/null
+++ b/fs/tests/.kunitconfig
@@ -0,0 +1,2 @@
+CONFIG_KUNIT=y
+CONFIG_FDTABLE_KUNIT_TEST=y
diff --git a/fs/tests/fdtable_kunit.c b/fs/tests/fdtable_kunit.c
new file mode 100644
index 000000000000..6abd2a8d8f5d
--- /dev/null
+++ b/fs/tests/fdtable_kunit.c
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <kunit/test.h>
+#include <linux/fdtable.h>
+#include <linux/file.h>
+
+static void test_alloc_fdtable(struct kunit *test)
+{
+ struct fdtable *fdt;
+ unsigned int slots = 64;
+
+ fdt = alloc_fdtable(slots);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fdt);
+
+ /* Check that max_fds is set correctly and is >= slots */
+ KUNIT_EXPECT_GE(test, fdt->max_fds, slots);
+
+ /* Check that fd is allocated */
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fdt->fd);
+
+ /*
+ * Check dynamic object size of fdt->fd if compiler supports
+ * __counted_by_ptr.
+ */
+#ifdef CONFIG_CC_HAS_COUNTED_BY_PTR
+ KUNIT_EXPECT_EQ(test, __builtin_dynamic_object_size(fdt->fd, 0),
+ fdt->max_fds * sizeof(struct file *));
+#endif
+
+ __free_fdtable(fdt);
+}
+
+static void test_dup_fd(struct kunit *test)
+{
+ struct files_struct *newf;
+ struct fdtable *fdt;
+
+ newf = dup_fd(&init_files, NULL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, newf);
+
+ fdt = rcu_dereference_raw(newf->fdt);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fdt);
+
+ /* Check that max_fds is set correctly and is >= NR_OPEN_DEFAULT */
+ KUNIT_EXPECT_GE(test, fdt->max_fds, NR_OPEN_DEFAULT);
+
+ /* Check that fd is allocated */
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fdt->fd);
+
+ /*
+ * Check dynamic object size of fdt->fd if compiler supports
+ * __counted_by_ptr.
+ */
+#ifdef CONFIG_CC_HAS_COUNTED_BY_PTR
+ KUNIT_EXPECT_EQ(test, __builtin_dynamic_object_size(fdt->fd, 0),
+ fdt->max_fds * sizeof(struct file *));
+#endif
+
+ put_files_struct(newf);
+}
+
+static struct kunit_case fdtable_test_cases[] = {
+ KUNIT_CASE(test_alloc_fdtable),
+ KUNIT_CASE(test_dup_fd),
+ {}
+};
+
+static struct kunit_suite fdtable_test_suite = {
+ .name = "fdtable",
+ .test_cases = fdtable_test_cases,
+};
+
+kunit_test_suite(fdtable_test_suite);
--
2.55.0.897.gb25b4bd76c-goog
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [PATCH v3 2/2] vfs: Add KUnit tests for fdtable
2026-08-27 4:17 ` [PATCH v3 2/2] vfs: Add KUnit tests for fdtable Bill Wendling
@ 2026-08-27 11:16 ` Jan Kara
0 siblings, 0 replies; 16+ messages in thread
From: Jan Kara @ 2026-08-27 11:16 UTC (permalink / raw)
To: Bill Wendling
Cc: Alexander Viro, Christian Brauner, Jan Kara, Kees Cook,
Gustavo A. R. Silva, codemender-patching+linux, linux-kernel,
linux-fsdevel, linux-hardening
On Thu 27-08-26 04:17:30, Bill Wendling wrote:
> This adds a KUnit test suite for fdtable to verify correct allocation,
> max_fds initialization, and dynamic object size of the fd array under
> __counted_by_ptr when CONFIG_CC_HAS_COUNTED_BY_PTR is enabled.
>
> Assisted-by: Gemini:3.1-pro-preview
> Signed-off-by: Bill Wendling <morbo@google.com>
Looks sensible. Feel free to add:
Reviewed-by: Jan Kara <jack@suse.cz>
Honza
> ---
> v2 - Added 'test_dup_fd' testcase for separate allocation path.
> v3 - Add version to the PATCH subject line
> ---
> Cc: Alexander Viro <viro@zeniv.linux.org.uk>
> Cc: Christian Brauner <brauner@kernel.org>
> Cc: Jan Kara <jack@suse.cz>
> Cc: Kees Cook <kees@kernel.org>
> Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
> Cc: codemender-patching+linux@google.com
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-fsdevel@vger.kernel.org
> Cc: linux-hardening@vger.kernel.org
> ---
> fs/Kconfig | 8 +++++
> fs/file.c | 4 +++
> fs/tests/.kunitconfig | 2 ++
> fs/tests/fdtable_kunit.c | 72 ++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 86 insertions(+)
> create mode 100644 fs/tests/.kunitconfig
> create mode 100644 fs/tests/fdtable_kunit.c
>
> diff --git a/fs/Kconfig b/fs/Kconfig
> index e05917adcd60..05b63f7506a7 100644
> --- a/fs/Kconfig
> +++ b/fs/Kconfig
> @@ -421,4 +421,12 @@ source "fs/unicode/Kconfig"
> config IO_WQ
> bool
>
> +config FDTABLE_KUNIT_TEST
> + bool "KUnit test for fdtable" if !KUNIT_ALL_TESTS
> + depends on KUNIT=y
> + default KUNIT_ALL_TESTS
> + help
> + This builds the fdtable KUnit tests, which tests various aspects
> + of the fdtable structure and allocation.
> +
> endmenu
> diff --git a/fs/file.c b/fs/file.c
> index 628ca07dc4b1..9c7001b901cf 100644
> --- a/fs/file.c
> +++ b/fs/file.c
> @@ -1529,3 +1529,7 @@ int iterate_fd(struct files_struct *files, unsigned n,
> return res;
> }
> EXPORT_SYMBOL(iterate_fd);
> +
> +#ifdef CONFIG_FDTABLE_KUNIT_TEST
> +#include "tests/fdtable_kunit.c"
> +#endif
> diff --git a/fs/tests/.kunitconfig b/fs/tests/.kunitconfig
> new file mode 100644
> index 000000000000..de67125a9421
> --- /dev/null
> +++ b/fs/tests/.kunitconfig
> @@ -0,0 +1,2 @@
> +CONFIG_KUNIT=y
> +CONFIG_FDTABLE_KUNIT_TEST=y
> diff --git a/fs/tests/fdtable_kunit.c b/fs/tests/fdtable_kunit.c
> new file mode 100644
> index 000000000000..6abd2a8d8f5d
> --- /dev/null
> +++ b/fs/tests/fdtable_kunit.c
> @@ -0,0 +1,72 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +#include <kunit/test.h>
> +#include <linux/fdtable.h>
> +#include <linux/file.h>
> +
> +static void test_alloc_fdtable(struct kunit *test)
> +{
> + struct fdtable *fdt;
> + unsigned int slots = 64;
> +
> + fdt = alloc_fdtable(slots);
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fdt);
> +
> + /* Check that max_fds is set correctly and is >= slots */
> + KUNIT_EXPECT_GE(test, fdt->max_fds, slots);
> +
> + /* Check that fd is allocated */
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fdt->fd);
> +
> + /*
> + * Check dynamic object size of fdt->fd if compiler supports
> + * __counted_by_ptr.
> + */
> +#ifdef CONFIG_CC_HAS_COUNTED_BY_PTR
> + KUNIT_EXPECT_EQ(test, __builtin_dynamic_object_size(fdt->fd, 0),
> + fdt->max_fds * sizeof(struct file *));
> +#endif
> +
> + __free_fdtable(fdt);
> +}
> +
> +static void test_dup_fd(struct kunit *test)
> +{
> + struct files_struct *newf;
> + struct fdtable *fdt;
> +
> + newf = dup_fd(&init_files, NULL);
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, newf);
> +
> + fdt = rcu_dereference_raw(newf->fdt);
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fdt);
> +
> + /* Check that max_fds is set correctly and is >= NR_OPEN_DEFAULT */
> + KUNIT_EXPECT_GE(test, fdt->max_fds, NR_OPEN_DEFAULT);
> +
> + /* Check that fd is allocated */
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fdt->fd);
> +
> + /*
> + * Check dynamic object size of fdt->fd if compiler supports
> + * __counted_by_ptr.
> + */
> +#ifdef CONFIG_CC_HAS_COUNTED_BY_PTR
> + KUNIT_EXPECT_EQ(test, __builtin_dynamic_object_size(fdt->fd, 0),
> + fdt->max_fds * sizeof(struct file *));
> +#endif
> +
> + put_files_struct(newf);
> +}
> +
> +static struct kunit_case fdtable_test_cases[] = {
> + KUNIT_CASE(test_alloc_fdtable),
> + KUNIT_CASE(test_dup_fd),
> + {}
> +};
> +
> +static struct kunit_suite fdtable_test_suite = {
> + .name = "fdtable",
> + .test_cases = fdtable_test_cases,
> +};
> +
> +kunit_test_suite(fdtable_test_suite);
> --
> 2.55.0.897.gb25b4bd76c-goog
>
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v3 1/2] vfs: Annotate struct fdtable's fd field with __counted_by_ptr
2026-08-27 4:17 ` [PATCH v3 1/2] vfs: Annotate struct fdtable's fd field with __counted_by_ptr Bill Wendling
2026-08-27 4:17 ` [PATCH v3 2/2] vfs: Add KUnit tests for fdtable Bill Wendling
@ 2026-08-27 11:12 ` Jan Kara
2026-09-10 7:33 ` Christian Brauner
2 siblings, 0 replies; 16+ messages in thread
From: Jan Kara @ 2026-08-27 11:12 UTC (permalink / raw)
To: Bill Wendling
Cc: Alexander Viro, Christian Brauner, Jan Kara, Kees Cook,
Gustavo A. R. Silva, codemender-patching+linux, linux-kernel,
linux-fsdevel, linux-hardening
On Thu 27-08-26 04:17:29, Bill Wendling wrote:
> The 'struct fdtable' holds the file descriptor table information,
> including the current file descriptor array 'fd' and its size 'max_fds'.
> To harden the kernel against out-of-bounds accesses, we can annotate the
> 'fd' pointer field with the '__counted_by_ptr' attribute, referencing
> 'max_fds'.
>
> The compiler uses the '__counted_by_ptr' attribute to track the
> size of the memory allocated for the pointer field, enabling
> runtime bounds checks under KASAN and fortified functions. There are
> three places where a 'struct fdtable' is initialized, and in all of
> them, 'max_fds' is set before the 'fd' pointer is accessed or assigned
> in all allocation and initialization places.
>
> No accesses to 'fd' occur before 'max_fds' is set, preventing any
> potential runtime false-positives or panics due to uninitialized count
> fields.
>
> Assisted-by: Gemini:3.1-pro-preview
> Signed-off-by: Bill Wendling <morbo@google.com>
Looks good. Feel free to add:
Reviewed-by: Jan Kara <jack@suse.cz>
Honza
> ---
> v3 - Add version to the PATCH subject line
> ---
> Cc: Alexander Viro <viro@zeniv.linux.org.uk>
> Cc: Christian Brauner <brauner@kernel.org>
> Cc: Jan Kara <jack@suse.cz>
> Cc: Kees Cook <kees@kernel.org>
> Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
> Cc: codemender-patching+linux@google.com
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-fsdevel@vger.kernel.org
> Cc: linux-hardening@vger.kernel.org
> ---
> include/linux/fdtable.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h
> index c45306a9f007..3a5c88291125 100644
> --- a/include/linux/fdtable.h
> +++ b/include/linux/fdtable.h
> @@ -25,7 +25,7 @@
>
> struct fdtable {
> unsigned int max_fds;
> - struct file __rcu **fd; /* current fd array */
> + struct file __rcu **fd __counted_by_ptr(max_fds); /* current fd array */
> unsigned long *close_on_exec;
> unsigned long *open_fds;
> unsigned long *full_fds_bits;
> --
> 2.55.0.897.gb25b4bd76c-goog
>
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [PATCH v3 1/2] vfs: Annotate struct fdtable's fd field with __counted_by_ptr
2026-08-27 4:17 ` [PATCH v3 1/2] vfs: Annotate struct fdtable's fd field with __counted_by_ptr Bill Wendling
2026-08-27 4:17 ` [PATCH v3 2/2] vfs: Add KUnit tests for fdtable Bill Wendling
2026-08-27 11:12 ` [PATCH v3 1/2] vfs: Annotate struct fdtable's fd field with __counted_by_ptr Jan Kara
@ 2026-09-10 7:33 ` Christian Brauner
2 siblings, 0 replies; 16+ messages in thread
From: Christian Brauner @ 2026-09-10 7:33 UTC (permalink / raw)
To: Bill Wendling
Cc: Alexander Viro, Jan Kara, Kees Cook, Gustavo A. R. Silva,
codemender-patching+linux, linux-kernel, linux-fsdevel,
linux-hardening
On Thu, 27 Aug 2026 04:17:29 +0000, Bill Wendling wrote:
> vfs: Annotate struct fdtable's fd field with __counted_by_ptr
Applied to the vfs-7.4.file branch of the vfs/vfs.git tree.
Patches in the vfs-7.4.file branch should appear in linux-next soon.
Please report any outstanding bugs that were missed during review in a
new review to the original patch series allowing us to drop it.
It's encouraged to provide Acked-bys and Reviewed-bys even though the
patch has now been applied. If possible patch trailers will be updated.
Note that commit hashes shown below are subject to change due to rebase,
trailer updates or similar. If in doubt, please check the listed branch.
tree: https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git
branch: vfs-7.4.file
[1/2] vfs: Annotate struct fdtable's fd field with __counted_by_ptr
https://git.kernel.org/vfs/vfs/c/b4db97b9ef46
[2/2] vfs: Add KUnit tests for fdtable
https://git.kernel.org/vfs/vfs/c/501cbbd276b7
^ permalink raw reply [flat|nested] 16+ messages in thread