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