1/* Copyright (C) 2007-2010 The Android Open Source Project
2**
3** This software is licensed under the terms of the GNU General Public
4** License version 2, as published by the Free Software Foundation, and
5** may be copied, distributed, and modified under those terms.
6**
7** This program is distributed in the hope that it will be useful,
8** but WITHOUT ANY WARRANTY; without even the implied warranty of
9** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10** GNU General Public License for more details.
11*/
12
13/*
14 * Contains implementation of memory checking framework in the emulator.
15 */
16
17#include "qemu-queue.h"
18#include "qemu_file.h"
19#include "elff_api.h"
20#include "memcheck.h"
21#include "memcheck_proc_management.h"
22#include "memcheck_util.h"
23#include "memcheck_logging.h"
24
25// =============================================================================
26// Global data
27// =============================================================================
28
29/* Controls what messages from the guest should be printed to emulator's
30 * stdout. This variable holds a combinations of TRACE_LIBC_XXX flags. */
31uint32_t trace_flags = 0;
32
33/* Global flag, indicating whether or not memchecking has been enabled
34 * for the current emulator session. 1 means that memchecking has been enabled,
35 * 0 means that memchecking has not been enabled. */
36int memcheck_enabled = 0;
37
38/* Global flag, indicating whether or not __ld/__stx_mmu should be instrumented
39 * for checking for access violations. If read / write access violation check
40 * has been disabled by -memcheck flags, there is no need to instrument mmu
41 * routines and waste performance.
42 * 1 means that instrumenting is required, 0 means that instrumenting is not
43 * required. */
44int memcheck_instrument_mmu = 0;
45
46/* Global flag, indicating whether or not memchecker is collecting call stack.
47 * 1 - call stack is being collected, 0 means that stack is not being
48 * collected. */
49int memcheck_watch_call_stack = 1;
50
51// =============================================================================
52// Static routines.
53// =============================================================================
54
55/* Prints invalid pointer access violation information.
56 * Param:
57 *  proc - Process that caused access violation.
58 *  ptr - Pointer that caused access violation.
59 *  routine - If 1, access violation has occurred in 'free' routine.
60 *      If 2, access violation has occurred in 'realloc' routine.
61 */
62static void
63av_invalid_pointer(ProcDesc* proc, target_ulong ptr, int routine)
64{
65    if (trace_flags & TRACE_CHECK_INVALID_PTR_ENABLED) {
66        printf("memcheck: Access violation is detected in process %s[pid=%u]:\n"
67          "  INVALID POINTER 0x%08X is used in '%s' operation.\n"
68          "  Allocation descriptor for this pointer has not been found in the\n"
69          "  allocation map for the process. Most likely, this is an attempt\n"
70          "  to %s a pointer that has been freed.\n",
71          proc->image_path, proc->pid, ptr, routine == 1 ? "free" : "realloc",
72          routine == 1 ? "free" : "reallocate");
73    }
74}
75
76/* Prints read / write access violation information.
77 * Param:
78 *  proc - Process that caused access violation.
79 *  desc - Allocation descriptor for the violation.
80 *  addr - Address at which vilation has occurred.
81 *  data_size - Size of data accessed at the 'addr'.
82 *  val - If access violation has occurred at write operation, this parameter
83 *      contains value that's being written to 'addr'. For read violation this
84 *      parameter is not used.
85 *  retaddr - Code address (in TB) where access violation has occurred.
86 *  is_read - If 1, access violation has occurred when memory at 'addr' has been
87 *      read. If 0, access violation has occurred when memory was written.
88 */
89static void
90av_access_violation(ProcDesc* proc,
91                    MallocDescEx* desc,
92                    target_ulong addr,
93                    uint32_t data_size,
94                    uint64_t val,
95                    target_ulong retaddr,
96                    int is_read)
97{
98    target_ulong vaddr;
99    Elf_AddressInfo elff_info;
100    ELFF_HANDLE elff_handle = NULL;
101
102    desc->malloc_desc.av_count++;
103    if ((is_read && !(trace_flags & TRACE_CHECK_READ_VIOLATION_ENABLED)) ||
104        (!is_read && !(trace_flags & TRACE_CHECK_WRITE_VIOLATION_ENABLED))) {
105        return;
106    }
107
108    /* Convert host address to guest address. */
109    vaddr = memcheck_tpc_to_gpc(retaddr);
110    printf("memcheck: Access violation is detected in process %s[pid=%u]:\n",
111           proc->image_path, proc->pid);
112
113    /* Obtain routine, filename / line info for the address. */
114    const MMRangeDesc* rdesc = procdesc_get_range_desc(proc, vaddr);
115    if (rdesc != NULL) {
116        int elff_res;
117        printf("  In module %s at address 0x%08X\n", rdesc->path, vaddr);
118        elff_res =
119          memcheck_get_address_info(vaddr, rdesc, &elff_info, &elff_handle);
120        if (elff_res == 0) {
121            printf("  In routine %s in %s/%s:%u\n",
122                   elff_info.routine_name, elff_info.dir_name,
123                   elff_info.file_name, elff_info.line_number);
124            if (elff_info.inline_stack != NULL) {
125                const Elf_InlineInfo* inl = elff_info.inline_stack;
126                int index = 0;
127                for (; inl[index].routine_name != NULL; index++) {
128                    char align[64];
129                    size_t set_align = 4 + index * 2;
130                    if (set_align >= sizeof(align)) {
131                        set_align = sizeof(align) -1;
132                    }
133                    memset(align, ' ', set_align);
134                    align[set_align] = '\0';
135                    printf("%s", align);
136                    if (inl[index].inlined_in_file == NULL) {
137                        printf("inlined to %s in unknown location\n",
138                               inl[index].routine_name);
139                    } else {
140                        printf("inlined to %s in %s/%s:%u\n",
141                               inl[index].routine_name,
142                               inl[index].inlined_in_file_dir,
143                               inl[index].inlined_in_file,
144                               inl[index].inlined_at_line);
145                    }
146                }
147            }
148            elff_free_pc_address_info(elff_handle, &elff_info);
149            elff_close(elff_handle);
150        } else if (elff_res == 1) {
151            printf("  Unable to obtain routine information. Symbols file is not found.\n");
152        } else {
153            printf("  Unable to obtain routine information.\n"
154                   "  Symbols file doesn't contain debugging information for address 0x%08X.\n",
155                    mmrangedesc_get_module_offset(rdesc, vaddr));
156        }
157    } else {
158        printf("  In unknown module at address 0x%08X\n", vaddr);
159    }
160
161    printf("  Process attempts to %s %u bytes %s address 0x%08X\n",
162           is_read ? "read" : "write", data_size,
163           is_read ? "from" : "to", addr);
164    printf("  Accessed range belongs to the %s guarding area of allocated block.\n",
165           addr < (target_ulong)mallocdesc_get_user_ptr(&desc->malloc_desc) ?
166                "prefix" : "suffix");
167    printf("  Allocation descriptor for this violation:\n");
168    memcheck_dump_malloc_desc(desc, 1, 0);
169}
170
171/* Validates access to a guest address.
172 * Param:
173 *  addr - Virtual address in the guest space where memory is accessed.
174 *  data_size - Size of the accessed data.
175 *  proc_ptr - Upon exit from this routine contains pointer to the process
176 *      descriptor for the current process, or NULL, if no such descriptor has
177 *      been found.
178 *  desc_ptr - Upon exit from this routine contains pointer to the allocation
179 *      descriptor matching given address range, or NULL, if allocation
180 *      descriptor for the validated memory range has not been found.
181 * Return:
182 *  0 if access to the given guest address range doesn't violate anything, or
183 *  1 if given guest address range doesn't match any entry in the current
184 *      process allocation descriptors map, or
185 *  -1 if a violation has been detected.
186 */
187static int
188memcheck_common_access_validation(target_ulong addr,
189                                  uint32_t data_size,
190                                  ProcDesc** proc_ptr,
191                                  MallocDescEx** desc_ptr)
192{
193    MallocDescEx* desc;
194    target_ulong validating_range_end;
195    target_ulong user_range_end;
196
197    ProcDesc* proc = get_current_process();
198    *proc_ptr = proc;
199    if (proc == NULL) {
200        *desc_ptr = NULL;
201        return 1;
202    }
203
204    desc = procdesc_find_malloc_for_range(proc, addr, data_size);
205    *desc_ptr = desc;
206    if (desc == NULL) {
207        return 1;
208    }
209
210    /* Verify that validating address range doesn't start before the address
211     * available to the user. */
212    if (addr < mallocdesc_get_user_ptr(&desc->malloc_desc)) {
213        // Stepped on the prefix guarding area.
214        return -1;
215    }
216
217    validating_range_end = addr + data_size;
218    user_range_end = mallocdesc_get_user_alloc_end(&desc->malloc_desc);
219
220    /* Verify that validating address range ends inside the user block.
221     * We may step on the suffix guarding area because of alignment issue.
222     * For example, the application code reads last byte in the allocated block
223     * with something like this:
224     *
225     *      char last_byte_value = *(char*)last_byte_address;
226     *
227     * and this code got compiled into something like this:
228     *
229     *      mov eax, [last_byte_address];
230     *      mov [last_byte_value], al;
231     *
232     * In this case we will catch a read from the suffix area, even though
233     * there were no errors in the code. So, in order to prevent such "false
234     * negative" alarms, lets "forgive" this violation.
235     * There is one bad thing about this "forgivness" though, as it may very
236     * well be, that in real life some of these "out of bound" bytes will cross
237     * page boundaries, marching into a page that has not been mapped to the
238     * process.
239     */
240    if (validating_range_end <= user_range_end) {
241        // Validating address range is fully contained inside the user block.
242        return 0;
243    }
244
245    /* Lets see if this AV is caused by an alignment issue.*/
246    if ((validating_range_end - user_range_end) < data_size) {
247        /* Could be an alignment. */
248        return 0;
249    }
250
251    return -1;
252}
253
254/* Checks if process has allocation descriptors for pages defined by a buffer.
255 * Param:
256 *  addr - Starting address of a buffer.
257 *  buf_size - Buffer size.
258 * Return:
259 *  1 if process has allocations descriptors for pages defined by a buffer, or
260 *  0 if pages containing given buffer don't have any memory allocations in
261 *  them.
262 */
263static inline int
264procdesc_contains_allocs(ProcDesc* proc, target_ulong addr, uint32_t buf_size) {
265    if (proc != NULL) {
266        // Beginning of the page containing last byte in range.
267        const target_ulong end_page = (addr + buf_size - 1) & TARGET_PAGE_MASK;
268        // Adjust beginning of the range to the beginning of the page.
269        addr &= TARGET_PAGE_MASK;
270        // Total size of range to check for descriptors.
271        buf_size = end_page - addr + TARGET_PAGE_SIZE + 1;
272        return procdesc_find_malloc_for_range(proc, addr, buf_size) ? 1 : 0;
273    } else {
274        return 0;
275    }
276}
277
278// =============================================================================
279// Memchecker API.
280// =============================================================================
281
282void
283memcheck_init(const char* tracing_flags)
284{
285    if (*tracing_flags == '0') {
286        // Memchecker is disabled.
287        return;
288    } else if (*tracing_flags == '1') {
289        // Set default tracing.
290        trace_flags = TRACE_CHECK_LEAK_ENABLED             |
291                      TRACE_CHECK_READ_VIOLATION_ENABLED   |
292                      TRACE_CHECK_INVALID_PTR_ENABLED      |
293                      TRACE_CHECK_WRITE_VIOLATION_ENABLED;
294    }
295
296    // Parse -memcheck option params, converting them into tracing flags.
297    while (*tracing_flags) {
298        switch (*tracing_flags) {
299            case 'A':
300                // Enable all emulator's tracing messages.
301                trace_flags |= TRACE_ALL_ENABLED;
302                break;
303            case 'F':
304                // Enable fork() tracing.
305                trace_flags |= TRACE_PROC_FORK_ENABLED;
306                break;
307            case 'S':
308                // Enable guest process staring tracing.
309                trace_flags |= TRACE_PROC_START_ENABLED;
310                break;
311            case 'E':
312                // Enable guest process exiting tracing.
313                trace_flags |= TRACE_PROC_EXIT_ENABLED;
314                break;
315            case 'C':
316                // Enable clone() tracing.
317                trace_flags |= TRACE_PROC_CLONE_ENABLED;
318                break;
319            case 'N':
320                // Enable new PID allocation tracing.
321                trace_flags |= TRACE_PROC_NEW_PID_ENABLED;
322                break;
323            case 'B':
324                // Enable libc.so initialization tracing.
325                trace_flags |= TRACE_PROC_LIBC_INIT_ENABLED;
326                break;
327            case 'L':
328                // Enable memory leaks tracing.
329                trace_flags |= TRACE_CHECK_LEAK_ENABLED;
330                break;
331            case 'I':
332                // Enable invalid free / realloc pointer tracing.
333                trace_flags |= TRACE_CHECK_INVALID_PTR_ENABLED;
334                break;
335            case 'R':
336                // Enable reading violations tracing.
337                trace_flags |= TRACE_CHECK_READ_VIOLATION_ENABLED;
338                break;
339            case 'W':
340                // Enable writing violations tracing.
341                trace_flags |= TRACE_CHECK_WRITE_VIOLATION_ENABLED;
342                break;
343            case 'M':
344                // Enable module mapping tracing.
345                trace_flags |= TRACE_PROC_MMAP_ENABLED;
346                break;
347            default:
348                break;
349        }
350        if (trace_flags == TRACE_ALL_ENABLED) {
351            break;
352        }
353        tracing_flags++;
354    }
355
356    /* Lets see if we need to instrument MMU, injecting memory access checking.
357     * We instrument MMU only if we monitor read, or write memory access. */
358    if (trace_flags & (TRACE_CHECK_READ_VIOLATION_ENABLED |
359                       TRACE_CHECK_WRITE_VIOLATION_ENABLED)) {
360        memcheck_instrument_mmu = 1;
361    } else {
362        memcheck_instrument_mmu = 0;
363    }
364
365    memcheck_init_proc_management();
366
367    /* Lets check env. variables needed for memory checking. */
368    if (getenv("ANDROID_PROJECT_OUT") == NULL) {
369        printf("memcheck: Missing ANDROID_PROJECT_OUT environment variable, that is used\n"
370               "to calculate path to symbol files.\n");
371    }
372
373    // Always set this flag at the very end of the initialization!
374    memcheck_enabled = 1;
375}
376
377void
378memcheck_guest_libc_initialized(uint32_t pid)
379{
380    ProcDesc* proc = get_process_from_pid(pid);
381    if (proc == NULL) {
382        ME("memcheck: Unable to obtain process for libc_init pid=%u", pid);
383        return;
384    }
385    proc->flags |= PROC_FLAG_LIBC_INITIALIZED;
386
387    /* When process initializes its own libc.so instance, it means that now
388     * it has fresh heap. So, at this point we must get rid of all entries
389     * (inherited and transition) that were collected in this process'
390     * allocation descriptors map. */
391    procdesc_empty_alloc_map(proc);
392    T(PROC_LIBC_INIT, "memcheck: libc.so has been initialized for %s[pid=%u]\n",
393      proc->image_path, proc->pid);
394}
395
396void
397memcheck_guest_alloc(target_ulong guest_address)
398{
399    MallocDescEx desc;
400    MallocDescEx replaced;
401    RBTMapResult insert_res;
402    ProcDesc* proc;
403    ThreadDesc* thread;
404    uint32_t indx;
405
406    // Copy allocation descriptor from guest to emulator.
407    memcheck_get_malloc_descriptor(&desc.malloc_desc, guest_address);
408    desc.flags = 0;
409    desc.call_stack = NULL;
410    desc.call_stack_count = 0;
411
412    proc = get_process_from_pid(desc.malloc_desc.allocator_pid);
413    if (proc == NULL) {
414        ME("memcheck: Unable to obtain process for allocation pid=%u",
415           desc.malloc_desc.allocator_pid);
416        memcheck_fail_alloc(guest_address);
417        return;
418    }
419
420    if (!procdesc_is_executing(proc)) {
421        desc.flags |= MDESC_FLAG_TRANSITION_ENTRY;
422    }
423
424    /* Copy thread's calling stack to the allocation descriptor. */
425    thread = get_current_thread();
426    desc.call_stack_count = thread->call_stack_count;
427    if (desc.call_stack_count) {
428        desc.call_stack = qemu_malloc(desc.call_stack_count * sizeof(target_ulong));
429        if (desc.call_stack == NULL) {
430            ME("memcheck: Unable to allocate %u bytes for the calling stack",
431               desc.call_stack_count * sizeof(target_ulong));
432            return;
433        }
434    }
435
436    /* Thread's calling stack is in descending order (i.e. first entry in the
437     * thread's stack is the most distant routine from the current one). On the
438     * other hand, we keep calling stack entries in allocation descriptor in
439     * assending order. */
440    for (indx = 0; indx < thread->call_stack_count; indx++) {
441        desc.call_stack[indx] =
442           thread->call_stack[thread->call_stack_count - 1 - indx].call_address;
443    }
444
445    // Save malloc descriptor in the map.
446    insert_res = procdesc_add_malloc(proc, &desc, &replaced);
447    if (insert_res == RBT_MAP_RESULT_ENTRY_INSERTED) {
448        // Invalidate TLB cache for the allocated block.
449        if (memcheck_instrument_mmu) {
450            invalidate_tlb_cache(desc.malloc_desc.ptr,
451                                mallocdesc_get_alloc_end(&desc.malloc_desc));
452        }
453    } else if (insert_res == RBT_MAP_RESULT_ENTRY_REPLACED) {
454        /* We don't expect to have another entry in the map that matches
455         * inserting entry. This is an error condition for us, indicating
456         * that we somehow lost track of memory allocations. */
457        ME("memcheck: Duplicate allocation blocks:");
458        if (VERBOSE_CHECK(memcheck)) {
459            printf("   New block:\n");
460            memcheck_dump_malloc_desc(&desc, 1, 1);
461            printf("   Replaced block:\n");
462            memcheck_dump_malloc_desc(&replaced, 1, 1);
463        }
464        if (replaced.call_stack != NULL) {
465            qemu_free(replaced.call_stack);
466        }
467    } else {
468        ME("memcheck: Unable to insert an entry to the allocation map:");
469        if (VERBOSE_CHECK(memcheck)) {
470            memcheck_dump_malloc_desc(&desc, 1, 1);
471        }
472        memcheck_fail_alloc(guest_address);
473        return;
474    }
475}
476
477void
478memcheck_guest_free(target_ulong guest_address)
479{
480    MallocFree desc;
481    MallocDescEx pulled;
482    int pull_res;
483    ProcDesc* proc;
484
485    // Copy free descriptor from guest to emulator.
486    memcheck_get_free_descriptor(&desc, guest_address);
487
488    proc = get_process_from_pid(desc.free_pid);
489    if (proc == NULL) {
490        ME("memcheck: Unable to obtain process for pid=%u on free",
491           desc.free_pid);
492        memcheck_fail_free(guest_address);
493        return;
494    }
495
496    // Pull matching entry from the map.
497    pull_res = procdesc_pull_malloc(proc, desc.ptr, &pulled);
498    if (pull_res) {
499        av_invalid_pointer(proc, desc.ptr, 1);
500        memcheck_fail_free(guest_address);
501        return;
502    }
503
504    // Make sure that ptr has expected value
505    if (desc.ptr != mallocdesc_get_user_ptr(&pulled.malloc_desc)) {
506        if (trace_flags & TRACE_CHECK_INVALID_PTR_ENABLED) {
507            printf("memcheck: Access violation is detected in process %s[pid=%u]:\n",
508                   proc->image_path, proc->pid);
509            printf("  INVALID POINTER 0x%08X is used in 'free' operation.\n"
510                   "  This pointer is unexpected for 'free' operation, as allocation\n"
511                   "  descriptor found for this pointer in the process' allocation map\n"
512                   "  suggests that 0x%08X is the pointer to be used to free this block.\n"
513                   "  Allocation descriptor matching the pointer:\n",
514                   desc.ptr,
515                   (uint32_t)mallocdesc_get_user_ptr(&pulled.malloc_desc));
516            memcheck_dump_malloc_desc(&pulled, 1, 0);
517        }
518    }
519    if (pulled.call_stack != NULL) {
520        qemu_free(pulled.call_stack);
521    }
522}
523
524void
525memcheck_guest_query_malloc(target_ulong guest_address)
526{
527    MallocDescQuery qdesc;
528    MallocDescEx* found;
529    ProcDesc* proc;
530
531    // Copy free descriptor from guest to emulator.
532    memcheck_get_query_descriptor(&qdesc, guest_address);
533
534    proc = get_process_from_pid(qdesc.query_pid);
535    if (proc == NULL) {
536        ME("memcheck: Unable to obtain process for pid=%u on query_%s",
537           qdesc.query_pid, qdesc.routine == 1 ? "free" : "realloc");
538        memcheck_fail_query(guest_address);
539        return;
540    }
541
542    // Find allocation entry for the given address.
543    found = procdesc_find_malloc(proc, qdesc.ptr);
544    if (found == NULL) {
545        av_invalid_pointer(proc, qdesc.ptr, qdesc.routine);
546        memcheck_fail_query(guest_address);
547        return;
548    }
549
550    // Copy allocation descriptor back to the guest's space.
551    memcheck_set_malloc_descriptor(qdesc.desc, &found->malloc_desc);
552}
553
554void
555memcheck_guest_print_str(target_ulong str) {
556    char str_copy[4096];
557    memcheck_get_guest_string(str_copy, str, sizeof(str_copy));
558    printf("%s", str_copy);
559}
560
561/* Validates read operations, detected in __ldx_mmu routine.
562 * This routine is called from __ldx_mmu wrapper implemented in
563 * softmmu_template.h on condition that loading is occurring from user memory.
564 * Param:
565 *  addr - Virtual address in the guest space where memory is read.
566 *  data_size - Size of the read.
567 *  retaddr - Code address (in TB) that accesses memory.
568 * Return:
569 *  1 if TLB record for the accessed page should be invalidated in order to
570 *  ensure that subsequent attempts to access data in this page will cause
571 *  __ld/stx_mmu to be used. If memchecker is no longer interested in monitoring
572 * access to this page, this routine returns 0.
573 */
574int
575memcheck_validate_ld(target_ulong addr,
576                     uint32_t data_size,
577                     target_ulong retaddr)
578{
579    ProcDesc* proc;
580    MallocDescEx* desc;
581
582    int res = memcheck_common_access_validation(addr, data_size, &proc, &desc);
583    if (res == -1) {
584        av_access_violation(proc, desc, addr, data_size, 0, retaddr, 1);
585        return 1;
586    }
587
588    /* Even though descriptor for the given address range has not been found,
589     * we need to make sure that pages containing the given address range
590     * don't contain other descriptors. */
591    return res ? procdesc_contains_allocs(proc, addr, data_size) : 0;
592}
593
594/* Validates write operations, detected in __stx_mmu routine.
595 * This routine is called from __stx_mmu wrapper implemented in
596 * softmmu_template.h on condition that storing is occurring from user memory.
597 * Param:
598 *  addr - Virtual address in the guest space where memory is written.
599 *  data_size - Size of the write.
600 *  value - Value to be written. Note that we typecast all values to 64 bits,
601 *      since this will fit all data sizes.
602 *  retaddr - Code address (in TB) that accesses memory.
603 * Return:
604 *  1 if TLB record for the accessed page should be invalidated in order to
605 *  ensure that subsequent attempts to access data in this page will cause
606 *  __ld/stx_mmu to be used. If memchecker is no longer interested in monitoring
607 * access to this page, this routine returns 0.
608 */
609int
610memcheck_validate_st(target_ulong addr,
611                     uint32_t data_size,
612                     uint64_t value,
613                     target_ulong retaddr)
614{
615    MallocDescEx* desc;
616    ProcDesc* proc;
617
618    int res = memcheck_common_access_validation(addr, data_size, &proc, &desc);
619    if (res == -1) {
620        av_access_violation(proc, desc, addr, data_size, value, retaddr, 0);
621        return 1;
622    }
623
624    /* Even though descriptor for the given address range has not been found,
625     * we need to make sure that pages containing the given address range
626     * don't contain other descriptors. */
627    return res ? procdesc_contains_allocs(proc, addr, data_size) : 0;
628}
629
630/* Checks if given address range in the context of the current process is under
631 * surveillance.
632 * Param:
633 *  addr - Starting address of a range.
634 *  size - Range size.
635 * Return:
636 *  boolean: 1 if address range contains memory that require access violation
637 *  detection, or 0 if given address range is in no interest to the memchecker.
638 */
639int
640memcheck_is_checked(target_ulong addr, uint32_t size) {
641    return procdesc_contains_allocs(get_current_process(), addr, size) ? 1 : 0;
642}
643