View Issue Details

IDProjectCategoryView StatusLast Update
0006186GNUnetutil librarypublic2021-09-02 16:14
Reporterfefe Assigned ToChristian Grothoff Due Date
PrioritynormalSeveritytrivialReproducibilityN/A
Status closedResolutionfixed 
Product Version0.12.1 
Target Version0.13.0Fixed in Version0.13.0 
Summary0006186: Why does GNUNET_free not set the pointer to NULL?
DescriptionOne of the more notorious sources of errors in C is that free() will leave the pointer around, even though it no longer points to anything. That enables security holes like double free or other types of memory corruption.

GNUNET comes with a wrapper around free called GNUNET_free, and it is a macro, so it could set the pointer to NULL after the freeing is done.

It does not.

Why?
TagsNo tags attached.

Activities

Christian Grothoff

2020-04-17 16:23

manager   ~0015682

Not sure how to do it that works. Suppose I use:
#define GNUNET_free(ptr) do { \
    GNUNET_xfree_ (ptr, __FILE__, __LINE__); \
    ptr = NULL; \
} while (0)

it immediately bombs on things like:

gnunet-resolver.c: In function ‘main’:
../../src/include/gnunet_common.h:1294:9: error: lvalue required as left operand of assignment
     ptr = NULL; \
         ^
gnunet-resolver.c:181:3: note: in expansion of macro ‘GNUNET_free’
   GNUNET_free ((void *) argv);

Christian Grothoff

2020-04-17 16:25

manager   ~0015683

I'm happy to #define a GNUNET_freez() that additionally sets to NULL, but as the example above shows, that won't _always_ work.

Christian Grothoff

2020-04-20 21:50

manager   ~0015712

fefe: any better suggestions?

fefe

2020-04-20 21:57

reporter   ~0015713

Remove the void* cast maybe?
It looks superfluous to me?

Maybe you can trick something with gcc extensions here, but I think your freez suggestion looks good.

However I'd do it the other way around. Make GNUNET_free set the pointer to zero, and add an exceptional version for the few cases where that won't work.
That may however break other third party code using that gnunet macro.

Christian Grothoff

2020-04-20 22:14

manager   ~0015714

There are cases (rare, admittedly), where the pointer might have been 'const', and still must be free'd. Now, that itself may be ugly, but I'd still want to support it.

I'll investigate just how badly it breaks existing code bases (those I know of) if we change the default of GNUNET_free to set to zero and have a GNUNET_free_nz for the 'exceptions'. Based that, it'll be easier to decide if it's acceptable to break compatibility like that.

Christian Grothoff

2020-04-20 23:01

manager   ~0015715

zero-ing out is now the default, GNUNET_nz remains (for const casting and stuff like GNUNET_free(fun()) which happens, but rarely.

schanzen

2020-07-09 07:17

administrator   ~0016434

0.13.0 released

Christian Grothoff

2021-09-02 16:14

manager   ~0018263

Fix committed to master branch.

Issue History

Date ModifiedUsernameFieldChange
2020-04-17 10:32fefeNew Issue
2020-04-17 16:23Christian GrothoffNote Added: 0015682
2020-04-17 16:25Christian GrothoffNote Added: 0015683
2020-04-18 11:15Christian GrothoffStatusnew => feedback
2020-04-20 21:50Christian GrothoffNote Added: 0015712
2020-04-20 21:57fefeNote Added: 0015713
2020-04-20 21:57fefeStatusfeedback => new
2020-04-20 22:14Christian GrothoffNote Added: 0015714
2020-04-20 23:01Christian GrothoffAssigned To => Christian Grothoff
2020-04-20 23:01Christian GrothoffStatusnew => resolved
2020-04-20 23:01Christian GrothoffResolutionopen => fixed
2020-04-20 23:01Christian GrothoffFixed in Version => 0.12.2
2020-04-20 23:01Christian GrothoffNote Added: 0015715
2020-04-20 23:01Christian GrothoffTarget Version => 0.12.2
2020-04-23 08:45schanzenFixed in Version0.12.2 => 0.13.0
2020-04-23 08:47schanzenTarget Version0.12.2 => 0.13.0
2020-05-31 22:49AdminknoxIssue cloned: 0006313
2020-05-31 22:52AdminknoxIssue cloned: 0006345
2020-07-09 07:17schanzenNote Added: 0016434
2020-07-09 07:17schanzenStatusresolved => closed
2021-09-02 16:13Christian Grothoff
2021-09-02 16:14Christian GrothoffNote Added: 0018263