1 /*
2  * Memory allocation functions for testing
3  *
4  * Copyright (C) 2011-2021, Joachim Metz <joachim.metz@gmail.com>
5  *
6  * Refer to AUTHORS for acknowledgements.
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20  */
21 
22 #include <common.h>
23 
24 #if defined( HAVE_STDLIB_H ) || defined( WINAPI )
25 #include <stdlib.h>
26 #endif
27 
28 #if defined( HAVE_GNU_DL_DLSYM ) && defined( __GNUC__ )
29 #define __USE_GNU
30 #include <dlfcn.h>
31 #undef __USE_GNU
32 #endif
33 
34 #include "evt_test_memory.h"
35 
36 #if defined( HAVE_EVT_TEST_MEMORY )
37 
38 static void *(*evt_test_real_malloc)(size_t)                       = NULL;
39 static void *(*evt_test_real_memcpy)(void *, const void *, size_t) = NULL;
40 static void *(*evt_test_real_memset)(void *, int, size_t)          = NULL;
41 static void *(*evt_test_real_realloc)(void *, size_t)              = NULL;
42 
43 int evt_test_malloc_attempts_before_fail                           = -1;
44 int evt_test_memcpy_attempts_before_fail                           = -1;
45 int evt_test_memset_attempts_before_fail                           = -1;
46 int evt_test_realloc_attempts_before_fail                          = -1;
47 
48 /* Custom malloc for testing memory error cases
49  * Note this function might fail if compiled with optimation
50  * Returns a pointer to newly allocated data or NULL
51  */
malloc(size_t size)52 void *malloc(
53        size_t size )
54 {
55 	void *ptr = NULL;
56 
57 	if( evt_test_real_malloc == NULL )
58 	{
59 		evt_test_real_malloc = dlsym(
60 		                        RTLD_NEXT,
61 		                        "malloc" );
62 	}
63 	if( evt_test_malloc_attempts_before_fail == 0 )
64 	{
65 		evt_test_malloc_attempts_before_fail = -1;
66 
67 		return( NULL );
68 	}
69 	else if( evt_test_malloc_attempts_before_fail > 0 )
70 	{
71 		evt_test_malloc_attempts_before_fail--;
72 	}
73 	ptr = evt_test_real_malloc(
74 	       size );
75 
76 	return( ptr );
77 }
78 
79 /* Custom memcpy for testing memory error cases
80  * Note this function might fail if compiled with optimation and as a shared libary
81  * Returns a pointer to newly allocated data or NULL
82  */
memcpy(void * destination,const void * source,size_t size)83 void *memcpy(
84        void *destination,
85        const void *source,
86        size_t size )
87 {
88 	if( evt_test_real_memcpy == NULL )
89 	{
90 		evt_test_real_memcpy = dlsym(
91 		                        RTLD_NEXT,
92 		                        "memcpy" );
93 	}
94 	if( evt_test_memcpy_attempts_before_fail == 0 )
95 	{
96 		evt_test_memcpy_attempts_before_fail = -1;
97 
98 		return( NULL );
99 	}
100 	else if( evt_test_memcpy_attempts_before_fail > 0 )
101 	{
102 		evt_test_memcpy_attempts_before_fail--;
103 	}
104 	destination = evt_test_real_memcpy(
105 	               destination,
106 	               source,
107 	               size );
108 
109 	return( destination );
110 }
111 
112 /* Custom memset for testing memory error cases
113  * Note this function might fail if compiled with optimation and as a shared libary
114  * Returns a pointer to newly allocated data or NULL
115  */
memset(void * ptr,int constant,size_t size)116 void *memset(
117        void *ptr,
118        int constant,
119        size_t size )
120 {
121 	if( evt_test_real_memset == NULL )
122 	{
123 		evt_test_real_memset = dlsym(
124 		                        RTLD_NEXT,
125 		                        "memset" );
126 	}
127 	if( evt_test_memset_attempts_before_fail == 0 )
128 	{
129 		evt_test_memset_attempts_before_fail = -1;
130 
131 		return( NULL );
132 	}
133 	else if( evt_test_memset_attempts_before_fail > 0 )
134 	{
135 		evt_test_memset_attempts_before_fail--;
136 	}
137 	ptr = evt_test_real_memset(
138 	       ptr,
139 	       constant,
140 	       size );
141 
142 	return( ptr );
143 }
144 
145 /* Custom realloc for testing memory error cases
146  * Note this function might fail if compiled with optimation
147  * Returns a pointer to reallocated data or NULL
148  */
realloc(void * ptr,size_t size)149 void *realloc(
150        void *ptr,
151        size_t size )
152 {
153 	if( evt_test_real_realloc == NULL )
154 	{
155 		evt_test_real_realloc = dlsym(
156 		                         RTLD_NEXT,
157 		                         "realloc" );
158 	}
159 	if( evt_test_realloc_attempts_before_fail == 0 )
160 	{
161 		evt_test_realloc_attempts_before_fail = -1;
162 
163 		return( NULL );
164 	}
165 	else if( evt_test_realloc_attempts_before_fail > 0 )
166 	{
167 		evt_test_realloc_attempts_before_fail--;
168 	}
169 	ptr = evt_test_real_realloc(
170 	       ptr,
171 	       size );
172 
173 	return( ptr );
174 }
175 
176 #endif /* defined( HAVE_EVT_TEST_MEMORY ) */
177 
178