Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c99 goto past initialization

Tags:

While debugging a crash, I came across this issue in some code:

int func() {     char *p1 = malloc(...);     if (p1 == NULL)         goto err_exit;      char *p2 = malloc(...);     if (p2 == NULL)         goto err_exit;      ...  err_exit:     free(p2);     free(p1);      return -1; } 

The problem occurs when the first malloc fails. Because we jump across the initialization of p2, it contains random data and the call to free(p2) can crash.

I would expect/hope that this would be treated the same way as in C++ where the compiler does not allow a goto to jump across an initialization.

My question: is jumping across an initialization allowed by the standard or is this a bug in gcc's implementation of c99?

like image 741
R Samuel Klatchko Avatar asked May 12 '10 18:05

R Samuel Klatchko


1 Answers

You can ask gcc to warn you when you jump over a variable definition by using -Wjump-misses-init and then you can use -Werror (or, more precisely, -Werror=jump-misses-init) to force the users to deal with it. This warning is included in -Wc++-compat so the gcc developers are aware that the code behaves differently in C versus C++.

You could also change the code slightly:

int func() {     char *p1 = malloc(...);     if (p1 == NULL)         goto err_exit_1;      char *p2 = malloc(...);     if (p2 == NULL)         goto err_exit_2;      ...  err_exit_2:     free(p2); err_exit_1:     free(p1);      return -1; } 

... and just keep pairing labels with initialized variables. You'll have the same problem with calling many other functions with unitialized variables, free just happens to be a more obvious one.

like image 178
florin Avatar answered Sep 20 '22 18:09

florin