linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [RFC] slab: introduce auto_kfree macro
@ 2025-04-01 13:44 Przemek Kitszel
  2025-04-02 10:32 ` Andy Shevchenko
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Przemek Kitszel @ 2025-04-01 13:44 UTC (permalink / raw)
  To: linux-kernel, linux-mm, vbabka, torvalds, peterz
  Cc: andriy.shevchenko, intel-wired-lan, netdev, Przemek Kitszel

Add auto_kfree macro that acts as a higher level wrapper for manual
__free(kfree) invocation, and sets the pointer to NULL - to have both
well defined behavior also for the case code would lack other assignement.

Consider the following code:
int my_foo(int arg)
{
	struct my_dev_foo *foo __free(kfree); /* no assignement */

	foo = kzalloc(sizeof(*foo), GFP_KERNEL);
	/* ... */
}

So far it is fine and even optimal in terms of not assigning when
not needed. But it is typical to don't touch (and sadly to don't
think about) code that is not related to the change, so let's consider
an extension to the above, namely an "early return" style to check
arg prior to allocation:
int my_foo(int arg)
{
        struct my_dev_foo *foo __free(kfree); /* no assignement */
+
+	if (!arg)
+		return -EINVAL;
        foo = kzalloc(sizeof(*foo), GFP_KERNEL);
        /* ... */
}
Now we have uninitialized foo passed to kfree, what likely will crash.
One could argue that `= NULL` should be added to this patch, but it is
easy to forgot, especially when the foo declaration is outside of the
default git context.

With new auto_kfree, we simply will start with
	struct my_dev_foo *foo auto_kfree;
and be safe against future extensions.

I believe this will open up way for broader adoption of Scope Based
Resource Management, say in networking.
I also believe that my proposed name is special enough that it will
be easy to know/spot that the assignement is hidden.

Signed-off-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
---
 include/linux/slab.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/slab.h b/include/linux/slab.h
index 98e07e9e9e58..b943be0ce626 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -471,6 +471,7 @@ void kfree_sensitive(const void *objp);
 size_t __ksize(const void *objp);
 
 DEFINE_FREE(kfree, void *, if (!IS_ERR_OR_NULL(_T)) kfree(_T))
+#define auto_kfree __free(kfree) = NULL
 DEFINE_FREE(kfree_sensitive, void *, if (_T) kfree_sensitive(_T))
 
 /**
-- 
2.39.3



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC] slab: introduce auto_kfree macro
  2025-04-01 13:44 [RFC] slab: introduce auto_kfree macro Przemek Kitszel
@ 2025-04-02 10:32 ` Andy Shevchenko
  2025-04-02 10:40   ` Andy Shevchenko
                     ` (2 more replies)
  2025-04-02 10:44 ` Vlastimil Babka
  2025-04-03 18:15 ` Linus Torvalds
  2 siblings, 3 replies; 14+ messages in thread
From: Andy Shevchenko @ 2025-04-02 10:32 UTC (permalink / raw)
  To: Przemek Kitszel
  Cc: linux-kernel, linux-mm, vbabka, torvalds, peterz,
	intel-wired-lan, netdev

On Tue, Apr 01, 2025 at 03:44:08PM +0200, Przemek Kitszel wrote:
> Add auto_kfree macro that acts as a higher level wrapper for manual
> __free(kfree) invocation, and sets the pointer to NULL - to have both
> well defined behavior also for the case code would lack other assignement.
> 
> Consider the following code:
> int my_foo(int arg)
> {
> 	struct my_dev_foo *foo __free(kfree); /* no assignement */
> 
> 	foo = kzalloc(sizeof(*foo), GFP_KERNEL);
> 	/* ... */
> }
> 
> So far it is fine and even optimal in terms of not assigning when
> not needed. But it is typical to don't touch (and sadly to don't
> think about) code that is not related to the change, so let's consider
> an extension to the above, namely an "early return" style to check
> arg prior to allocation:
> int my_foo(int arg)
> {
>         struct my_dev_foo *foo __free(kfree); /* no assignement */
> +
> +	if (!arg)
> +		return -EINVAL;
>         foo = kzalloc(sizeof(*foo), GFP_KERNEL);
>         /* ... */
> }
> Now we have uninitialized foo passed to kfree, what likely will crash.
> One could argue that `= NULL` should be added to this patch, but it is
> easy to forgot, especially when the foo declaration is outside of the
> default git context.
> 
> With new auto_kfree, we simply will start with
> 	struct my_dev_foo *foo auto_kfree;
> and be safe against future extensions.
> 
> I believe this will open up way for broader adoption of Scope Based
> Resource Management, say in networking.
> I also believe that my proposed name is special enough that it will
> be easy to know/spot that the assignement is hidden.


I understand the issue and the problem it solves, but...

> +#define auto_kfree __free(kfree) = NULL

...I do not like this syntax at all (note, you forgot to show the result
in the code how it will look like).

What would be better in my opinion is to have it something like DEFINE_*()
type, which will look more naturally in the current kernel codebase
(as we have tons of DEFINE_FOO().

	DEFINE_AUTO_KFREE_VAR(name, struct foo);

with equivalent to

	struct foo *name __free(kfree) = NULL

-- 
With Best Regards,
Andy Shevchenko




^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC] slab: introduce auto_kfree macro
  2025-04-02 10:32 ` Andy Shevchenko
@ 2025-04-02 10:40   ` Andy Shevchenko
  2025-04-02 12:19   ` Peter Zijlstra
  2025-04-02 12:21   ` Peter Zijlstra
  2 siblings, 0 replies; 14+ messages in thread
From: Andy Shevchenko @ 2025-04-02 10:40 UTC (permalink / raw)
  To: Przemek Kitszel
  Cc: linux-kernel, linux-mm, vbabka, torvalds, peterz,
	intel-wired-lan, netdev

On Wed, Apr 02, 2025 at 01:32:52PM +0300, Andy Shevchenko wrote:
> On Tue, Apr 01, 2025 at 03:44:08PM +0200, Przemek Kitszel wrote:
> > Add auto_kfree macro that acts as a higher level wrapper for manual
> > __free(kfree) invocation, and sets the pointer to NULL - to have both
> > well defined behavior also for the case code would lack other assignement.
> > 
> > Consider the following code:
> > int my_foo(int arg)
> > {
> > 	struct my_dev_foo *foo __free(kfree); /* no assignement */
> > 
> > 	foo = kzalloc(sizeof(*foo), GFP_KERNEL);
> > 	/* ... */
> > }
> > 
> > So far it is fine and even optimal in terms of not assigning when
> > not needed. But it is typical to don't touch (and sadly to don't
> > think about) code that is not related to the change, so let's consider
> > an extension to the above, namely an "early return" style to check
> > arg prior to allocation:
> > int my_foo(int arg)
> > {
> >         struct my_dev_foo *foo __free(kfree); /* no assignement */
> > +
> > +	if (!arg)
> > +		return -EINVAL;
> >         foo = kzalloc(sizeof(*foo), GFP_KERNEL);
> >         /* ... */
> > }
> > Now we have uninitialized foo passed to kfree, what likely will crash.
> > One could argue that `= NULL` should be added to this patch, but it is
> > easy to forgot, especially when the foo declaration is outside of the
> > default git context.
> > 
> > With new auto_kfree, we simply will start with
> > 	struct my_dev_foo *foo auto_kfree;
> > and be safe against future extensions.
> > 
> > I believe this will open up way for broader adoption of Scope Based
> > Resource Management, say in networking.
> > I also believe that my proposed name is special enough that it will
> > be easy to know/spot that the assignement is hidden.
> 
> 
> I understand the issue and the problem it solves, but...
> 
> > +#define auto_kfree __free(kfree) = NULL
> 
> ...I do not like this syntax at all (note, you forgot to show the result
> in the code how it will look like).
> 
> What would be better in my opinion is to have it something like DEFINE_*()
> type, which will look more naturally in the current kernel codebase
> (as we have tons of DEFINE_FOO().
> 
> 	DEFINE_AUTO_KFREE_VAR(name, struct foo);

Maybe slightly better name is

	DEFINE_AUTO_KFREE_PTR()

as we expect this to be a pointer.

> with equivalent to
> 
> 	struct foo *name __free(kfree) = NULL

-- 
With Best Regards,
Andy Shevchenko




^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC] slab: introduce auto_kfree macro
  2025-04-01 13:44 [RFC] slab: introduce auto_kfree macro Przemek Kitszel
  2025-04-02 10:32 ` Andy Shevchenko
@ 2025-04-02 10:44 ` Vlastimil Babka
  2025-04-03 16:59   ` Kees Cook
  2025-04-03 18:15 ` Linus Torvalds
  2 siblings, 1 reply; 14+ messages in thread
From: Vlastimil Babka @ 2025-04-02 10:44 UTC (permalink / raw)
  To: Przemek Kitszel, linux-kernel, linux-mm, torvalds, peterz,
	Kees Cook, Jann Horn
  Cc: andriy.shevchenko, intel-wired-lan, netdev, Harry Yoo,
	Matthew Wilcox, Christoph Lameter

Cc Kees and others from his related efforts:

https://lore.kernel.org/all/20250321202620.work.175-kees@kernel.org/

On 4/1/25 15:44, Przemek Kitszel wrote:
> Add auto_kfree macro that acts as a higher level wrapper for manual
> __free(kfree) invocation, and sets the pointer to NULL - to have both
> well defined behavior also for the case code would lack other assignement.
> 
> Consider the following code:
> int my_foo(int arg)
> {
> 	struct my_dev_foo *foo __free(kfree); /* no assignement */
> 
> 	foo = kzalloc(sizeof(*foo), GFP_KERNEL);
> 	/* ... */
> }
> 
> So far it is fine and even optimal in terms of not assigning when
> not needed. But it is typical to don't touch (and sadly to don't
> think about) code that is not related to the change, so let's consider
> an extension to the above, namely an "early return" style to check
> arg prior to allocation:
> int my_foo(int arg)
> {
>         struct my_dev_foo *foo __free(kfree); /* no assignement */
> +
> +	if (!arg)
> +		return -EINVAL;
>         foo = kzalloc(sizeof(*foo), GFP_KERNEL);
>         /* ... */
> }
> Now we have uninitialized foo passed to kfree, what likely will crash.
> One could argue that `= NULL` should be added to this patch, but it is
> easy to forgot, especially when the foo declaration is outside of the
> default git context.
> 
> With new auto_kfree, we simply will start with
> 	struct my_dev_foo *foo auto_kfree;
> and be safe against future extensions.
> 
> I believe this will open up way for broader adoption of Scope Based
> Resource Management, say in networking.
> I also believe that my proposed name is special enough that it will
> be easy to know/spot that the assignement is hidden.
> 
> Signed-off-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
> ---
>  include/linux/slab.h | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/include/linux/slab.h b/include/linux/slab.h
> index 98e07e9e9e58..b943be0ce626 100644
> --- a/include/linux/slab.h
> +++ b/include/linux/slab.h
> @@ -471,6 +471,7 @@ void kfree_sensitive(const void *objp);
>  size_t __ksize(const void *objp);
>  
>  DEFINE_FREE(kfree, void *, if (!IS_ERR_OR_NULL(_T)) kfree(_T))
> +#define auto_kfree __free(kfree) = NULL
>  DEFINE_FREE(kfree_sensitive, void *, if (_T) kfree_sensitive(_T))
>  
>  /**



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC] slab: introduce auto_kfree macro
  2025-04-02 10:32 ` Andy Shevchenko
  2025-04-02 10:40   ` Andy Shevchenko
@ 2025-04-02 12:19   ` Peter Zijlstra
  2025-04-02 12:22     ` Peter Zijlstra
  2025-04-04  3:05     ` Herbert Xu
  2025-04-02 12:21   ` Peter Zijlstra
  2 siblings, 2 replies; 14+ messages in thread
From: Peter Zijlstra @ 2025-04-02 12:19 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Przemek Kitszel, linux-kernel, linux-mm, vbabka, torvalds,
	intel-wired-lan, netdev, linux-toolchains

On Wed, Apr 02, 2025 at 01:32:51PM +0300, Andy Shevchenko wrote:
> On Tue, Apr 01, 2025 at 03:44:08PM +0200, Przemek Kitszel wrote:
> > Add auto_kfree macro that acts as a higher level wrapper for manual
> > __free(kfree) invocation, and sets the pointer to NULL - to have both
> > well defined behavior also for the case code would lack other assignement.
> > 
> > Consider the following code:
> > int my_foo(int arg)
> > {
> > 	struct my_dev_foo *foo __free(kfree); /* no assignement */
> > 
> > 	foo = kzalloc(sizeof(*foo), GFP_KERNEL);
> > 	/* ... */
> > }
> > 
> > So far it is fine and even optimal in terms of not assigning when
> > not needed. But it is typical to don't touch (and sadly to don't
> > think about) code that is not related to the change, so let's consider
> > an extension to the above, namely an "early return" style to check
> > arg prior to allocation:
> > int my_foo(int arg)
> > {
> >         struct my_dev_foo *foo __free(kfree); /* no assignement */
> > +
> > +	if (!arg)
> > +		return -EINVAL;
> >         foo = kzalloc(sizeof(*foo), GFP_KERNEL);
> >         /* ... */
> > }
> > Now we have uninitialized foo passed to kfree, what likely will crash.
> > One could argue that `= NULL` should be added to this patch, but it is
> > easy to forgot, especially when the foo declaration is outside of the
> > default git context.

The compiler *should* complain. But neither GCC nor clang actually
appear to warn in this case.

I don't think we should be making dodgy macros like you propose to work
around this compiler deficiency. Instead I would argue we ought to get
both compilers fixed asap, and then none of this will be needed.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC] slab: introduce auto_kfree macro
  2025-04-02 10:32 ` Andy Shevchenko
  2025-04-02 10:40   ` Andy Shevchenko
  2025-04-02 12:19   ` Peter Zijlstra
@ 2025-04-02 12:21   ` Peter Zijlstra
  2025-04-02 12:55     ` Andy Shevchenko
  2 siblings, 1 reply; 14+ messages in thread
From: Peter Zijlstra @ 2025-04-02 12:21 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Przemek Kitszel, linux-kernel, linux-mm, vbabka, torvalds,
	intel-wired-lan, netdev

On Wed, Apr 02, 2025 at 01:32:51PM +0300, Andy Shevchenko wrote:
> What would be better in my opinion is to have it something like DEFINE_*()
> type, which will look more naturally in the current kernel codebase
> (as we have tons of DEFINE_FOO().
> 
> 	DEFINE_AUTO_KFREE_VAR(name, struct foo);

Still weird. Much better to have the compiler complain about the
obvious use of uninitialized.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC] slab: introduce auto_kfree macro
  2025-04-02 12:19   ` Peter Zijlstra
@ 2025-04-02 12:22     ` Peter Zijlstra
  2025-04-02 12:57       ` Andy Shevchenko
  2025-04-04  3:05     ` Herbert Xu
  1 sibling, 1 reply; 14+ messages in thread
From: Peter Zijlstra @ 2025-04-02 12:22 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Przemek Kitszel, linux-kernel, linux-mm, vbabka, torvalds,
	intel-wired-lan, netdev, linux-toolchains

On Wed, Apr 02, 2025 at 02:19:35PM +0200, Peter Zijlstra wrote:
> On Wed, Apr 02, 2025 at 01:32:51PM +0300, Andy Shevchenko wrote:
> > On Tue, Apr 01, 2025 at 03:44:08PM +0200, Przemek Kitszel wrote:
> > > Add auto_kfree macro that acts as a higher level wrapper for manual
> > > __free(kfree) invocation, and sets the pointer to NULL - to have both
> > > well defined behavior also for the case code would lack other assignement.
> > > 
> > > Consider the following code:
> > > int my_foo(int arg)
> > > {
> > > 	struct my_dev_foo *foo __free(kfree); /* no assignement */
> > > 
> > > 	foo = kzalloc(sizeof(*foo), GFP_KERNEL);
> > > 	/* ... */
> > > }
> > > 
> > > So far it is fine and even optimal in terms of not assigning when
> > > not needed. But it is typical to don't touch (and sadly to don't
> > > think about) code that is not related to the change, so let's consider
> > > an extension to the above, namely an "early return" style to check
> > > arg prior to allocation:
> > > int my_foo(int arg)
> > > {
> > >         struct my_dev_foo *foo __free(kfree); /* no assignement */
> > > +
> > > +	if (!arg)
> > > +		return -EINVAL;
> > >         foo = kzalloc(sizeof(*foo), GFP_KERNEL);
> > >         /* ... */
> > > }
> > > Now we have uninitialized foo passed to kfree, what likely will crash.
> > > One could argue that `= NULL` should be added to this patch, but it is
> > > easy to forgot, especially when the foo declaration is outside of the
> > > default git context.
> 
> The compiler *should* complain. But neither GCC nor clang actually
> appear to warn in this case.
> 
> I don't think we should be making dodgy macros like you propose to work
> around this compiler deficiency. Instead I would argue we ought to get
> both compilers fixed asap, and then none of this will be needed.

Ah, I think the problem is that the cleanup function takes a pointer to
the object, and pointers to uninitialized values are generally
considered okay.

The compilers would have to explicitly disallow this for the cleanup
functions.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC] slab: introduce auto_kfree macro
  2025-04-02 12:21   ` Peter Zijlstra
@ 2025-04-02 12:55     ` Andy Shevchenko
  0 siblings, 0 replies; 14+ messages in thread
From: Andy Shevchenko @ 2025-04-02 12:55 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Przemek Kitszel, linux-kernel, linux-mm, vbabka, torvalds,
	intel-wired-lan, netdev

On Wed, Apr 02, 2025 at 02:21:04PM +0200, Peter Zijlstra wrote:
> On Wed, Apr 02, 2025 at 01:32:51PM +0300, Andy Shevchenko wrote:
> > What would be better in my opinion is to have it something like DEFINE_*()
> > type, which will look more naturally in the current kernel codebase
> > (as we have tons of DEFINE_FOO().
> > 
> > 	DEFINE_AUTO_KFREE_VAR(name, struct foo);
> 
> Still weird. Much better to have the compiler complain about the
> obvious use of uninitialized.

That would be ideal!

-- 
With Best Regards,
Andy Shevchenko




^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC] slab: introduce auto_kfree macro
  2025-04-02 12:22     ` Peter Zijlstra
@ 2025-04-02 12:57       ` Andy Shevchenko
  0 siblings, 0 replies; 14+ messages in thread
From: Andy Shevchenko @ 2025-04-02 12:57 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Przemek Kitszel, linux-kernel, linux-mm, vbabka, torvalds,
	intel-wired-lan, netdev, linux-toolchains

On Wed, Apr 02, 2025 at 02:22:24PM +0200, Peter Zijlstra wrote:
> On Wed, Apr 02, 2025 at 02:19:35PM +0200, Peter Zijlstra wrote:
> > On Wed, Apr 02, 2025 at 01:32:51PM +0300, Andy Shevchenko wrote:
> > > On Tue, Apr 01, 2025 at 03:44:08PM +0200, Przemek Kitszel wrote:
> > > > Add auto_kfree macro that acts as a higher level wrapper for manual
> > > > __free(kfree) invocation, and sets the pointer to NULL - to have both
> > > > well defined behavior also for the case code would lack other assignement.
> > > > 
> > > > Consider the following code:
> > > > int my_foo(int arg)
> > > > {
> > > > 	struct my_dev_foo *foo __free(kfree); /* no assignement */
> > > > 
> > > > 	foo = kzalloc(sizeof(*foo), GFP_KERNEL);
> > > > 	/* ... */
> > > > }
> > > > 
> > > > So far it is fine and even optimal in terms of not assigning when
> > > > not needed. But it is typical to don't touch (and sadly to don't
> > > > think about) code that is not related to the change, so let's consider
> > > > an extension to the above, namely an "early return" style to check
> > > > arg prior to allocation:
> > > > int my_foo(int arg)
> > > > {
> > > >         struct my_dev_foo *foo __free(kfree); /* no assignement */
> > > > +
> > > > +	if (!arg)
> > > > +		return -EINVAL;
> > > >         foo = kzalloc(sizeof(*foo), GFP_KERNEL);
> > > >         /* ... */
> > > > }
> > > > Now we have uninitialized foo passed to kfree, what likely will crash.
> > > > One could argue that `= NULL` should be added to this patch, but it is
> > > > easy to forgot, especially when the foo declaration is outside of the
> > > > default git context.
> > 
> > The compiler *should* complain. But neither GCC nor clang actually
> > appear to warn in this case.
> > 
> > I don't think we should be making dodgy macros like you propose to work
> > around this compiler deficiency. Instead I would argue we ought to get
> > both compilers fixed asap, and then none of this will be needed.
> 
> Ah, I think the problem is that the cleanup function takes a pointer to
> the object, and pointers to uninitialized values are generally
> considered okay.
> 
> The compilers would have to explicitly disallow this for the cleanup
> functions.

Hmm... What I have heard is that the cleanup is basically a port of
C++ destructor code to C, and it might be related to the virtual functions
that are may be absent for the basic classes. But not an expert here,
just speculating based on my poor knowledge of C++.

-- 
With Best Regards,
Andy Shevchenko




^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC] slab: introduce auto_kfree macro
  2025-04-02 10:44 ` Vlastimil Babka
@ 2025-04-03 16:59   ` Kees Cook
  2025-04-03 17:35     ` Matthew Wilcox
  0 siblings, 1 reply; 14+ messages in thread
From: Kees Cook @ 2025-04-03 16:59 UTC (permalink / raw)
  To: Vlastimil Babka
  Cc: Przemek Kitszel, linux-kernel, linux-mm, torvalds, peterz,
	Jann Horn, andriy.shevchenko, intel-wired-lan, netdev, Harry Yoo,
	Matthew Wilcox, Christoph Lameter

On Wed, Apr 02, 2025 at 12:44:50PM +0200, Vlastimil Babka wrote:
> Cc Kees and others from his related efforts:
> 
> https://lore.kernel.org/all/20250321202620.work.175-kees@kernel.org/

I think, unfortunately, the consensus is that "invisible side-effects"
are not going to be tolerated. After I finish with kmalloc_obj(), I'd
like to take another run at this for basically providing something like:

static inline __must_check
void *kfree(void *p) { __kfree(p); return NULL; }

And then switch all:

	kfree(s->ptr);

to

	s->ptr = kfree(s->ptr);

Where s->ptr isn't used again.

-Kees

> 
> On 4/1/25 15:44, Przemek Kitszel wrote:
> > Add auto_kfree macro that acts as a higher level wrapper for manual
> > __free(kfree) invocation, and sets the pointer to NULL - to have both
> > well defined behavior also for the case code would lack other assignement.
> > 
> > Consider the following code:
> > int my_foo(int arg)
> > {
> > 	struct my_dev_foo *foo __free(kfree); /* no assignement */
> > 
> > 	foo = kzalloc(sizeof(*foo), GFP_KERNEL);
> > 	/* ... */
> > }
> > 
> > So far it is fine and even optimal in terms of not assigning when
> > not needed. But it is typical to don't touch (and sadly to don't
> > think about) code that is not related to the change, so let's consider
> > an extension to the above, namely an "early return" style to check
> > arg prior to allocation:
> > int my_foo(int arg)
> > {
> >         struct my_dev_foo *foo __free(kfree); /* no assignement */
> > +
> > +	if (!arg)
> > +		return -EINVAL;
> >         foo = kzalloc(sizeof(*foo), GFP_KERNEL);
> >         /* ... */
> > }
> > Now we have uninitialized foo passed to kfree, what likely will crash.
> > One could argue that `= NULL` should be added to this patch, but it is
> > easy to forgot, especially when the foo declaration is outside of the
> > default git context.
> > 
> > With new auto_kfree, we simply will start with
> > 	struct my_dev_foo *foo auto_kfree;
> > and be safe against future extensions.
> > 
> > I believe this will open up way for broader adoption of Scope Based
> > Resource Management, say in networking.
> > I also believe that my proposed name is special enough that it will
> > be easy to know/spot that the assignement is hidden.
> > 
> > Signed-off-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
> > ---
> >  include/linux/slab.h | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/include/linux/slab.h b/include/linux/slab.h
> > index 98e07e9e9e58..b943be0ce626 100644
> > --- a/include/linux/slab.h
> > +++ b/include/linux/slab.h
> > @@ -471,6 +471,7 @@ void kfree_sensitive(const void *objp);
> >  size_t __ksize(const void *objp);
> >  
> >  DEFINE_FREE(kfree, void *, if (!IS_ERR_OR_NULL(_T)) kfree(_T))
> > +#define auto_kfree __free(kfree) = NULL
> >  DEFINE_FREE(kfree_sensitive, void *, if (_T) kfree_sensitive(_T))
> >  
> >  /**
> 

-- 
Kees Cook


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC] slab: introduce auto_kfree macro
  2025-04-03 16:59   ` Kees Cook
@ 2025-04-03 17:35     ` Matthew Wilcox
  2025-04-03 17:46       ` Andy Shevchenko
  0 siblings, 1 reply; 14+ messages in thread
From: Matthew Wilcox @ 2025-04-03 17:35 UTC (permalink / raw)
  To: Kees Cook
  Cc: Vlastimil Babka, Przemek Kitszel, linux-kernel, linux-mm,
	torvalds, peterz, Jann Horn, andriy.shevchenko, intel-wired-lan,
	netdev, Harry Yoo, Christoph Lameter

On Thu, Apr 03, 2025 at 09:59:41AM -0700, Kees Cook wrote:
> On Wed, Apr 02, 2025 at 12:44:50PM +0200, Vlastimil Babka wrote:
> > Cc Kees and others from his related efforts:
> > 
> > https://lore.kernel.org/all/20250321202620.work.175-kees@kernel.org/
> 
> I think, unfortunately, the consensus is that "invisible side-effects"
> are not going to be tolerated. After I finish with kmalloc_obj(), I'd
> like to take another run at this for basically providing something like:
> 
> static inline __must_check
> void *kfree(void *p) { __kfree(p); return NULL; }
> 
> And then switch all:
> 
> 	kfree(s->ptr);
> 
> to
> 
> 	s->ptr = kfree(s->ptr);
> 
> Where s->ptr isn't used again.

Umm ... kfree is now going to be __must_check?  That's a lot of churn.

I'd just go with making kfree() return NULL and leave off the
__must_check.  It doesn't need the __kfree() indirection either.
That lets individual functions opt into the new safety.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC] slab: introduce auto_kfree macro
  2025-04-03 17:35     ` Matthew Wilcox
@ 2025-04-03 17:46       ` Andy Shevchenko
  0 siblings, 0 replies; 14+ messages in thread
From: Andy Shevchenko @ 2025-04-03 17:46 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Kees Cook, Vlastimil Babka, Przemek Kitszel, linux-kernel,
	linux-mm, torvalds, peterz, Jann Horn, intel-wired-lan, netdev,
	Harry Yoo, Christoph Lameter

On Thu, Apr 03, 2025 at 06:35:39PM +0100, Matthew Wilcox wrote:
> On Thu, Apr 03, 2025 at 09:59:41AM -0700, Kees Cook wrote:
> > On Wed, Apr 02, 2025 at 12:44:50PM +0200, Vlastimil Babka wrote:
> > > Cc Kees and others from his related efforts:
> > > 
> > > https://lore.kernel.org/all/20250321202620.work.175-kees@kernel.org/
> > 
> > I think, unfortunately, the consensus is that "invisible side-effects"
> > are not going to be tolerated. After I finish with kmalloc_obj(), I'd
> > like to take another run at this for basically providing something like:
> > 
> > static inline __must_check
> > void *kfree(void *p) { __kfree(p); return NULL; }
> > 
> > And then switch all:
> > 
> > 	kfree(s->ptr);
> > 
> > to
> > 
> > 	s->ptr = kfree(s->ptr);
> > 
> > Where s->ptr isn't used again.
> 
> Umm ... kfree is now going to be __must_check?  That's a lot of churn.
> 
> I'd just go with making kfree() return NULL and leave off the
> __must_check.  It doesn't need the __kfree() indirection either.
> That lets individual functions opt into the new safety.

Maybe something like

void kfree_and_null(void **ptr)
{
	__kfree(*ptr);
	*ptr = NULL;
}

?

-- 
With Best Regards,
Andy Shevchenko




^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC] slab: introduce auto_kfree macro
  2025-04-01 13:44 [RFC] slab: introduce auto_kfree macro Przemek Kitszel
  2025-04-02 10:32 ` Andy Shevchenko
  2025-04-02 10:44 ` Vlastimil Babka
@ 2025-04-03 18:15 ` Linus Torvalds
  2 siblings, 0 replies; 14+ messages in thread
From: Linus Torvalds @ 2025-04-03 18:15 UTC (permalink / raw)
  To: Przemek Kitszel
  Cc: linux-kernel, linux-mm, vbabka, peterz, andriy.shevchenko,
	intel-wired-lan, netdev

On Tue, 1 Apr 2025 at 06:50, Przemek Kitszel
<przemyslaw.kitszel@intel.com> wrote:
>
> With new auto_kfree, we simply will start with
>         struct my_dev_foo *foo auto_kfree;
> and be safe against future extensions.

Honestly, I'd much rather just see any auto-freeing *always* assigning
the value.

We used to have a rule that declarations had to be at the top of a
block, which made that not an option, but that rule went out the
window exactly because you can't do that with the cleanup macros.

So just make the rule be that __free() without an assignment is simply a bug.

               Linus


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC] slab: introduce auto_kfree macro
  2025-04-02 12:19   ` Peter Zijlstra
  2025-04-02 12:22     ` Peter Zijlstra
@ 2025-04-04  3:05     ` Herbert Xu
  1 sibling, 0 replies; 14+ messages in thread
From: Herbert Xu @ 2025-04-04  3:05 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: andriy.shevchenko, przemyslaw.kitszel, linux-kernel, linux-mm,
	vbabka, torvalds, intel-wired-lan, netdev, linux-toolchains

Peter Zijlstra <peterz@infradead.org> wrote:
>
> The compiler *should* complain. But neither GCC nor clang actually
> appear to warn in this case.

Linus turned that warning off in 2020:

commit 78a5255ffb6a1af189a83e493d916ba1c54d8c75
Author: Linus Torvalds <torvalds@linux-foundation.org>
Date:   Sat May 9 13:57:10 2020 -0700

    Stop the ad-hoc games with -Wno-maybe-initialized

You need to enable it by hand to see the warning:

make KBUILD_CFLAGS_KERNEL=-Wmaybe-uninitialized CFLAGS_MODULE=-Wmaybe-uninitialized

W=2 enables it too but it also enables lots of other crap so it's
useless.

Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2025-04-04  3:06 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-04-01 13:44 [RFC] slab: introduce auto_kfree macro Przemek Kitszel
2025-04-02 10:32 ` Andy Shevchenko
2025-04-02 10:40   ` Andy Shevchenko
2025-04-02 12:19   ` Peter Zijlstra
2025-04-02 12:22     ` Peter Zijlstra
2025-04-02 12:57       ` Andy Shevchenko
2025-04-04  3:05     ` Herbert Xu
2025-04-02 12:21   ` Peter Zijlstra
2025-04-02 12:55     ` Andy Shevchenko
2025-04-02 10:44 ` Vlastimil Babka
2025-04-03 16:59   ` Kees Cook
2025-04-03 17:35     ` Matthew Wilcox
2025-04-03 17:46       ` Andy Shevchenko
2025-04-03 18:15 ` Linus Torvalds

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox