1 /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ 2 #ifndef __LIBPERF_INTERNAL_RC_CHECK_H 3 #define __LIBPERF_INTERNAL_RC_CHECK_H 4 5 #include <stdlib.h> 6 #include <linux/zalloc.h> 7 8 /* 9 * Enable reference count checking implicitly with leak checking, which is 10 * integrated into address sanitizer. 11 */ 12 #if defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER) 13 #define REFCNT_CHECKING 1 14 #endif 15 16 /* 17 * Shared reference count checking macros. 18 * 19 * Reference count checking is an approach to sanitizing the use of reference 20 * counted structs. It leverages address and leak sanitizers to make sure gets 21 * are paired with a put. Reference count checking adds a malloc-ed layer of 22 * indirection on a get, and frees it on a put. A missed put will be reported as 23 * a memory leak. A double put will be reported as a double free. Accessing 24 * after a put will cause a use-after-free and/or a segfault. 25 */ 26 27 #ifndef REFCNT_CHECKING 28 /* Replaces "struct foo" so that the pointer may be interposed. */ 29 #define DECLARE_RC_STRUCT(struct_name) \ 30 struct struct_name 31 32 /* Declare a reference counted struct variable. */ 33 #define RC_STRUCT(struct_name) struct struct_name 34 35 /* 36 * Interpose the indirection. Result will hold the indirection and object is the 37 * reference counted struct. 38 */ 39 #define ADD_RC_CHK(result, object) (result = object, object) 40 41 /* Strip the indirection layer. */ 42 #define RC_CHK_ACCESS(object) object 43 44 /* Frees the object and the indirection layer. */ 45 #define RC_CHK_FREE(object) free(object) 46 47 /* A get operation adding the indirection layer. */ 48 #define RC_CHK_GET(result, object) ADD_RC_CHK(result, object) 49 50 /* A put operation removing the indirection layer. */ 51 #define RC_CHK_PUT(object) {} 52 53 #else 54 55 /* Replaces "struct foo" so that the pointer may be interposed. */ 56 #define DECLARE_RC_STRUCT(struct_name) \ 57 struct original_##struct_name; \ 58 struct struct_name { \ 59 struct original_##struct_name *orig; \ 60 }; \ 61 struct original_##struct_name 62 63 /* Declare a reference counted struct variable. */ 64 #define RC_STRUCT(struct_name) struct original_##struct_name 65 66 /* 67 * Interpose the indirection. Result will hold the indirection and object is the 68 * reference counted struct. 69 */ 70 #define ADD_RC_CHK(result, object) \ 71 ( \ 72 object ? (result = malloc(sizeof(*result)), \ 73 result ? (result->orig = object, result) \ 74 : (result = NULL, NULL)) \ 75 : (result = NULL, NULL) \ 76 ) 77 78 /* Strip the indirection layer. */ 79 #define RC_CHK_ACCESS(object) object->orig 80 81 /* Frees the object and the indirection layer. */ 82 #define RC_CHK_FREE(object) \ 83 do { \ 84 zfree(&object->orig); \ 85 free(object); \ 86 } while(0) 87 88 /* A get operation adding the indirection layer. */ 89 #define RC_CHK_GET(result, object) ADD_RC_CHK(result, (object ? object->orig : NULL)) 90 91 /* A put operation removing the indirection layer. */ 92 #define RC_CHK_PUT(object) \ 93 do { \ 94 if (object) { \ 95 object->orig = NULL; \ 96 free(object); \ 97 } \ 98 } while(0) 99 100 #endif 101 102 #endif /* __LIBPERF_INTERNAL_RC_CHECK_H */ 103