1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 /* 30 * Contains implementation of memory allocation routines instrumented for 31 * usage in the emulator to detect memory allocation violations, such as 32 * memory leaks, buffer overruns, etc. 33 * Code, implemented here is intended to run in the emulated environment only, 34 * and serves simply as hooks into memory allocation routines. Main job of this 35 * code is to notify the emulator about memory being allocated/deallocated, 36 * providing information about each allocation. The idea is that emulator will 37 * keep list of currently allocated blocks, and, knowing boundaries of each 38 * block it will be able to verify that ld/st access to these blocks don't step 39 * over boundaries set for the user. To enforce that, each memory block 40 * allocated by this code is guarded with "prefix" and "suffix" areas, so 41 * every time emulator detects access to any of these guarding areas, it can be 42 * considered as access violation. 43 */ 44 45 #include <stdlib.h> 46 #include <stddef.h> 47 #include <stdio.h> 48 #include <fcntl.h> 49 #include <sys/mman.h> 50 #include <pthread.h> 51 #include <unistd.h> 52 #include <errno.h> 53 #include "dlmalloc.h" 54 #include "libc_logging.h" 55 #include "malloc_debug_common.h" 56 57 /* This file should be included into the build only when 58 * MALLOC_QEMU_INSTRUMENT macro is defined. */ 59 #ifndef MALLOC_QEMU_INSTRUMENT 60 #error MALLOC_QEMU_INSTRUMENT is not defined. 61 #endif // !MALLOC_QEMU_INSTRUMENT 62 63 /* Controls access violation test performed to make sure that we catch AVs 64 * all the time they occur. See test_access_violation for more info. This macro 65 * is used for internal testing purposes and should always be set to zero for 66 * the production builds. */ 67 #define TEST_ACCESS_VIOLATIONS 0 68 69 // ============================================================================= 70 // Communication structures 71 // ============================================================================= 72 73 /* Describes memory block allocated from the heap. This structure is passed 74 * along with TRACE_DEV_REG_MALLOC event. This descriptor is used to inform 75 * the emulator about new memory block being allocated from the heap. The entire 76 * structure is initialized by the guest system before event is fired up. It is 77 * important to remember that same structure (an exact copy, except for 78 * replacing pointers with target_ulong) is also declared in the emulator's 79 * sources (file memcheck/memcheck_common.h). So, every time a change is made to 80 * any of these two declaration, another one must be also updated accordingly. 81 */ 82 struct MallocDesc { 83 /* Pointer to the memory block actually allocated from the heap. Note that 84 * this is not the pointer that is returned to the malloc's caller. Pointer 85 * returned to the caller is calculated by adding value stored in this field 86 * to the value stored in prefix_size field of this structure. 87 */ 88 void* ptr; 89 90 /* Number of bytes requested by the malloc's caller. */ 91 uint32_t requested_bytes; 92 93 /* Byte size of the prefix data. Actual pointer returned to the malloc's 94 * caller is calculated by adding value stored in this field to the value 95 * stored in in the ptr field of this structure. 96 */ 97 uint32_t prefix_size; 98 99 /* Byte size of the suffix data. */ 100 uint32_t suffix_size; 101 102 /* Id of the process that initialized libc instance, in which allocation 103 * has occurred. This field is used by the emulator to report errors in 104 * the course of TRACE_DEV_REG_MALLOC event handling. In case of an error, 105 * emulator sets this field to zero (invalid value for a process ID). 106 */ 107 uint32_t libc_pid; 108 109 /* Id of the process in context of which allocation has occurred. 110 * Value in this field may differ from libc_pid value, if process that 111 * is doing allocation has been forked from the process that initialized 112 * libc instance. 113 */ 114 uint32_t allocator_pid; 115 116 /* Number of access violations detected on this allocation. */ 117 uint32_t av_count; 118 }; 119 120 /* Describes memory block info queried from emulator. This structure is passed 121 * along with TRACE_DEV_REG_QUERY_MALLOC event. When handling free and realloc 122 * calls, it is required that we have information about memory blocks that were 123 * actually allocated in previous calls to malloc, calloc, memalign, or realloc. 124 * Since we don't keep this information directly in the allocated block, but 125 * rather we keep it in the emulator, we need to query emulator for that 126 * information with TRACE_DEV_REG_QUERY_MALLOC query. The entire structure is 127 * initialized by the guest system before event is fired up. It is important to 128 * remember that same structure (an exact copy, except for replacing pointers 129 * with target_ulong) is also declared in the emulator's sources (file 130 * memcheck/memecheck_common.h). So, every time a change is made to any of these 131 * two declaration, another one must be also updated accordingly. 132 */ 133 struct MallocDescQuery { 134 /* Pointer, for which information is queried. Note that this pointer doesn't 135 * have to be exact pointer returned to malloc's caller, but can point 136 * anywhere inside an allocated block, including guarding areas. Emulator 137 * will respond with information about allocated block that contains this 138 * pointer. 139 */ 140 const void* ptr; 141 142 /* Id of the process that initialized libc instance, in which this query 143 * is called. This field is used by the emulator to report errors in 144 * the course of TRACE_DEV_REG_QUERY_MALLOC event handling. In case of an 145 * error, emulator sets this field to zero (invalid value for a process ID). 146 */ 147 uint32_t libc_pid; 148 149 /* Process ID in context of which query is made. */ 150 uint32_t query_pid; 151 152 /* Code of the allocation routine, in context of which query has been made: 153 * 1 - free 154 * 2 - realloc 155 */ 156 uint32_t routine; 157 158 /* Address of memory allocation descriptor for the queried pointer. 159 * Descriptor, addressed by this field is initialized by the emulator in 160 * response to the query. 161 */ 162 MallocDesc* desc; 163 }; 164 165 /* Describes memory block that is being freed back to the heap. This structure 166 * is passed along with TRACE_DEV_REG_FREE_PTR event. The entire structure is 167 * initialized by the guest system before event is fired up. It is important to 168 * remember that same structure (an exact copy, except for replacing pointers 169 * with target_ulong) is also declared in the emulator's sources (file 170 * memcheck/memecheck_common.h). So, every time a change is made to any of these 171 * two declaration, another one must be also updated accordingly. 172 */ 173 struct MallocFree { 174 /* Pointer to be freed. */ 175 void* ptr; 176 177 /* Id of the process that initialized libc instance, in which this free 178 * is called. This field is used by the emulator to report errors in 179 * the course of TRACE_DEV_REG_FREE_PTR event handling. In case of an 180 * error, emulator sets this field to zero (invalid value for a process ID). 181 */ 182 uint32_t libc_pid; 183 184 /* Process ID in context of which memory is being freed. */ 185 uint32_t free_pid; 186 }; 187 188 // ============================================================================= 189 // Communication events 190 // ============================================================================= 191 192 /* Notifies the emulator that libc has been initialized for a process. 193 * Event's value parameter is PID for the process in context of which libc has 194 * been initialized. 195 */ 196 #define TRACE_DEV_REG_LIBC_INIT 1536 197 198 /* Notifies the emulator about new memory block been allocated. 199 * Event's value parameter points to MallocDesc instance that contains 200 * allocated block information. Note that 'libc_pid' field of the descriptor 201 * is used by emulator to report failure in handling this event. In case 202 * of a failure emulator will zero that field before completing this event. 203 */ 204 #define TRACE_DEV_REG_MALLOC 1537 205 206 /* Notifies the emulator about memory block being freed. 207 * Event's value parameter points to MallocFree descriptor that contains 208 * information about block that's being freed. Note that 'libc_pid' field 209 * of the descriptor is used by emulator to report failure in handling this 210 * event. In case of a failure emulator will zero that field before completing 211 * this event. 212 */ 213 #define TRACE_DEV_REG_FREE_PTR 1538 214 215 /* Queries the emulator about allocated memory block information. 216 * Event's value parameter points to MallocDescQuery descriptor that contains 217 * query parameters. Note that 'libc_pid' field of the descriptor is used by 218 * emulator to report failure in handling this event. In case of a failure 219 * emulator will zero that field before completing this event. 220 */ 221 #define TRACE_DEV_REG_QUERY_MALLOC 1539 222 223 /* Queries the emulator to print a string to its stdout. 224 * Event's value parameter points to a zero-terminated string to be printed. 225 */ 226 #define TRACE_DEV_REG_PRINT_USER_STR 1540 227 228 static void notify_qemu_string(const char* str); 229 static void qemu_log(int prio, const char* fmt, ...); 230 static void dump_malloc_descriptor(char* str, 231 size_t str_buf_size, 232 const MallocDesc* desc); 233 234 // ============================================================================= 235 // Macros 236 // ============================================================================= 237 238 /* Defines default size of allocation prefix. 239 * Note that we make prefix area quite large in order to increase chances of 240 * catching buffer overflow. */ 241 #define DEFAULT_PREFIX_SIZE (malloc_alignment * 4) 242 243 /* Defines default size of allocation suffix. 244 * Note that we make suffix area quite large in order to increase chances of 245 * catching buffer overflow. */ 246 #define DEFAULT_SUFFIX_SIZE (malloc_alignment * 4) 247 248 /* Debug tracing has been enabled by the emulator. */ 249 #define DEBUG_TRACING_ENABLED 0x00000001 250 /* Error tracing has been enabled by the emulator. */ 251 #define ERROR_TRACING_ENABLED 0x00000002 252 /* Info tracing has been enabled by the emulator. */ 253 #define INFO_TRACING_ENABLED 0x00000004 254 /* All tracing flags combined. */ 255 #define ALL_TRACING_ENABLED (DEBUG_TRACING_ENABLED | \ 256 ERROR_TRACING_ENABLED | \ 257 INFO_TRACING_ENABLED) 258 259 /* Prints a string to the emulator's stdout. 260 * In early stages of system loading, logging messages to logcat 261 * is not available, because ADB API has not been 262 * hooked up yet. So, in order to see such messages we need to print them to 263 * the emulator's stdout. 264 * Parameters passed to this macro are the same as parameters for printf 265 * routine. 266 */ 267 #define TR(...) \ 268 do { \ 269 char tr_str[4096]; \ 270 snprintf(tr_str, sizeof(tr_str), __VA_ARGS__); \ 271 tr_str[sizeof(tr_str) - 1] = '\0'; \ 272 notify_qemu_string(&tr_str[0]); \ 273 } while (0) 274 275 // ============================================================================= 276 // Logging macros. Note that we simultaneously log messages to ADB and emulator. 277 // ============================================================================= 278 279 /* 280 * Helper macros for checking if particular trace level is enabled. 281 */ 282 #define debug_LOG_ENABLED ((tracing_flags & DEBUG_TRACING_ENABLED) != 0) 283 #define error_LOG_ENABLED ((tracing_flags & ERROR_TRACING_ENABLED) != 0) 284 #define info_LOG_ENABLED ((tracing_flags & INFO_TRACING_ENABLED) != 0) 285 #define tracing_enabled(type) (type##_LOG_ENABLED) 286 287 /* 288 * Logging helper macros. 289 */ 290 #define qemu_debug_log(format, ...) \ 291 do { \ 292 __libc_format_log(ANDROID_LOG_DEBUG, "memcheck", (format), ##__VA_ARGS__); \ 293 if (tracing_flags & DEBUG_TRACING_ENABLED) { \ 294 qemu_log(ANDROID_LOG_DEBUG, (format), ##__VA_ARGS__); \ 295 } \ 296 } while (0) 297 298 #define qemu_error_log(format, ...) \ 299 do { \ 300 __libc_format_log(ANDROID_LOG_ERROR, "memcheck", (format), ##__VA_ARGS__); \ 301 if (tracing_flags & ERROR_TRACING_ENABLED) { \ 302 qemu_log(ANDROID_LOG_ERROR, (format), ##__VA_ARGS__); \ 303 } \ 304 } while (0) 305 306 #define qemu_info_log(format, ...) \ 307 do { \ 308 __libc_format_log(ANDROID_LOG_INFO, "memcheck", (format), ##__VA_ARGS__); \ 309 if (tracing_flags & INFO_TRACING_ENABLED) { \ 310 qemu_log(ANDROID_LOG_INFO, (format), ##__VA_ARGS__); \ 311 } \ 312 } while (0) 313 314 /* Logs message dumping MallocDesc instance at the end of the message. 315 * Param: 316 * type - Message type: debug, error, or info 317 * desc - MallocDesc instance to dump. 318 * fmt + rest - Formats message preceding dumped descriptor. 319 */ 320 #define log_mdesc(type, desc, fmt, ...) \ 321 do { \ 322 if (tracing_enabled(type)) { \ 323 char log_str[4096]; \ 324 __libc_format_buffer(log_str, sizeof(log_str), fmt, ##__VA_ARGS__); \ 325 log_str[sizeof(log_str) - 1] = '\0'; \ 326 size_t str_len = strlen(log_str); \ 327 dump_malloc_descriptor(log_str + str_len, \ 328 sizeof(log_str) - str_len, \ 329 (desc)); \ 330 type##_log("%s", log_str); \ 331 } \ 332 } while (0) 333 334 // ============================================================================= 335 // Static data 336 // ============================================================================= 337 338 /* Emulator's magic page address. 339 * This page (mapped on /dev/qemu_trace device) is used to fire up events 340 * in the emulator. */ 341 static volatile void* qtrace = NULL; 342 343 /* Cached PID of the process in context of which this libc instance 344 * has been initialized. */ 345 static uint32_t malloc_pid = 0; 346 347 /* Memory allocation alignment that is used in dlmalloc. 348 * This variable is updated by memcheck_initialize routine. */ 349 static uint32_t malloc_alignment = 8; 350 351 /* Tracing flags. These flags control which types of logging messages are 352 * enabled by the emulator. See XXX_TRACING_ENABLED for the values of flags 353 * stored in this variable. This variable is updated by memcheck_initialize 354 * routine. */ 355 static uint32_t tracing_flags = 0; 356 357 // ============================================================================= 358 // Static routines 359 // ============================================================================= 360 361 /* Gets pointer, returned to malloc caller for the given allocation decriptor. 362 * Param: 363 * desc - Allocation descriptor. 364 * Return: 365 * Pointer to the allocated memory returned to the malloc caller. 366 */ 367 static inline void* mallocdesc_user_ptr(const MallocDesc* desc) { 368 return static_cast<char*>(desc->ptr) + desc->prefix_size; 369 } 370 371 /* Gets size of memory block actually allocated from the heap for the given 372 * allocation decriptor. 373 * Param: 374 * desc - Allocation descriptor. 375 * Return: 376 * Size of memory block actually allocated from the heap. 377 */ 378 static inline uint32_t mallocdesc_alloc_size(const MallocDesc* desc) { 379 return desc->prefix_size + desc->requested_bytes + desc->suffix_size; 380 } 381 382 /* Gets pointer to the end of the allocated block for the given descriptor. 383 * Param: 384 * desc - Descriptor for the memory block, allocated in malloc handler. 385 * Return: 386 * Pointer to the end of (one byte past) the allocated block. 387 */ 388 static inline void* mallocdesc_alloc_end(const MallocDesc* desc) { 389 return static_cast<char*>(desc->ptr) + mallocdesc_alloc_size(desc); 390 } 391 392 /* Fires up an event in the emulator. 393 * Param: 394 * code - Event code (one of the TRACE_DEV_XXX). 395 * val - Event's value parameter. 396 */ 397 static inline void notify_qemu(uint32_t code, uint32_t val) { 398 if (NULL != qtrace) { 399 *(volatile uint32_t*)((uint32_t)qtrace + ((code - 1024) << 2)) = val; 400 } 401 } 402 403 /* Prints a zero-terminated string to the emulator's stdout (fires up 404 * TRACE_DEV_REG_PRINT_USER_STR event in the emulator). 405 * Param: 406 * str - Zero-terminated string to print. 407 */ 408 static void notify_qemu_string(const char* str) { 409 if (str != NULL) { 410 notify_qemu(TRACE_DEV_REG_PRINT_USER_STR, (uint32_t)str); 411 } 412 } 413 414 /* Fires up TRACE_DEV_REG_LIBC_INIT event in the emulator. 415 * Param: 416 * pid - ID of the process that initialized libc. 417 */ 418 static void notify_qemu_libc_initialized(uint32_t pid) { 419 notify_qemu(TRACE_DEV_REG_LIBC_INIT, pid); 420 } 421 422 /* Fires up TRACE_DEV_REG_MALLOC event in the emulator. 423 * Param: 424 * desc - Pointer to MallocDesc instance containing allocated block 425 * information. 426 * Return: 427 * Zero on success, or -1 on failure. Note that on failure libc_pid field of 428 * the desc parameter passed to this routine has been zeroed out by the 429 * emulator. 430 */ 431 static inline int notify_qemu_malloc(volatile MallocDesc* desc) { 432 desc->libc_pid = malloc_pid; 433 desc->allocator_pid = getpid(); 434 desc->av_count = 0; 435 notify_qemu(TRACE_DEV_REG_MALLOC, (uint32_t)desc); 436 437 /* Emulator reports failure by zeroing libc_pid field of the 438 * descriptor. */ 439 return desc->libc_pid != 0 ? 0 : -1; 440 } 441 442 /* Fires up TRACE_DEV_REG_FREE_PTR event in the emulator. 443 * Param: 444 * ptr - Pointer to the memory block that's being freed. 445 * Return: 446 * Zero on success, or -1 on failure. 447 */ 448 static inline int notify_qemu_free(void* ptr_to_free) { 449 volatile MallocFree free_desc; 450 451 free_desc.ptr = ptr_to_free; 452 free_desc.libc_pid = malloc_pid; 453 free_desc.free_pid = getpid(); 454 notify_qemu(TRACE_DEV_REG_FREE_PTR, (uint32_t)&free_desc); 455 456 /* Emulator reports failure by zeroing libc_pid field of the 457 * descriptor. */ 458 return free_desc.libc_pid != 0 ? 0 : -1; 459 } 460 461 /* Fires up TRACE_DEV_REG_QUERY_MALLOC event in the emulator. 462 * Param: 463 * ptr - Pointer to request allocation information for. 464 * desc - Pointer to MallocDesc instance that will receive allocation 465 * information. 466 * routine - Code of the allocation routine, in context of which query is made: 467 * 1 - free 468 * 2 - realloc 469 * Return: 470 * Zero on success, or -1 on failure. 471 */ 472 static inline int query_qemu_malloc_info(const void* ptr, MallocDesc* desc, uint32_t routine) { 473 volatile MallocDescQuery query; 474 475 query.ptr = ptr; 476 query.libc_pid = malloc_pid; 477 query.query_pid = getpid(); 478 query.routine = routine; 479 query.desc = desc; 480 notify_qemu(TRACE_DEV_REG_QUERY_MALLOC, (uint32_t)&query); 481 482 /* Emulator reports failure by zeroing libc_pid field of the 483 * descriptor. */ 484 return query.libc_pid != 0 ? 0 : -1; 485 } 486 487 /* Logs a message to emulator's stdout. 488 * Param: 489 * prio - Message priority (debug, info, or error) 490 * fmt + rest - Message format and parameters. 491 */ 492 static void qemu_log(int prio, const char* fmt, ...) { 493 va_list ap; 494 char buf[4096]; 495 const char* prefix; 496 497 /* Choose message prefix depending on the priority value. */ 498 switch (prio) { 499 case ANDROID_LOG_ERROR: 500 if (!tracing_enabled(error)) { 501 return; 502 } 503 prefix = "E"; 504 break; 505 case ANDROID_LOG_INFO: 506 if (!tracing_enabled(info)) { 507 return; 508 } 509 prefix = "I"; 510 break; 511 case ANDROID_LOG_DEBUG: 512 default: 513 if (!tracing_enabled(debug)) { 514 return; 515 } 516 prefix = "D"; 517 break; 518 } 519 520 va_start(ap, fmt); 521 vsnprintf(buf, sizeof(buf), fmt, ap); 522 va_end(ap); 523 buf[sizeof(buf) - 1] = '\0'; 524 525 TR("%s/memcheck: %s\n", prefix, buf); 526 } 527 528 /* Dumps content of memory allocation descriptor to a string. 529 * Param: 530 * str - String to dump descriptor to. 531 * str_buf_size - Size of string's buffer. 532 * desc - Descriptor to dump. 533 */ 534 static void dump_malloc_descriptor(char* str, size_t str_buf_size, const MallocDesc* desc) { 535 if (str_buf_size) { 536 snprintf(str, str_buf_size, 537 "MDesc: %p: %X <-> %X [%u + %u + %u] by pid=%03u in libc_pid=%03u", 538 mallocdesc_user_ptr(desc), (uint32_t)desc->ptr, 539 (uint32_t)mallocdesc_alloc_end(desc), desc->prefix_size, 540 desc->requested_bytes, desc->suffix_size, desc->allocator_pid, 541 desc->libc_pid); 542 str[str_buf_size - 1] = '\0'; 543 } 544 } 545 546 #if TEST_ACCESS_VIOLATIONS 547 /* Causes an access violation on allocation descriptor, and verifies that 548 * violation has been detected by memory checker in the emulator. 549 */ 550 static void test_access_violation(const MallocDesc* desc) { 551 MallocDesc desc_chk; 552 char ch; 553 volatile char* prefix = (volatile char*)desc->ptr; 554 volatile char* suffix = (volatile char*)mallocdesc_user_ptr(desc) + 555 desc->requested_bytes; 556 /* We're causing AV by reading from the prefix and suffix areas of the 557 * allocated block. This should produce two access violations, so when we 558 * get allocation descriptor from QEMU, av_counter should be bigger than 559 * av_counter of the original descriptor by 2. */ 560 ch = *prefix; 561 ch = *suffix; 562 if (!query_qemu_malloc_info(mallocdesc_user_ptr(desc), &desc_chk, 2) && 563 desc_chk.av_count != (desc->av_count + 2)) { 564 log_mdesc(error, &desc_chk, 565 "<libc_pid=%03u, pid=%03u>: malloc: Access violation test failed:\n" 566 "Expected violations count %u is not equal to the actually reported %u", 567 malloc_pid, getpid(), desc->av_count + 2, 568 desc_chk.av_count); 569 } 570 } 571 #endif // TEST_ACCESS_VIOLATIONS 572 573 // ============================================================================= 574 // API routines 575 // ============================================================================= 576 577 extern "C" void* qemu_instrumented_malloc(size_t bytes); 578 extern "C" void qemu_instrumented_free(void* mem); 579 extern "C" void* qemu_instrumented_calloc(size_t n_elements, size_t elem_size); 580 extern "C" void* qemu_instrumented_realloc(void* mem, size_t bytes); 581 extern "C" void* qemu_instrumented_memalign(size_t alignment, size_t bytes); 582 extern "C" size_t qemu_instrumented_malloc_usable_size(const void* mem); 583 584 /* Initializes malloc debugging instrumentation for the emulator. 585 * This routine is called from malloc_init_impl routine implemented in 586 * bionic/libc/bionic/malloc_debug_common.c when malloc debugging gets 587 * initialized for a process. The way malloc debugging implementation is 588 * done, it is guaranteed that this routine will be called just once per 589 * process. 590 * Return: 591 * 0 on success, or -1 on failure. 592 */ 593 extern "C" int malloc_debug_initialize() { 594 /* We will be using emulator's magic page to report memory allocation 595 * activities. In essence, what magic page does, it translates writes to 596 * the memory mapped spaces into writes to an I/O port that emulator 597 * "listens to" on the other end. Note that until we open and map that 598 * device, logging to emulator's stdout will not be available. */ 599 int fd = open("/dev/qemu_trace", O_RDWR); 600 if (fd < 0) { 601 error_log("Unable to open /dev/qemu_trace"); 602 return -1; 603 } else { 604 qtrace = mmap(NULL, PAGESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 605 close(fd); 606 607 if (qtrace == MAP_FAILED) { 608 qtrace = NULL; 609 error_log("Unable to mmap /dev/qemu_trace"); 610 return -1; 611 } 612 } 613 614 /* Cache pid of the process this library has been initialized for. */ 615 malloc_pid = getpid(); 616 617 return 0; 618 } 619 620 /* Completes malloc debugging instrumentation for the emulator. 621 * Note that this routine is called after successful return from 622 * malloc_debug_initialize, which means that connection to the emulator via 623 * "magic page" has been established. 624 * Param: 625 * alignment - Alignment requirement set for memiry allocations. 626 * memcheck_param - Emulator's -memcheck option parameters. This string 627 * contains abbreviation for guest events that are enabled for tracing. 628 * Return: 629 * 0 on success, or -1 on failure. 630 */ 631 extern "C" int memcheck_initialize(int alignment, const char* memcheck_param) { 632 malloc_alignment = alignment; 633 634 /* Parse -memcheck parameter for the guest tracing flags. */ 635 while (*memcheck_param != '\0') { 636 switch (*memcheck_param) { 637 case 'a': 638 // Enable all messages from the guest. 639 tracing_flags |= ALL_TRACING_ENABLED; 640 break; 641 case 'd': 642 // Enable debug messages from the guest. 643 tracing_flags |= DEBUG_TRACING_ENABLED; 644 break; 645 case 'e': 646 // Enable error messages from the guest. 647 tracing_flags |= ERROR_TRACING_ENABLED; 648 break; 649 case 'i': 650 // Enable info messages from the guest. 651 tracing_flags |= INFO_TRACING_ENABLED; 652 break; 653 default: 654 break; 655 } 656 if (tracing_flags == ALL_TRACING_ENABLED) { 657 break; 658 } 659 memcheck_param++; 660 } 661 662 notify_qemu_libc_initialized(malloc_pid); 663 664 qemu_debug_log("Instrumented for pid=%03u: malloc=%p, free=%p, calloc=%p, realloc=%p, memalign=%p", 665 malloc_pid, qemu_instrumented_malloc, qemu_instrumented_free, 666 qemu_instrumented_calloc, qemu_instrumented_realloc, 667 qemu_instrumented_memalign); 668 669 return 0; 670 } 671 672 /* This routine serves as entry point for 'malloc'. 673 * Primary responsibility of this routine is to allocate requested number of 674 * bytes (plus prefix, and suffix guards), and report allocation to the 675 * emulator. 676 */ 677 extern "C" void* qemu_instrumented_malloc(size_t bytes) { 678 MallocDesc desc; 679 680 /* Initialize block descriptor and allocate memory. Note that dlmalloc 681 * returns a valid pointer on zero allocation. Lets mimic this behavior. */ 682 desc.prefix_size = DEFAULT_PREFIX_SIZE; 683 desc.requested_bytes = bytes; 684 desc.suffix_size = DEFAULT_SUFFIX_SIZE; 685 desc.ptr = dlmalloc(mallocdesc_alloc_size(&desc)); 686 if (desc.ptr == NULL) { 687 qemu_error_log("<libc_pid=%03u, pid=%03u> malloc(%u): dlmalloc(%u) failed.", 688 malloc_pid, getpid(), bytes, mallocdesc_alloc_size(&desc)); 689 return NULL; 690 } 691 692 // Fire up event in the emulator. 693 if (notify_qemu_malloc(&desc)) { 694 log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: malloc: notify_malloc failed for ", 695 malloc_pid, getpid()); 696 dlfree(desc.ptr); 697 return NULL; 698 } else { 699 #if TEST_ACCESS_VIOLATIONS 700 test_access_violation(&desc); 701 #endif // TEST_ACCESS_VIOLATIONS 702 log_mdesc(info, &desc, "+++ <libc_pid=%03u, pid=%03u> malloc(%u) -> ", 703 malloc_pid, getpid(), bytes); 704 return mallocdesc_user_ptr(&desc); 705 } 706 } 707 708 /* This routine serves as entry point for 'malloc'. 709 * Primary responsibility of this routine is to free requested memory, and 710 * report free block to the emulator. 711 */ 712 extern "C" void qemu_instrumented_free(void* mem) { 713 MallocDesc desc; 714 715 if (mem == NULL) { 716 // Just let go NULL free 717 dlfree(mem); 718 return; 719 } 720 721 // Query emulator for the freeing block information. 722 if (query_qemu_malloc_info(mem, &desc, 1)) { 723 error_log("<libc_pid=%03u, pid=%03u>: free(%p) query_info failed.", 724 malloc_pid, getpid(), mem); 725 return; 726 } 727 728 #if TEST_ACCESS_VIOLATIONS 729 test_access_violation(&desc); 730 #endif // TEST_ACCESS_VIOLATIONS 731 732 /* Make sure that pointer that's being freed matches what we expect 733 * for this memory block. Note that this violation should be already 734 * caught in the emulator. */ 735 if (mem != mallocdesc_user_ptr(&desc)) { 736 log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: free(%p) is invalid for ", 737 malloc_pid, getpid(), mem); 738 return; 739 } 740 741 // Fire up event in the emulator and free block that was actually allocated. 742 if (notify_qemu_free(mem)) { 743 log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: free(%p) notify_free failed for ", 744 malloc_pid, getpid(), mem); 745 } else { 746 log_mdesc(info, &desc, "--- <libc_pid=%03u, pid=%03u> free(%p) -> ", 747 malloc_pid, getpid(), mem); 748 dlfree(desc.ptr); 749 } 750 } 751 752 /* This routine serves as entry point for 'calloc'. 753 * This routine behaves similarly to qemu_instrumented_malloc. 754 */ 755 extern "C" void* qemu_instrumented_calloc(size_t n_elements, size_t elem_size) { 756 if (n_elements == 0 || elem_size == 0) { 757 // Just let go zero bytes allocation. 758 qemu_info_log("::: <libc_pid=%03u, pid=%03u>: Zero calloc redir to malloc", 759 malloc_pid, getpid()); 760 return qemu_instrumented_malloc(0); 761 } 762 763 /* Fail on overflow - just to be safe even though this code runs only 764 * within the debugging C library, not the production one */ 765 if (n_elements && MAX_SIZE_T / n_elements < elem_size) { 766 return NULL; 767 } 768 769 MallocDesc desc; 770 771 /* Calculating prefix size. The trick here is to make sure that 772 * first element (returned to the caller) is properly aligned. */ 773 if (DEFAULT_PREFIX_SIZE >= elem_size) { 774 /* If default alignment is bigger than element size, we will 775 * set our prefix size to the default alignment size. */ 776 desc.prefix_size = DEFAULT_PREFIX_SIZE; 777 /* For the suffix we will use whatever bytes remain from the prefix 778 * allocation size, aligned to the size of an element, plus the usual 779 * default suffix size. */ 780 desc.suffix_size = (DEFAULT_PREFIX_SIZE % elem_size) + 781 DEFAULT_SUFFIX_SIZE; 782 } else { 783 /* Make sure that prefix, and suffix sizes is at least elem_size, 784 * and first element returned to the caller is properly aligned. */ 785 desc.prefix_size = elem_size + DEFAULT_PREFIX_SIZE - 1; 786 desc.prefix_size &= ~(malloc_alignment - 1); 787 desc.suffix_size = DEFAULT_SUFFIX_SIZE; 788 } 789 desc.requested_bytes = n_elements * elem_size; 790 size_t total_size = desc.requested_bytes + desc.prefix_size + desc.suffix_size; 791 size_t total_elements = total_size / elem_size; 792 total_size %= elem_size; 793 if (total_size != 0) { 794 // Add extra to the suffix area. 795 total_elements++; 796 desc.suffix_size += (elem_size - total_size); 797 } 798 desc.ptr = dlcalloc(total_elements, elem_size); 799 if (desc.ptr == NULL) { 800 error_log("<libc_pid=%03u, pid=%03u> calloc: dlcalloc(%u(%u), %u) (prx=%u, sfx=%u) failed.", 801 malloc_pid, getpid(), n_elements, total_elements, elem_size, 802 desc.prefix_size, desc.suffix_size); 803 return NULL; 804 } 805 806 if (notify_qemu_malloc(&desc)) { 807 log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: calloc(%u(%u), %u): notify_malloc failed for ", 808 malloc_pid, getpid(), n_elements, total_elements, elem_size); 809 dlfree(desc.ptr); 810 return NULL; 811 } else { 812 #if TEST_ACCESS_VIOLATIONS 813 test_access_violation(&desc); 814 #endif // TEST_ACCESS_VIOLATIONS 815 log_mdesc(info, &desc, "### <libc_pid=%03u, pid=%03u> calloc(%u(%u), %u) -> ", 816 malloc_pid, getpid(), n_elements, total_elements, elem_size); 817 return mallocdesc_user_ptr(&desc); 818 } 819 } 820 821 /* This routine serves as entry point for 'realloc'. 822 * This routine behaves similarly to qemu_instrumented_free + 823 * qemu_instrumented_malloc. Note that this modifies behavior of "shrinking" an 824 * allocation, but overall it doesn't seem to matter, as caller of realloc 825 * should not expect that pointer returned after shrinking will remain the same. 826 */ 827 extern "C" void* qemu_instrumented_realloc(void* mem, size_t bytes) { 828 MallocDesc new_desc; 829 MallocDesc cur_desc; 830 size_t to_copy; 831 void* ret; 832 833 if (mem == NULL) { 834 // Nothing to realloc. just do regular malloc. 835 qemu_info_log("::: <libc_pid=%03u, pid=%03u>: realloc(%p, %u) redir to malloc", 836 malloc_pid, getpid(), mem, bytes); 837 return qemu_instrumented_malloc(bytes); 838 } 839 840 if (bytes == 0) { 841 // This is a "free" condition. 842 qemu_info_log("::: <libc_pid=%03u, pid=%03u>: realloc(%p, %u) redir to free and malloc", 843 malloc_pid, getpid(), mem, bytes); 844 qemu_instrumented_free(mem); 845 846 // This is what dlrealloc does for a "free" realloc. 847 return NULL; 848 } 849 850 // Query emulator for the reallocating block information. 851 if (query_qemu_malloc_info(mem, &cur_desc, 2)) { 852 // Note that this violation should be already caught in the emulator. 853 error_log("<libc_pid=%03u, pid=%03u>: realloc(%p, %u) query_info failed.", 854 malloc_pid, getpid(), mem, bytes); 855 return NULL; 856 } 857 858 #if TEST_ACCESS_VIOLATIONS 859 test_access_violation(&cur_desc); 860 #endif // TEST_ACCESS_VIOLATIONS 861 862 /* Make sure that reallocating pointer value is what we would expect 863 * for this memory block. Note that this violation should be already caught 864 * in the emulator.*/ 865 if (mem != mallocdesc_user_ptr(&cur_desc)) { 866 log_mdesc(error, &cur_desc, "<libc_pid=%03u, pid=%03u>: realloc(%p, %u) is invalid for ", 867 malloc_pid, getpid(), mem, bytes); 868 return NULL; 869 } 870 871 /* TODO: We're a bit inefficient here, always allocating new block from 872 * the heap. If this realloc shrinks current buffer, we can just do the 873 * shrinking "in place", adjusting suffix_size in the allocation descriptor 874 * for this block that is stored in the emulator. */ 875 876 // Initialize descriptor for the new block. 877 new_desc.prefix_size = DEFAULT_PREFIX_SIZE; 878 new_desc.requested_bytes = bytes; 879 new_desc.suffix_size = DEFAULT_SUFFIX_SIZE; 880 new_desc.ptr = dlmalloc(mallocdesc_alloc_size(&new_desc)); 881 if (new_desc.ptr == NULL) { 882 log_mdesc(error, &cur_desc, "<libc_pid=%03u, pid=%03u>: realloc(%p, %u): dlmalloc(%u) failed on ", 883 malloc_pid, getpid(), mem, bytes, 884 mallocdesc_alloc_size(&new_desc)); 885 return NULL; 886 } 887 ret = mallocdesc_user_ptr(&new_desc); 888 889 // Copy user data from old block to the new one. 890 to_copy = bytes < cur_desc.requested_bytes ? bytes : 891 cur_desc.requested_bytes; 892 if (to_copy != 0) { 893 memcpy(ret, mallocdesc_user_ptr(&cur_desc), to_copy); 894 } 895 896 // Register new block with emulator. 897 if (notify_qemu_malloc(&new_desc)) { 898 log_mdesc(error, &new_desc, "<libc_pid=%03u, pid=%03u>: realloc(%p, %u) notify_malloc failed -> ", 899 malloc_pid, getpid(), mem, bytes); 900 log_mdesc(error, &cur_desc, " <- "); 901 dlfree(new_desc.ptr); 902 return NULL; 903 } 904 905 #if TEST_ACCESS_VIOLATIONS 906 test_access_violation(&new_desc); 907 #endif // TEST_ACCESS_VIOLATIONS 908 909 // Free old block. 910 if (notify_qemu_free(mem)) { 911 log_mdesc(error, &cur_desc, "<libc_pid=%03u, pid=%03u>: realloc(%p, %u): notify_free failed for ", 912 malloc_pid, getpid(), mem, bytes); 913 /* Since we registered new decriptor with the emulator, we need 914 * to unregister it before freeing newly allocated block. */ 915 notify_qemu_free(mallocdesc_user_ptr(&new_desc)); 916 dlfree(new_desc.ptr); 917 return NULL; 918 } 919 dlfree(cur_desc.ptr); 920 921 log_mdesc(info, &new_desc, "=== <libc_pid=%03u, pid=%03u>: realloc(%p, %u) -> ", 922 malloc_pid, getpid(), mem, bytes); 923 log_mdesc(info, &cur_desc, " <- "); 924 925 return ret; 926 } 927 928 /* This routine serves as entry point for 'memalign'. 929 * This routine behaves similarly to qemu_instrumented_malloc. 930 */ 931 extern "C" void* qemu_instrumented_memalign(size_t alignment, size_t bytes) { 932 MallocDesc desc; 933 934 if (bytes == 0) { 935 // Just let go zero bytes allocation. 936 qemu_info_log("::: <libc_pid=%03u, pid=%03u>: memalign(%X, %u) redir to malloc", 937 malloc_pid, getpid(), alignment, bytes); 938 return qemu_instrumented_malloc(0); 939 } 940 941 /* Prefix size for aligned allocation must be equal to the alignment used 942 * for allocation in order to ensure proper alignment of the returned 943 * pointer, in case that alignment requirement is greater than prefix 944 * size. */ 945 desc.prefix_size = alignment > DEFAULT_PREFIX_SIZE ? alignment : 946 DEFAULT_PREFIX_SIZE; 947 desc.requested_bytes = bytes; 948 desc.suffix_size = DEFAULT_SUFFIX_SIZE; 949 desc.ptr = dlmemalign(desc.prefix_size, mallocdesc_alloc_size(&desc)); 950 if (desc.ptr == NULL) { 951 error_log("<libc_pid=%03u, pid=%03u> memalign(%X, %u): dlmalloc(%u) failed.", 952 malloc_pid, getpid(), alignment, bytes, 953 mallocdesc_alloc_size(&desc)); 954 return NULL; 955 } 956 if (notify_qemu_malloc(&desc)) { 957 log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: memalign(%X, %u): notify_malloc failed for ", 958 malloc_pid, getpid(), alignment, bytes); 959 dlfree(desc.ptr); 960 return NULL; 961 } 962 963 #if TEST_ACCESS_VIOLATIONS 964 test_access_violation(&desc); 965 #endif // TEST_ACCESS_VIOLATIONS 966 967 log_mdesc(info, &desc, "@@@ <libc_pid=%03u, pid=%03u> memalign(%X, %u) -> ", 968 malloc_pid, getpid(), alignment, bytes); 969 return mallocdesc_user_ptr(&desc); 970 } 971 972 extern "C" size_t qemu_instrumented_malloc_usable_size(const void* mem) { 973 MallocDesc cur_desc; 974 975 // Query emulator for the reallocating block information. 976 if (query_qemu_malloc_info(mem, &cur_desc, 2)) { 977 // Note that this violation should be already caught in the emulator. 978 error_log("<libc_pid=%03u, pid=%03u>: malloc_usable_size(%p) query_info failed.", 979 malloc_pid, getpid(), mem); 980 return 0; 981 } 982 983 /* Make sure that reallocating pointer value is what we would expect 984 * for this memory block. Note that this violation should be already caught 985 * in the emulator.*/ 986 if (mem != mallocdesc_user_ptr(&cur_desc)) { 987 log_mdesc(error, &cur_desc, "<libc_pid=%03u, pid=%03u>: malloc_usable_size(%p) is invalid for ", 988 malloc_pid, getpid(), mem); 989 return 0; 990 } 991 992 /* during instrumentation, we can't really report anything more than requested_bytes */ 993 return cur_desc.requested_bytes; 994 } 995