static void InitMalloc(MallocDebug* table, int debug_level, const char* prefix) {
/*
  BEGIN mtk-modified: log for debug 15 and 16
*/
  if (debug_level == 15 || debug_level == 16) {
  	__libc_android_log_print(ANDROID_LOG_INFO, "libc", "%s: using MALLOC_DEBUG = %d\n",
                           __progname, debug_level);
  } else
  	__libc_android_log_print(ANDROID_LOG_INFO, "libc", "%s: using libc.debug.malloc %d (%s)\n",
                           __progname, debug_level, prefix);
/*
  END mtk-modified.
*/

  char symbol[128];

  snprintf(symbol, sizeof(symbol), "%s_malloc", prefix);
  table->malloc = reinterpret_cast<MallocDebugMalloc>(dlsym(libc_malloc_impl_handle, symbol));
  if (table->malloc == NULL) {
      error_log("%s: dlsym(\"%s\") failed", __progname, symbol);
  }

  snprintf(symbol, sizeof(symbol), "%s_free", prefix);
  table->free = reinterpret_cast<MallocDebugFree>(dlsym(libc_malloc_impl_handle, symbol));
  if (table->free == NULL) {
      error_log("%s: dlsym(\"%s\") failed", __progname, symbol);
  }

  snprintf(symbol, sizeof(symbol), "%s_calloc", prefix);
  table->calloc = reinterpret_cast<MallocDebugCalloc>(dlsym(libc_malloc_impl_handle, symbol));
  if (table->calloc == NULL) {
      error_log("%s: dlsym(\"%s\") failed", __progname, symbol);
  }

  snprintf(symbol, sizeof(symbol), "%s_realloc", prefix);
  table->realloc = reinterpret_cast<MallocDebugRealloc>(dlsym(libc_malloc_impl_handle, symbol));
  if (table->realloc == NULL) {
      error_log("%s: dlsym(\"%s\") failed", __progname, symbol);
  }

  snprintf(symbol, sizeof(symbol), "%s_memalign", prefix);
  table->memalign = reinterpret_cast<MallocDebugMemalign>(dlsym(libc_malloc_impl_handle, symbol));
  if (table->memalign == NULL) {
      error_log("%s: dlsym(\"%s\") failed", __progname, symbol);
  }
}
Exemplo n.º 2
0
/*
 * Runtime implementation of __umask_chk.
 *
 * Validate that umask is called with sane mode.
 *
 * This umask check is called if _FORTIFY_SOURCE is defined and
 * greater than 0.
 */
extern "C" mode_t __umask_chk(mode_t mode) {
    if ((mode & 0777) != mode) {
        __libc_android_log_print(ANDROID_LOG_FATAL, "libc",
            "*** FORTIFY_SOURCE: umask called with invalid mask ***\n");
        abort();
    }

    return umask(mode);
}
Exemplo n.º 3
0
/*
 * Runtime implementation of __builtin____memset_chk.
 *
 * See
 *   http://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html
 *   http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02055.html
 * for details.
 *
 * This memset check is called if _FORTIFY_SOURCE is defined and
 * greater than 0.
 */
extern "C" void *__memset_chk (void *dest, int c, size_t n, size_t dest_len) {
    if (n > dest_len) {
        __libc_android_log_print(ANDROID_LOG_FATAL, "libc",
            "*** memset buffer overflow detected ***\n");
        __libc_android_log_event_uid(BIONIC_EVENT_MEMSET_BUFFER_OVERFLOW);
        abort();
    }

    return memset(dest, c, n);
}
Exemplo n.º 4
0
/*
 * __strlcat_chk. Called in place of strlcat() when we know the
 * size of the buffer we're writing into.
 *
 * See
 *   http://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html
 *   http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02055.html
 * for details.
 *
 * This strlcat check is called if _FORTIFY_SOURCE is defined and
 * greater than 0.
 */
extern "C" size_t __strlcat_chk(char *dest, const char *src,
                                size_t supplied_size, size_t dest_len_from_compiler)
{
    if (supplied_size > dest_len_from_compiler) {
        __libc_android_log_print(ANDROID_LOG_FATAL, "libc",
                                 "*** strlcat buffer overflow detected ***\n");
        abort();
    }

    return strlcat(dest, src, supplied_size);
}
Exemplo n.º 5
0
/*
 * Runtime implementation of __memcpy_chk.
 *
 * See
 *   http://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html
 *   http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02055.html
 * for details.
 *
 * This memcpy check is called if _FORTIFY_SOURCE is defined and
 * greater than 0.
 */
extern "C" void *__memcpy_chk(void *dest, const void *src,
              size_t copy_amount, size_t dest_len)
{
    if (__builtin_expect(copy_amount > dest_len, 0)) {
        __libc_android_log_print(ANDROID_LOG_FATAL, "libc",
            "*** memcpy buffer overflow detected ***\n");
        __libc_android_log_event_uid(BIONIC_EVENT_MEMCPY_BUFFER_OVERFLOW);
        abort();
    }

    return memcpy(dest, src, copy_amount);
}
Exemplo n.º 6
0
/*
 * Runtime implementation of __builtin____memmove_chk.
 *
 * See
 *   http://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html
 *   http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02055.html
 * for details.
 *
 * This memmove check is called if _FORTIFY_SOURCE is defined and
 * greater than 0.
 */
extern "C" void *__memmove_chk (void *dest, const void *src,
              size_t len, size_t dest_len)
{
    if (len > dest_len) {
        __libc_android_log_print(ANDROID_LOG_FATAL, "libc",
            "*** memmove buffer overflow detected ***\n");
        __libc_android_log_event_uid(BIONIC_EVENT_MEMMOVE_BUFFER_OVERFLOW);
        abort();
    }

    return memmove(dest, src, len);
}
Exemplo n.º 7
0
static void InitMalloc(MallocDebug* table, int debug_level, const char* prefix) {
  __libc_android_log_print(ANDROID_LOG_INFO, "libc", "%s: using libc.debug.malloc %d (%s)\n",
                           __progname, debug_level, prefix);

  char symbol[128];

  snprintf(symbol, sizeof(symbol), "%s_malloc", prefix);
  table->malloc = reinterpret_cast<MallocDebugMalloc>(dlsym(libc_malloc_impl_handle, symbol));
  if (table->malloc == NULL) {
      error_log("%s: dlsym(\"%s\") failed", __progname, symbol);
  }

  snprintf(symbol, sizeof(symbol), "%s_free", prefix);
  table->free = reinterpret_cast<MallocDebugFree>(dlsym(libc_malloc_impl_handle, symbol));
  if (table->free == NULL) {
      error_log("%s: dlsym(\"%s\") failed", __progname, symbol);
  }

  snprintf(symbol, sizeof(symbol), "%s_calloc", prefix);
  table->calloc = reinterpret_cast<MallocDebugCalloc>(dlsym(libc_malloc_impl_handle, symbol));
  if (table->calloc == NULL) {
      error_log("%s: dlsym(\"%s\") failed", __progname, symbol);
  }

  snprintf(symbol, sizeof(symbol), "%s_realloc", prefix);
  table->realloc = reinterpret_cast<MallocDebugRealloc>(dlsym(libc_malloc_impl_handle, symbol));
  if (table->realloc == NULL) {
      error_log("%s: dlsym(\"%s\") failed", __progname, symbol);
  }

  snprintf(symbol, sizeof(symbol), "%s_memalign", prefix);
  table->memalign = reinterpret_cast<MallocDebugMemalign>(dlsym(libc_malloc_impl_handle, symbol));
  if (table->memalign == NULL) {
      error_log("%s: dlsym(\"%s\") failed", __progname, symbol);
  }
}
/* Initializes memory allocation framework once per process. */
static void malloc_init_impl(void)
{
    const char* so_name = NULL;
    MallocDebugInit malloc_debug_initialize = NULL;
    unsigned int qemu_running = 0;
    unsigned int debug_level = 0;


    unsigned int memcheck_enabled = 0;
    char env[PROP_VALUE_MAX];
    char memcheck_tracing[PROP_VALUE_MAX];

    // added by zmj
    mspace_malloc_stat = NULL;
    mspace_free_stat = NULL;

#ifdef _MTK_ENG_
    debug_level = 15;
#else
    debug_level = 0;
#endif
	
    /* Get custom malloc debug level. Note that emulator started with
     * memory checking option will have priority over debug level set in
     * libc.debug.malloc system property. */
    if (__system_property_get("ro.kernel.qemu", env) && atoi(env)) {
        qemu_running = 1;
        if (__system_property_get("ro.kernel.memcheck", memcheck_tracing)) {
            if (memcheck_tracing[0] != '0') {
                // Emulator has started with memory tracing enabled. Enforce it.
                debug_level = 20;
                memcheck_enabled = 1;
            }
        }
    }

    /* If debug level has not been set by memcheck option in the emulator,
     * lets grab it from libc.debug.malloc system property. */
    if ((debug_level !=  20) && __system_property_get("libc.debug.malloc", env)) {
        debug_level = atoi(env);
    }

    if ((debug_level != 20) && __system_property_get("persist.libc.debug.malloc", env)) {
        debug_level = atoi(env);
    }

    if (__system_property_get("ro.build.type", env)) {
        if(strncmp(env, "eng", 3))
			debug_level = 0;
    }
		
    /* Debug level 0 means that we should use dlxxx allocation
     * routines (default). */
    if (!debug_level) {
        return;
    }

    // Lets see which .so must be loaded for the requested debug level
    switch (debug_level) {
        case 1:
        case 5:
        case 10:
            so_name = "/system/lib/libc_malloc_debug_leak.so";
            break;
	case 15:
	case 16:
		so_name = "/system/lib/libc_malloc_debug_mtk.so";
		break;
        case 20:
            // Quick check: debug level 20 can only be handled in emulator.
            if (!qemu_running) {
                error_log("%s: Debug level %d can only be set in emulator\n",
                          __progname, debug_level);
                return;
            }
            // Make sure that memory checking has been enabled in emulator.
            if (!memcheck_enabled) {
                error_log("%s: Memory checking is not enabled in the emulator\n",
                          __progname);
                return;
            }
            so_name = "/system/lib/libc_malloc_debug_qemu.so";
            break;
        default:
            error_log("%s: Debug level %d is unknown\n",
                      __progname, debug_level);
            return;
    }

    // Load .so that implements the required malloc debugging functionality.
    libc_malloc_impl_handle = dlopen(so_name, RTLD_LAZY);
    if (libc_malloc_impl_handle == NULL) {
        error_log("%s: Missing module %s required for malloc debug level %d\n",
                 __progname, so_name, debug_level);
        return;
    }

    // Initialize malloc debugging in the loaded module.
    malloc_debug_initialize =
            dlsym(libc_malloc_impl_handle, "malloc_debug_initialize");
    if (malloc_debug_initialize == NULL) {
        error_log("%s: Initialization routine is not found in %s\n",
                  __progname, so_name);
        dlclose(libc_malloc_impl_handle);
        return;
    }
    if (malloc_debug_initialize()) {
        dlclose(libc_malloc_impl_handle);
        return;
    }

    if (debug_level == 20) {
        // For memory checker we need to do extra initialization.
        int (*memcheck_initialize)(int, const char*) =
                dlsym(libc_malloc_impl_handle, "memcheck_initialize");
        if (memcheck_initialize == NULL) {
            error_log("%s: memcheck_initialize routine is not found in %s\n",
                      __progname, so_name);
            dlclose(libc_malloc_impl_handle);
            return;
        }
        if (memcheck_initialize(MALLOC_ALIGNMENT, memcheck_tracing)) {
            dlclose(libc_malloc_impl_handle);
            return;
        }
    }

    if (debug_level == 15) {
		int sig = 0;
        // For debug 15 we need to do extra initialization.
        int (*debug15_extra_initialize)(int) =
                dlsym(libc_malloc_impl_handle, "debug15_extra_initialize");
        if (debug15_extra_initialize == NULL) {
            error_log("%s: malloc_debug_extra_initialize routine is not found in %s\n",
                      __progname, so_name);
            dlclose(libc_malloc_impl_handle);
			 return;
        }
				
	    if (__system_property_get("persist.debug15.sig", env)) {
	        sig = atoi(env);
	    }
		
        if (debug15_extra_initialize(sig)) {
            dlclose(libc_malloc_impl_handle);
            return;
        }
		
		// to indicate that debug 15 is on.
		__system_property_set("libc.debug15.status", "on");
    }
		
    // Initialize malloc dispatch table with appropriate routines.
    switch (debug_level) {
        case 1:
            __libc_android_log_print(ANDROID_LOG_INFO, "libc",
                    "%s using MALLOC_DEBUG = %d (leak checker)\n",
                    __progname, debug_level);
            gMallocUse.malloc =
                dlsym(libc_malloc_impl_handle, "leak_malloc");
            gMallocUse.free =
                dlsym(libc_malloc_impl_handle, "leak_free");
            gMallocUse.calloc =
                dlsym(libc_malloc_impl_handle, "leak_calloc");
            gMallocUse.realloc =
                dlsym(libc_malloc_impl_handle, "leak_realloc");
            gMallocUse.memalign =
                dlsym(libc_malloc_impl_handle, "leak_memalign");
            break;
        case 5:
            __libc_android_log_print(ANDROID_LOG_INFO, "libc",
                    "%s using MALLOC_DEBUG = %d (fill)\n",
                    __progname, debug_level);
            gMallocUse.malloc =
                dlsym(libc_malloc_impl_handle, "fill_malloc");
            gMallocUse.free =
                dlsym(libc_malloc_impl_handle, "fill_free");
            gMallocUse.calloc = dlcalloc;
            gMallocUse.realloc =
                dlsym(libc_malloc_impl_handle, "fill_realloc");
            gMallocUse.memalign =
                dlsym(libc_malloc_impl_handle, "fill_memalign");
            break;
        case 10:
            __libc_android_log_print(ANDROID_LOG_INFO, "libc",
                    "%s using MALLOC_DEBUG = %d (sentinels, fill)\n",
                    __progname, debug_level);
            gMallocUse.malloc =
                dlsym(libc_malloc_impl_handle, "chk_malloc");
            gMallocUse.free =
                dlsym(libc_malloc_impl_handle, "chk_free");
            gMallocUse.calloc =
                dlsym(libc_malloc_impl_handle, "chk_calloc");
            gMallocUse.realloc =
                dlsym(libc_malloc_impl_handle, "chk_realloc");
            gMallocUse.memalign =
                dlsym(libc_malloc_impl_handle, "chk_memalign");
            break;

	case 15:
		__libc_android_log_print(ANDROID_LOG_INFO, "libc",
								"%s using MALLOC_DEBUG = %d(dlmalloc, BT)\n",
								__progname, debug_level);
		gMallocUse.malloc =
			dlsym(libc_malloc_impl_handle, "mtk_malloc");
		gMallocUse.free =
			dlsym(libc_malloc_impl_handle, "mtk_free");
		gMallocUse.calloc =
			dlsym(libc_malloc_impl_handle, "mtk_calloc");
		gMallocUse.realloc =
			dlsym(libc_malloc_impl_handle, "mtk_realloc");
		gMallocUse.memalign =
			dlsym(libc_malloc_impl_handle, "mtk_memalign");
        gpMallocFullBacktrace = 
            dlsym(libc_malloc_impl_handle, "mtk_malloc_full_backtrace");
        gpFreeFullBacktrace = 
            dlsym(libc_malloc_impl_handle, "mtk_free_full_backtrace");
		break;
	case 16:
		__libc_android_log_print(ANDROID_LOG_INFO, "libc",
					"%s using MALLOC_DEBUG = %d (dlmalloc, mspace, BT)\n",
					__progname, debug_level);
		gMallocUse.malloc =
			dlsym(libc_malloc_impl_handle, "mtk_malloc");
		gMallocUse.free =
			dlsym(libc_malloc_impl_handle, "mtk_free");
		gMallocUse.calloc =
			dlsym(libc_malloc_impl_handle, "mtk_calloc");
		gMallocUse.realloc =
			dlsym(libc_malloc_impl_handle, "mtk_realloc");
		gMallocUse.memalign =
			dlsym(libc_malloc_impl_handle, "mtk_memalign");
		mspace_malloc_stat = 
			dlsym(libc_malloc_impl_handle, "mtk_mspace_malloc_stat");
        	mspace_free_stat = 
			dlsym(libc_malloc_impl_handle, "mtk_mspace_free_stat");
		break;

        case 20:
            __libc_android_log_print(ANDROID_LOG_INFO, "libc",
                "%s[%u] using MALLOC_DEBUG = %d (instrumented for emulator)\n",
                __progname, getpid(), debug_level);
            gMallocUse.malloc =
                dlsym(libc_malloc_impl_handle, "qemu_instrumented_malloc");
            gMallocUse.free =
                dlsym(libc_malloc_impl_handle, "qemu_instrumented_free");
            gMallocUse.calloc =
                dlsym(libc_malloc_impl_handle, "qemu_instrumented_calloc");
            gMallocUse.realloc =
                dlsym(libc_malloc_impl_handle, "qemu_instrumented_realloc");
            gMallocUse.memalign =
                dlsym(libc_malloc_impl_handle, "qemu_instrumented_memalign");
            break;
        default:
            break;
    }

    // Make sure dispatch table is initialized
    if ((gMallocUse.malloc == NULL) ||
        (gMallocUse.free == NULL) ||
        (gMallocUse.calloc == NULL) ||
        (gMallocUse.realloc == NULL) ||
        (gMallocUse.memalign == NULL)) {
        error_log("%s: Cannot initialize malloc dispatch table for debug level"
                  " %d: %p, %p, %p, %p, %p\n",
                  __progname, debug_level,
                  gMallocUse.malloc, gMallocUse.free,
                  gMallocUse.calloc, gMallocUse.realloc,
                  gMallocUse.memalign);
        dlclose(libc_malloc_impl_handle);
        libc_malloc_impl_handle = NULL;
    } else {
        __libc_malloc_dispatch = &gMallocUse;
    }
}