c.lang.security.use-after-free.use-after-free
Community Favorite

Author
46,010
Download Count*
License
Variable '$VAR' was used after being freed. This can lead to undefined behavior.
Run Locally
Run in CI
Defintion
rules:
- id: use-after-free
patterns:
- pattern: $VAR->$ACCESSOR
- pattern-inside: free($VAR); ...
- pattern-not-inside: $VAR = NULL; ...
message: Variable '$VAR' was used after being freed. This can lead to undefined
behavior.
metadata:
cwe:
- "CWE-416: Use After Free"
references:
- https://cwe.mitre.org/data/definitions/416.html
- https://ctf-wiki.github.io/ctf-wiki/pwn/linux/glibc-heap/use_after_free/
category: security
technology:
- c
confidence: MEDIUM
cwe2022-top25: true
cwe2021-top25: true
subcategory:
- vuln
likelihood: LOW
impact: HIGH
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
languages:
- c
severity: WARNING
Examples
use-after-free.c
#include <stdio.h>
#include <stdlib.h>
typedef struct name {
char *myname;
void (*func)(char *str);
} NAME;
void other_func(char *ignored) {}
int bad_code1() {
NAME *var;
var = (NAME *)malloc(sizeof(struct name));
free(var);
// ruleid: use-after-free
var->func("use after free");
return 0;
}
int okay_code1() {
NAME *var;
var = (NAME *)malloc(sizeof(struct name));
free(var);
var = NULL;
// This will segmentation fault
// ok: use-after-free
var->func("use after free");
return 0;
}
int bad_code2() {
NAME *var;
var = (NAME *)malloc(sizeof(struct name));
free(var);
// ruleid: use-after-free
other_func(var->myname);
return 0;
}
int okay_code2() {
NAME *var;
var = (NAME *)malloc(sizeof(struct name));
free(var);
var = NULL;
// This will segmentation fault
// ok: use-after-free
other_func(var->myname);
return 0;
}
struct NAME {
char first_name[32];
int auth;
} s_auth;
int bad_code3(){
struct NAME *var;
var = malloc(sizeof(s_auth));
free(var);
// ruleid: use-after-free
if(var->auth){
printf("you have logged in already");
}
else{
printf("you do not have the permision to log in.");
}
return 0;
}
int ok_code3(){
struct NAME *var;
var = malloc(sizeof(s_auth));
free(var);
var=NULL;
// ok: use-after-free
if(var->auth){
printf("you have logged in already");
}
else{
printf("you do not have the permision to log in.");
}
return 0;
}
struct lv {
int length;
char *value;
} lv;
struct lv2 {
int length;
struct lv *lv;
} lv2;
int bad_code4(){
int initial = 1000;
struct lv *lv = malloc(sizeof(*lv));
lv->length = initial;
lv->value = malloc(initial);
free(lv);
// ruleid: use-after-free
free(lv->value);
return 0;
}
int ok_code4(){
int initial = 1000;
struct lv *lv = malloc(sizeof(*lv));
lv->length = initial;
lv->value = malloc(initial);
// ok: use-after-free
free(lv->value);
// ok: use-after-free
free(lv);
return 0;
}
int bad_code5(){
int initial = 1000;
struct lv *lv = malloc(sizeof(*lv));
lv->length = initial;
lv->value = malloc(initial);
struct lv2 *lv2 = malloc(sizeof(*lv2));
lv2->length = initial;
lv2->lv = lv;
// ok: use-after-free
free(lv2->lv);
// ruleid: use-after-free
free(lv2->lv->value);
// ok: use-after-free
free(lv2);
return 0;
}
int ok_code5(){
int initial = 1000;
struct lv *lv = malloc(sizeof(*lv));
lv->length = initial;
lv->value = malloc(initial);
struct lv2 *lv2 = malloc(sizeof(*lv2));
lv2->length = initial;
lv2->lv = lv;
// ok: use-after-free
free(lv2->lv->value);
// ok: use-after-free
free(lv2->lv);
// ok: use-after-free
free(lv2);
return 0;
}
Short Link: https://sg.run/gL6e