MCPcopy Create free account
hub / github.com/GJDuck/e9patch / check

Function check

examples/bounds.c:146–222  ·  view source on GitHub ↗

* Memory error check routine: * - loc = static instruction address. * - base = memory operand base pointer. * - access = actual address that is accessed. * - sz = the size of the memory access. * - _asm = the ASM string of the instruction. */

Source from the content-addressed store, hash-verified

144 * - _asm = the ASM string of the instruction.
145 */
146void check(const void *loc, const void *base, const void *access, size_t sz,
147 const char *_asm)
148{
149 /*
150 * Step (1): Find the base of the allocation, which has the following
151 * layout (as guaranteed by libredfat.so):
152 *
153 * +----+--------------+
154 * | Sz | Object |
155 * +----+--------------+
156 * Allocation
157 *
158 * The allocation base stores the object size metadata (Sz)
159 * which is prepended to the start of the object. The meta
160 * region also serves as an inaccessible redzone between
161 * objects.
162 */
163 const size_t *meta = (size_t *)redfat_base(base, access);
164 if (meta == NULL)
165 return; // Not a RedFat pointer
166
167 /*
168 * Step (2): Do the bounds check. Note that "free" objects will have a
169 * size==0, so will always fail the bounds check.
170 */
171 size_t size = *meta;
172 const uint8_t *lb = (uint8_t *)meta + REDZONE;
173 const uint8_t *ub = lb + size;
174 const uint8_t *access8 = (uint8_t *)access;
175 if (access8 >= lb && access8 + sz <= ub && size < redfat_size(access))
176 return; // Valid memory access
177
178 /*
179 * Step (3): A memory error has been detected. Gather useful information
180 * and print the error to stderr, then abort.
181 */
182 const uint8_t *access_base = (uint8_t *)redfat_base(access, access);
183 size_t access_size = *(size_t *)access_base;
184 bool access_free = (access_size == 0x0);
185 access_size = (access_free? redfat_size(access): access_size);
186 const uint8_t *access_lb = access_base + REDZONE;
187 const uint8_t *access_ub = access_lb + access_size;
188
189 const uint8_t *base_base = (uint8_t *)redfat_base(base, access);
190 size_t base_size = *(size_t *)base_base;
191 bool base_free = (base_size == 0x0);
192 base_size = (base_free? redfat_size(base): base_size);
193 const uint8_t *base_lb = base_base + REDZONE;
194 const uint8_t *base_ub = base_lb + base_size;
195
196 const char *kind = "out-of-bounds";
197 if (access_free && base_free)
198 kind = "use-after-free";
199 else if (size > redfat_size(access))
200 kind = "size-metadata-corruption";
201
202 const uint8_t *base8 = (uint8_t *)base;
203 fprintf(stderr, "%sMEMORY ERROR%s: %s error detected!\n"

Callers

nothing calls this directly

Calls 4

redfat_baseFunction · 0.85
redfat_sizeFunction · 0.85
abortFunction · 0.85
fprintfFunction · 0.70

Tested by

no test coverage detected