Re: build bug on kfree(struct sk_buff*)

Previous thread: Re: netxen: remove old flash check. by David Miller on Friday, March 13, 2009 - 4:15 pm. (1 message)

Next thread: [PATCH] Make virtio_net support carrier detection by Rusty Russell on Friday, March 13, 2009 - 5:23 pm. (2 messages)
From: Roel Kluin
Date: Friday, March 13, 2009 - 4:16 pm

Hi David,

Maybe I should have sent this to you (and netdev) in the first place.



I am now trying allyesconfig. The errors are due to:

* In net/core/dev.c +2674 a struct sk_buff* was freed,

* when assigning kfree to a function pointer.

* Several kfrees, but I don't know why gcc complains:

In block/genhd.c:
struct timer_rand_state *random,

In drivers/gpu/drm/i915/intel_modes.c:
struct edid *edid,

In kernel/exit.c:
struct futex_pi_state *pi_state_cache;

In drivers/char/ipmi/ipmi_si_intf.c:
struct si_sm_data      *si_sm;

e.g:
/home/roel/dnld/src/kernel/git/linux-2.6/drivers/char/ipmi/ipmi_si_intf.c: In function 'try_smi_init':
/home/roel/dnld/src/kernel/git/linux-2.6/drivers/char/ipmi/ipmi_si_intf.c:2960: error: invalid use of undefined type 'struct si_sm_data'
/home/roel/dnld/src/kernel/git/linux-2.6/drivers/char/ipmi/ipmi_si_intf.c:2960: error: dereferencing pointer to incomplete type
/home/roel/dnld/src/kernel/git/linux-2.6/drivers/char/ipmi/ipmi_si_intf.c: In function 'cleanup_one_si':
/home/roel/dnld/src/kernel/git/linux-2.6/drivers/char/ipmi/ipmi_si_intf.c:3123: error: invalid use of undefined type 'struct si_sm_data'
/home/roel/dnld/src/kernel/git/linux-2.6/drivers/char/ipmi/ipmi_si_intf.c:3123: error: dereferencing pointer to incomplete type


But also in cases where the variable is a void*, e.g. net/core/dev.c +4720
below.

I can quite easily change these kfree's to _kfree, however, I am not sure
if that's the best strategy.

Roel

Not meant for inclusion (yet)
---
 block/genhd.c                      |    2 +-
 drivers/char/ipmi/ipmi_si_intf.c   |    4 ++--
 drivers/firmware/dmi-id.c          |    2 +-
 drivers/gpu/drm/i915/intel_modes.c |    2 +-
 drivers/s390/char/vmlogrdr.c       |    2 +-
 drivers/s390/net/netiucv.c         |    2 +-
 fs/nfsd/nfs4xdr.c                  |    4 ++--
 include/linux/kernel.h             |    5 +++++
 include/linux/slab.h               |    5 ++++-
 kernel/exit.c                      |    2 +-
 lib/kref.c   ...
From: Roel Kluin
Date: Sunday, March 15, 2009 - 9:42 am

I noticed that my initial attempt was invalid. The one below appears to be
correct, although I am not sure whether there is a better implementation.

this patch also fixes a kfree(skb) in net/core/dev.c, what do you think?

Roel

Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
---
 include/linux/kernel.h |    4 ++++
 include/linux/slab.h   |    3 +++
 mm/slab.c              |    2 ++
 mm/slob.c              |    2 ++
 mm/slub.c              |    2 ++
 net/core/dev.c         |    2 +-
 6 files changed, 14 insertions(+), 1 deletions(-)

diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 7fa3718..b7f22d8 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -526,6 +526,10 @@ struct sysinfo {
    aren't permitted). */
 #define BUILD_BUG_ON_ZERO(e) (sizeof(char[1 - 2 * !!(e)]) - 1)
 
+/* If the type of x is TYPE, force a compilation error, otherwise produce x */
+#define BUILD_BUG_ON_TYPE(x, TYPE) __builtin_choose_expr(		\
+		__builtin_types_compatible_p(typeof(x), TYPE), (void)0, (x))
+
 /* Trap pasters of __FUNCTION__ at compile-time */
 #define __FUNCTION__ (__func__)
 
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 24c5602..30c28f9 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -130,6 +130,9 @@ void kfree(const void *);
 void kzfree(const void *);
 size_t ksize(const void *);
 
+/* This ensures that kfree is not called with a struct sk_buff* */
+#define kfree(x) kfree(BUILD_BUG_ON_TYPE(x, struct sk_buff*))
+
 /*
  * Allocator specific definitions. These are mainly used to establish optimized
  * ways to convert kmalloc() calls to kmem_cache_alloc() invocations by
diff --git a/mm/slab.c b/mm/slab.c
index 4d00855..cbcd28a 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -3711,6 +3711,7 @@ EXPORT_SYMBOL(kmem_cache_free);
  * Don't free memory not originally allocated by kmalloc()
  * or you will run into trouble.
  */
+#undef kfree
 void kfree(const void *objp)
 {
 	struct kmem_cache *c;
@@ -3727,6 ...
From: Ben Hutchings
Date: Sunday, March 15, 2009 - 12:33 pm

[...]

There are many types that should not be allocated and freed using the
general-purpose heap functions.  Why provide this check only for struct
skbuff?

Perhaps you should try to find a general way of detecting this, such as
a type annotation for sparse.

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
--

Previous thread: Re: netxen: remove old flash check. by David Miller on Friday, March 13, 2009 - 4:15 pm. (1 message)

Next thread: [PATCH] Make virtio_net support carrier detection by Rusty Russell on Friday, March 13, 2009 - 5:23 pm. (2 messages)