Missed warning (-Wuse-after-free)

Yann Droneaud ydroneaud@opteya.com
Fri Feb 17 08:49:09 GMT 2023


Hi,

Le 16/02/2023 à 15:35, Alejandro Colomar via Gcc a écrit :
> Hi!
>
> I was preparing an example program of a use-after-realloc bug,
> when I found that GCC doesn't warn in a case where it should.
>
>
> alx@debian:~/tmp$ cat realloc.c
> #include <stdint.h>
> #include <stdlib.h>
> #include <stdio.h>
> #include <string.h>
> #include <unistd.h>
>
> static inline char *
> xstrdup(const char *s)
> {
> 	char  *p;
>
> 	p = strdup(s);
> 	if (p == NULL)
> 		exit(EXIT_FAILURE);
> 	return p;
> }
>
> static inline char *
> strnul(const char *s)
> {
> 	return (char *) s + strlen(s);
> }
>
> int
> main(void)
> {
> 	char  *p, *q;
>
> 	p = xstrdup("");
> 	q = strnul(p);
>
> 	if (p == q)
> 		puts("equal before");
> 	else
> 		exit(EXIT_FAILURE); // It's an empty string; this won't happen
>
> 	printf("p = %p; q = %p\n", p, q);
>
> 	p = realloc(p, UINT16_MAX);
> 	if (p == NULL)
> 		exit(EXIT_FAILURE);
> 	puts("realloc()");
>
> 	if (p == q) {  // Use after realloc.  I'd expect a warning here.
> 		puts("equal after");
> 	} else {
> 		/* Can we get here?
> 		   Let's see the options:
>
> 			- realloc(3) fails:
> 				We exit immediately.  We don't arrive here.
>
> 			- realloc(3) doesn't move the memory:
> 				p == q, as before
>
> 			- realloc(3) moved the memory:
> 				p is guaranteed to be a unique pointer,
> 				and q is now an invalid pointer.  It is
> 				Undefined Behavior to read `q`, so `p == q`
> 				is UB.
>
> 		   As we see, there's no _defined_ path where this can happen
> 		 */
> 		printf("PID = %i\n", (int) getpid());
> 	}
>
> 	printf("p = %p; q = %p\n", p, q);
> }
> alx@debian:~/tmp$ cc -Wall -Wextra realloc.c -O3 -fanalyzer
> realloc.c: In function ‘main’:
> realloc.c:67:9: warning: pointer ‘p’ may be used after ‘realloc’ [-Wuse-after-free]
>     67 |         printf("p = %p; q = %p\n", p, q);
>        |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> realloc.c:39:13: note: call to ‘realloc’ here
>     39 |         p = realloc(p, UINT16_MAX);
>        |             ^~~~~~~~~~~~~~~~~~~~~~
> alx@debian:~/tmp$ ./a.out
> equal before
> p = 0x55bff80802a0; q = 0x55bff80802a0
> realloc()
> PID = 25222
> p = 0x55bff80806d0; q = 0x55bff80802a0
>
>
> Did I miss anything?

-Wuse-after-free=3

Regards.

-- 
Yann Droneaud
OPTEYA




More information about the Gcc mailing list