You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
126 lines
2.8 KiB
126 lines
2.8 KiB
/*
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <stdnoreturn.h>
|
|
|
|
int* malloc_no_check_bad() {
|
|
int* p = (int*)malloc(sizeof(int));
|
|
*p = 42;
|
|
return p;
|
|
}
|
|
|
|
void create_null_path_ok(int* p) {
|
|
if (p) {
|
|
*p = 32;
|
|
}
|
|
}
|
|
|
|
void call_create_null_path_then_deref_unconditionally_ok(int* p) {
|
|
create_null_path_ok(p);
|
|
*p = 52;
|
|
}
|
|
|
|
void create_null_path2_latent(int* p) {
|
|
int* q = NULL;
|
|
if (p) {
|
|
*p = 32;
|
|
}
|
|
// arguably bogus to check p above but not here, but the above could
|
|
// also be macro-generated code so both reporting and not reporting
|
|
// are sort of justifiable
|
|
*p = 52;
|
|
}
|
|
|
|
// combine several of the difficulties above
|
|
void malloc_then_call_create_null_path_then_deref_unconditionally_latent(
|
|
int* p) {
|
|
int* x = (int*)malloc(sizeof(int));
|
|
if (p) {
|
|
*p = 32;
|
|
}
|
|
create_null_path_ok(p);
|
|
*p = 52;
|
|
free(x);
|
|
}
|
|
|
|
// pulse should remember the value of vec[64] because it was just written to
|
|
void nullptr_deref_young_bad(int* x) {
|
|
int* vec[65] = {x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
|
|
x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
|
|
x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
|
|
x, x, x, x, x, x, x, x, x, x, x, x, x, NULL};
|
|
int p = *vec[64];
|
|
}
|
|
|
|
// due to the recency model of memory accesses, vec[0] can get forgotten
|
|
// by the time we have processed the last element of the
|
|
// initialization so we don't report here
|
|
void FN_nullptr_deref_old_bad(int* x) {
|
|
int* vec[65] = {NULL, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
|
|
x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
|
|
x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
|
|
x, x, x, x, x, x, x, x, x, x, x, x, x, x};
|
|
int p = *vec[0];
|
|
}
|
|
|
|
void malloc_free_ok() {
|
|
int* p = (int*)malloc(sizeof(int));
|
|
free(p);
|
|
}
|
|
|
|
void wrap_free(void* p) { free(p); }
|
|
|
|
void interproc_free_ok() {
|
|
int* p = (int*)malloc(sizeof(int));
|
|
wrap_free(p);
|
|
}
|
|
|
|
noreturn void no_return();
|
|
|
|
void wrap_malloc(int** x) {
|
|
*x = (int*)malloc(sizeof(int));
|
|
if (!*x) {
|
|
no_return();
|
|
}
|
|
}
|
|
|
|
void user_malloc_leak_bad() { int* x = (int*)a_malloc(sizeof(int)); }
|
|
|
|
void call_no_return_good() {
|
|
int* x = NULL;
|
|
wrap_malloc(&x);
|
|
*x = 5;
|
|
free(x);
|
|
}
|
|
|
|
void bug_after_malloc_result_test_bad(int* x) {
|
|
x = (int*)malloc(sizeof(int));
|
|
if (x) {
|
|
int* y = NULL;
|
|
*y = 42;
|
|
}
|
|
}
|
|
|
|
void bug_after_abduction_bad(int* x) {
|
|
*x = 42;
|
|
int* y = NULL;
|
|
*y = 42;
|
|
}
|
|
|
|
void bug_with_allocation_bad(int* x) {
|
|
x = (int*)malloc(sizeof(int*));
|
|
int* y = NULL;
|
|
*y = 42;
|
|
}
|
|
|
|
void null_alias_bad(int* x) {
|
|
int* y = NULL;
|
|
x = (int*)malloc(sizeof(int*));
|
|
*x = 42;
|
|
}
|