From 26f0309ec923da64851e69b982f1ea2e81986dd4 Mon Sep 17 00:00:00 2001 From: Jules Villard Date: Mon, 24 May 2021 05:05:49 -0700 Subject: [PATCH] [pulse] add "fat pointers" mem leak tests Summary: yay tests! Reviewed By: skcho Differential Revision: D28606677 fbshipit-source-id: ce930e660 --- infer/tests/codetoanalyze/c/pulse/issues.exp | 3 ++ .../codetoanalyze/c/pulse/issues.exp-isl | 3 ++ .../tests/codetoanalyze/c/pulse/memory_leak.c | 42 +++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/infer/tests/codetoanalyze/c/pulse/issues.exp b/infer/tests/codetoanalyze/c/pulse/issues.exp index b3f7dbf2c..65fb3b11c 100644 --- a/infer/tests/codetoanalyze/c/pulse/issues.exp +++ b/infer/tests/codetoanalyze/c/pulse/issues.exp @@ -14,6 +14,9 @@ codetoanalyze/c/pulse/latent.c, latent_use_after_free, 4, NULLPTR_DEREFERENCE, n codetoanalyze/c/pulse/latent.c, latent_use_after_free, 4, USE_AFTER_FREE, no_bucket, ERROR, [*** LATENT ***,invalidation part of the trace starts here,parameter `x` of latent_use_after_free,was invalidated by call to `free()`,use-after-lifetime part of the trace starts here,parameter `x` of latent_use_after_free,invalid access occurs here] codetoanalyze/c/pulse/latent.c, main, 3, USE_AFTER_FREE, no_bucket, ERROR, [calling context starts here,in call to `latent_use_after_free`,invalidation part of the trace starts here,parameter `x` of latent_use_after_free,was invalidated by call to `free()`,use-after-lifetime part of the trace starts here,parameter `x` of latent_use_after_free,invalid access occurs here] codetoanalyze/c/pulse/latent.c, manifest_use_after_free, 0, USE_AFTER_FREE, no_bucket, ERROR, [calling context starts here,in call to `latent_use_after_free`,invalidation part of the trace starts here,parameter `x` of latent_use_after_free,was invalidated by call to `free()`,use-after-lifetime part of the trace starts here,parameter `x` of latent_use_after_free,invalid access occurs here] +codetoanalyze/c/pulse/memory_leak.c, FP_alloc_ref_counted_arith_ok, 4, MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocated by `malloc` here,memory becomes unreachable here] +codetoanalyze/c/pulse/memory_leak.c, FP_alloc_ref_counted_ok, 5, MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocated by `malloc` here,memory becomes unreachable here] +codetoanalyze/c/pulse/memory_leak.c, alloc_ref_counted_bad, 6, MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocated by `malloc` here,memory becomes unreachable here] codetoanalyze/c/pulse/memory_leak.c, malloc_formal_leak_bad, 0, MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocated by `malloc` here,memory becomes unreachable here] codetoanalyze/c/pulse/memory_leak.c, malloc_interproc_no_free_bad, 0, MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,when calling `create_p` here,allocated by `malloc` here,memory becomes unreachable here] codetoanalyze/c/pulse/memory_leak.c, malloc_interproc_no_free_bad2, 4, MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocated by `malloc` here,memory becomes unreachable here] diff --git a/infer/tests/codetoanalyze/c/pulse/issues.exp-isl b/infer/tests/codetoanalyze/c/pulse/issues.exp-isl index 434478473..d4c3762a0 100644 --- a/infer/tests/codetoanalyze/c/pulse/issues.exp-isl +++ b/infer/tests/codetoanalyze/c/pulse/issues.exp-isl @@ -14,6 +14,9 @@ codetoanalyze/c/pulse/latent.c, latent_use_after_free, 4, NULLPTR_DEREFERENCE, n codetoanalyze/c/pulse/latent.c, latent_use_after_free, 4, USE_AFTER_FREE, no_bucket, ERROR, [*** LATENT ***,invalidation part of the trace starts here,was invalidated by call to `free()`,use-after-lifetime part of the trace starts here,invalid access occurs here] codetoanalyze/c/pulse/latent.c, main, 3, USE_AFTER_FREE, no_bucket, ERROR, [calling context starts here,in call to `latent_use_after_free`,invalidation part of the trace starts here,was invalidated by call to `free()`,use-after-lifetime part of the trace starts here,invalid access occurs here] codetoanalyze/c/pulse/latent.c, manifest_use_after_free, 0, USE_AFTER_FREE, no_bucket, ERROR, [calling context starts here,in call to `latent_use_after_free`,invalidation part of the trace starts here,was invalidated by call to `free()`,use-after-lifetime part of the trace starts here,invalid access occurs here] +codetoanalyze/c/pulse/memory_leak.c, FP_alloc_ref_counted_arith_ok, 4, MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocated by `malloc` here,memory becomes unreachable here] +codetoanalyze/c/pulse/memory_leak.c, FP_alloc_ref_counted_ok, 5, MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocated by `malloc` here,memory becomes unreachable here] +codetoanalyze/c/pulse/memory_leak.c, alloc_ref_counted_bad, 6, MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocated by `malloc` here,memory becomes unreachable here] codetoanalyze/c/pulse/memory_leak.c, malloc_formal_leak_bad, 0, MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocated by `malloc` here,memory becomes unreachable here] codetoanalyze/c/pulse/memory_leak.c, malloc_interproc_no_free_bad, 0, MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,when calling `create_p` here,allocated by `malloc` here,memory becomes unreachable here] codetoanalyze/c/pulse/memory_leak.c, malloc_interproc_no_free_bad2, 4, MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocated by `malloc` here,memory becomes unreachable here] diff --git a/infer/tests/codetoanalyze/c/pulse/memory_leak.c b/infer/tests/codetoanalyze/c/pulse/memory_leak.c index 400096870..103b7ad8a 100644 --- a/infer/tests/codetoanalyze/c/pulse/memory_leak.c +++ b/infer/tests/codetoanalyze/c/pulse/memory_leak.c @@ -145,3 +145,45 @@ void test_config_options_no_free_bad() { int* p = (int*)my_malloc(sizeof(int)); int* q = my_realloc(p, sizeof(int)); } + +struct ref_counted { + size_t count; + int data; +}; + +// the address of the malloc()'d pointer can be retrieved from the +// return value using pointer arithmetic +int* FP_alloc_ref_counted_ok() { + struct ref_counted* p = + (struct ref_counted*)malloc(sizeof(struct ref_counted)); + if (p) { + p->count = 1; + return &(p->data); + } else { + return NULL; + } +} + +// returning the value of the field loses the address of p +int alloc_ref_counted_bad() { + struct ref_counted* p = + (struct ref_counted*)malloc(sizeof(struct ref_counted)); + if (p) { + p->count = 1; + p->data = 42; + return p->data; + } else { + return NULL; + } +} + +// the address of the malloc()'d pointer can be retrieved from the +// return value using pointer arithmetic +void* FP_alloc_ref_counted_arith_ok(size_t size) { + int* p = (int*)malloc(size + sizeof(int)); + if (p) { + // register count = 1 and point past the ref count + *p++ = 1; + } + return p; +}