From df8b047bcab3ee0a9fc37c4268c4cae874ab7423 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Thu, 27 Sep 2018 03:11:10 -0400 Subject: [PATCH] Generalize logging interface --- native/jni/Android.mk | 4 +- native/jni/Application.mk | 4 +- native/jni/core/daemon.c | 4 ++ native/jni/core/log_daemon.c | 2 + native/jni/core/magisk.c | 1 + native/jni/core/magiskinit.c | 16 ++--- native/jni/core/socket.c | 2 + native/jni/include/logging.h | 78 +++++++------------- native/jni/magiskboot/bootimg.c | 1 + native/jni/magiskboot/compress.c | 2 + native/jni/magiskboot/cpio.c | 2 + native/jni/magiskboot/ramdisk.c | 4 +- native/jni/magiskhide/magiskhide.c | 1 + native/jni/magiskpolicy/magiskpolicy.c | 1 + native/jni/resetprop/_resetprop.h | 3 - native/jni/resetprop/persist_properties.c | 8 +-- native/jni/resetprop/resetprop.c | 27 ++++--- native/jni/utils/img.c | 3 + native/jni/utils/logging.c | 88 +++++++++++++++++++++++ native/jni/utils/selinux.c | 2 +- 20 files changed, 170 insertions(+), 83 deletions(-) create mode 100644 native/jni/utils/logging.c diff --git a/native/jni/Android.mk b/native/jni/Android.mk index 6f8fe17d2..11dd5a60e 100644 --- a/native/jni/Android.mk +++ b/native/jni/Android.mk @@ -17,6 +17,7 @@ COMMON_UTILS := \ utils/misc.c \ utils/vector.c \ utils/selinux.c \ + utils/logging.c \ utils/xwrap.c ######################## @@ -32,7 +33,6 @@ LOCAL_SHARED_LIBRARIES := libsqlite LOCAL_STATIC_LIBRARIES := libnanopb libsystemproperties LOCAL_C_INCLUDES := \ jni/include \ - jni/magiskpolicy \ $(EXT_PATH)/include \ $(LIBNANOPB) \ $(LIBSYSTEMPROPERTIES) @@ -144,7 +144,7 @@ include jni/external/busybox/Android.mk endif ######################## -# Externals +# Libraries ######################## include jni/external/Android.mk include jni/resetprop/libsystemproperties/Android.mk diff --git a/native/jni/Application.mk b/native/jni/Application.mk index 2d00194ec..3853dce4f 100644 --- a/native/jni/Application.mk +++ b/native/jni/Application.mk @@ -1,14 +1,14 @@ APP_ABI := armeabi-v7a x86 -APP_CFLAGS := -std=gnu99 ${MAGISK_DEBUG} \ +APP_CFLAGS := -std=gnu11 ${MAGISK_DEBUG} \ -DMAGISK_VERSION="${MAGISK_VERSION}" -DMAGISK_VER_CODE=${MAGISK_VER_CODE} APP_CPPFLAGS := -std=c++14 APP_STL := system APP_PLATFORM := android-16 -APP_CFLAGS += -Wno-implicit-function-declaration # Busybox require some additional settings ifdef B_BB APP_SHORT_COMMANDS := true NDK_TOOLCHAIN_VERSION := 4.9 APP_PLATFORM := android-21 +APP_CFLAGS += -Wno-implicit-function-declaration endif diff --git a/native/jni/core/daemon.c b/native/jni/core/daemon.c index 5677f713e..99b16d55b 100644 --- a/native/jni/core/daemon.c +++ b/native/jni/core/daemon.c @@ -96,6 +96,10 @@ static void *request_handler(void *args) { } void main_daemon() { + android_logging(); +#ifndef MAGISK_DEBUG + log_cb.d = nop_log; +#endif setsid(); setcon("u:r:"SEPOL_PROC_DOMAIN":s0"); int fd = xopen("/dev/null", O_RDWR | O_CLOEXEC); diff --git a/native/jni/core/log_daemon.c b/native/jni/core/log_daemon.c index bf0594fa4..74cc1ff17 100644 --- a/native/jni/core/log_daemon.c +++ b/native/jni/core/log_daemon.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include #include diff --git a/native/jni/core/magisk.c b/native/jni/core/magisk.c index 8587db8c8..aefdf98d8 100644 --- a/native/jni/core/magisk.c +++ b/native/jni/core/magisk.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "utils.h" #include "magisk.h" diff --git a/native/jni/core/magiskinit.c b/native/jni/core/magiskinit.c index ba9598af8..9317d3d60 100644 --- a/native/jni/core/magiskinit.c +++ b/native/jni/core/magiskinit.c @@ -46,12 +46,6 @@ #include "daemon.h" #include "magisk.h" -#ifdef MAGISK_DEBUG -#define VLOG(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__) -#else -#define VLOG(fmt, ...) -#endif - #define DEFAULT_DT_DIR "/proc/device-tree/firmware/android" int (*init_applet_main[]) (int, char *[]) = { magiskpolicy_main, magiskpolicy_main, NULL }; @@ -94,7 +88,7 @@ static void parse_cmdline(struct cmdline *cmd) { if (cmd->dt_dir[0] == '\0') strcpy(cmd->dt_dir, DEFAULT_DT_DIR); - VLOG("cmdline: skip_initramfs[%d] slot[%s] dt_dir[%s]\n", cmd->skip_initramfs, cmd->slot, cmd->dt_dir); + LOGD("cmdline: skip_initramfs[%d] slot[%s] dt_dir[%s]\n", cmd->skip_initramfs, cmd->slot, cmd->dt_dir); } static void parse_device(struct device *dev, const char *uevent) { @@ -113,7 +107,7 @@ static void parse_device(struct device *dev, const char *uevent) { } } fclose(fp); - VLOG("%s [%s] (%u, %u)\n", dev->devname, dev->partname, (unsigned) dev->major, (unsigned) dev->minor); + LOGD("%s [%s] (%u, %u)\n", dev->devname, dev->partname, (unsigned) dev->major, (unsigned) dev->minor); } static int setup_block(struct device *dev, const char *partname) { @@ -199,7 +193,7 @@ static int verify_precompiled() { } } closedir(dir); - VLOG("sys_sha[%.*s]\nven_sha[%.*s]\n", sizeof(sys_sha), sys_sha, sizeof(ven_sha), ven_sha); + LOGD("sys_sha[%.*s]\nven_sha[%.*s]\n", sizeof(sys_sha), sys_sha, sizeof(ven_sha), ven_sha); return memcmp(sys_sha, ven_sha, sizeof(sys_sha)) == 0; } @@ -339,6 +333,10 @@ int main(int argc, char *argv[]) { return dump_magiskrc(argv[3], 0755); } +#ifdef MAGISK_DEBUG + log_cb.d = vprintf; +#endif + // Prevent file descriptor confusion mknod("/null", S_IFCHR | 0666, makedev(1, 3)); int null = open("/null", O_RDWR | O_CLOEXEC); diff --git a/native/jni/core/socket.c b/native/jni/core/socket.c index 23673c334..c83bde2a9 100644 --- a/native/jni/core/socket.c +++ b/native/jni/core/socket.c @@ -1,6 +1,8 @@ /* socket.c - All socket related operations */ +#include +#include #include #include diff --git a/native/jni/include/logging.h b/native/jni/include/logging.h index 3ebd9be32..e4232ed36 100644 --- a/native/jni/include/logging.h +++ b/native/jni/include/logging.h @@ -1,68 +1,44 @@ /* logging.h - Error handling and logging */ -#ifndef _LOGGING_H_ -#define _LOGGING_H_ +#pragma once -#include #include -#include +#include +#include #define str(a) #a #define xstr(a) str(a) -/************** - * No logging * - **************/ +typedef enum { + L_DEBUG, + L_INFO, + L_WARN, + L_ERR +} log_type; -#define LOGD(...) -#define LOGI(...) -#define LOGW(...) -#define LOGE(...) -#define PLOGE(...) +struct log_callback { + int (*d)(const char* fmt, va_list ap); + int (*i)(const char* fmt, va_list ap); + int (*w)(const char* fmt, va_list ap); + int (*e)(const char* fmt, va_list ap); + void (*ex)(int code); +}; -/****************** - * Daemon logging * - ******************/ +extern struct log_callback log_cb; -#ifdef IS_DAEMON - -#undef LOGI -#undef LOGW -#undef LOGE -#undef PLOGE - -#include -#include - -#define LOG_TAG "Magisk" - -#ifdef MAGISK_DEBUG -#undef LOGD -#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) -#endif -#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) -#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__) -#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) +#define LOGD(...) log_handler(L_DEBUG, __VA_ARGS__) +#define LOGI(...) log_handler(L_INFO, __VA_ARGS__) +#define LOGW(...) log_handler(L_WARN, __VA_ARGS__) +#define LOGE(...) log_handler(L_ERR, __VA_ARGS__) #define PLOGE(fmt, args...) LOGE(fmt " failed with %d: %s", ##args, errno, strerror(errno)) -#endif +int nop_log(const char *fmt, va_list ap); +void nop_ex(int i); -/******************** - * Tools Log & Exit * - ********************/ +void no_logging(); +void android_logging(); +void cmdline_logging(); -#ifdef XWRAP_EXIT +int log_handler(log_type t, const char *fmt, ...); -#undef LOGE -#undef PLOGE - -#include - -#define LOGE(...) { fprintf(stderr, __VA_ARGS__); exit(1); } -#define PLOGE(fmt, args...) { fprintf(stderr, fmt " failed with %d: %s\n\n", ##args, errno, strerror(errno)); exit(1); } - -#endif - - -#endif // _LOGGING_H_ diff --git a/native/jni/magiskboot/bootimg.c b/native/jni/magiskboot/bootimg.c index 65c01cb3f..711c9e10e 100644 --- a/native/jni/magiskboot/bootimg.c +++ b/native/jni/magiskboot/bootimg.c @@ -250,6 +250,7 @@ int parse_img(const char *image, boot_img *boot) { } } LOGE("No boot image magic found!\n"); + exit(1); } int unpack(const char *image) { diff --git a/native/jni/magiskboot/compress.c b/native/jni/magiskboot/compress.c index 0329cc03d..74c1f4e6e 100644 --- a/native/jni/magiskboot/compress.c +++ b/native/jni/magiskboot/compress.c @@ -1,5 +1,7 @@ #include #include +#include +#include #include #include diff --git a/native/jni/magiskboot/cpio.c b/native/jni/magiskboot/cpio.c index 9fe46f182..bfd04f5e6 100644 --- a/native/jni/magiskboot/cpio.c +++ b/native/jni/magiskboot/cpio.c @@ -1,6 +1,8 @@ #include #include #include +#include +#include #include "cpio.h" #include "logging.h" diff --git a/native/jni/magiskboot/ramdisk.c b/native/jni/magiskboot/ramdisk.c index 10c6b7db0..a9e74984e 100644 --- a/native/jni/magiskboot/ramdisk.c +++ b/native/jni/magiskboot/ramdisk.c @@ -1,12 +1,14 @@ #include #include +#include +#include #include -#include #include #include #include "magiskboot.h" #include "cpio.h" +#include "utils.h" static void cpio_patch(struct vector *v, int keepverity, int keepforceencrypt) { fprintf(stderr, "Patch with flag KEEPVERITY=[%s] KEEPFORCEENCRYPT=[%s]\n", diff --git a/native/jni/magiskhide/magiskhide.c b/native/jni/magiskhide/magiskhide.c index ce09a1b18..97777a25a 100644 --- a/native/jni/magiskhide/magiskhide.c +++ b/native/jni/magiskhide/magiskhide.c @@ -114,6 +114,7 @@ void stop_magiskhide(int client) { } int magiskhide_main(int argc, char *argv[]) { + cmdline_logging(); if (argc < 2) { usage(argv[0]); } diff --git a/native/jni/magiskpolicy/magiskpolicy.c b/native/jni/magiskpolicy/magiskpolicy.c index 0d489d47b..783cf492b 100644 --- a/native/jni/magiskpolicy/magiskpolicy.c +++ b/native/jni/magiskpolicy/magiskpolicy.c @@ -391,6 +391,7 @@ static void syntax_error_msg() { } int magiskpolicy_main(int argc, char *argv[]) { + cmdline_logging(); char *outfile = NULL, *tok, *saveptr; int magisk = 0; struct vector rules; diff --git a/native/jni/resetprop/_resetprop.h b/native/jni/resetprop/_resetprop.h index 3a8ba7c1e..5266fdbf9 100644 --- a/native/jni/resetprop/_resetprop.h +++ b/native/jni/resetprop/_resetprop.h @@ -10,9 +10,6 @@ extern int prop_verbose; -#define PRINT_D(...) { LOGD(__VA_ARGS__); if (prop_verbose) fprintf(stderr, __VA_ARGS__); } -#define PRINT_E(...) { LOGE(__VA_ARGS__); fprintf(stderr, __VA_ARGS__); } - struct prop_t { char *name; char value[PROP_VALUE_MAX]; diff --git a/native/jni/resetprop/persist_properties.c b/native/jni/resetprop/persist_properties.c index bff68e5ef..90fb77fb8 100644 --- a/native/jni/resetprop/persist_properties.c +++ b/native/jni/resetprop/persist_properties.c @@ -153,7 +153,7 @@ static void pb_getprop_cb(const char *name, const char *value, void *v) { void persist_getprop_all(struct read_cb_t *read_cb) { if (access(PERSISTENT_PROPERTY_DIR "/persistent_properties", R_OK) == 0) { - PRINT_D("resetprop: decode with protobuf from [" PERSISTENT_PROPERTY_DIR "/persistent_properties]\n"); + LOGD("resetprop: decode with protobuf from [" PERSISTENT_PROPERTY_DIR "/persistent_properties]\n"); PersistentProperties props = PersistentProperties_init_zero; props.properties.funcs.decode = prop_decode; props.properties.arg = read_cb; @@ -196,7 +196,7 @@ char *persist_getprop(const char *name) { int fd = open(path, O_RDONLY | O_CLOEXEC); if (fd < 0) return NULL; - PRINT_D("resetprop: read prop from [%s]\n", path); + LOGD("resetprop: read prop from [%s]\n", path); prop.value[read(fd, prop.value, sizeof(PROP_VALUE_MAX))] = '\0'; // Null terminate the read value close(fd); } @@ -231,7 +231,7 @@ bool persist_deleteprop(const char *name) { pb_ostream_t ostream = create_ostream(PERSISTENT_PROPERTY_DIR "/persistent_properties.tmp"); props.properties.funcs.encode = prop_encode; props.properties.arg = &v; - PRINT_D("resetprop: encode with protobuf to [" PERSISTENT_PROPERTY_DIR "/persistent_properties.tmp]\n"); + LOGD("resetprop: encode with protobuf to [" PERSISTENT_PROPERTY_DIR "/persistent_properties.tmp]\n"); if (!pb_encode(&ostream, PersistentProperties_fields, &props)) return false; clone_attr(PERSISTENT_PROPERTY_DIR "/persistent_properties", PERSISTENT_PROPERTY_DIR "/persistent_properties.tmp"); @@ -244,7 +244,7 @@ bool persist_deleteprop(const char *name) { char path[PATH_MAX]; snprintf(path, sizeof(path), PERSISTENT_PROPERTY_DIR "/%s", name); if (unlink(path) == 0) { - PRINT_D("resetprop: unlink [%s]\n", path); + LOGD("resetprop: unlink [%s]\n", path); return true; } } diff --git a/native/jni/resetprop/resetprop.c b/native/jni/resetprop/resetprop.c index b2f1a6424..a8e26ad21 100644 --- a/native/jni/resetprop/resetprop.c +++ b/native/jni/resetprop/resetprop.c @@ -50,7 +50,7 @@ static int check_legal_property_name(const char *name) { return 0; illegal: - PRINT_E("Illegal property name: [%s]\n", name); + LOGE("Illegal property name: [%s]\n", name); return 1; } @@ -124,7 +124,7 @@ static int prop_cmp(const void *p1, const void *p2) { static int init_resetprop() { if (__system_properties_init()) { - PRINT_E("resetprop: Initialize error\n"); + LOGE("resetprop: Initialize error\n"); return -1; } return 0; @@ -176,7 +176,7 @@ char *getprop2(const char *name, int persist) { if (value) return value; } - PRINT_D("resetprop: prop [%s] does not exist\n", name); + LOGD("resetprop: prop [%s] does not exist\n", name); return NULL; } else { char value[PROP_VALUE_MAX]; @@ -185,7 +185,7 @@ char *getprop2(const char *name, int persist) { .cookie = value }; __system_property_read_callback(pi, callback_wrapper, &read_cb); - PRINT_D("resetprop: getprop [%s]: [%s]\n", name, value); + LOGD("resetprop: getprop [%s]: [%s]\n", name, value); return strdup(value); } } @@ -218,7 +218,7 @@ int setprop2(const char *name, const char *value, const int trigger) { ret = __system_property_update(pi, value, strlen(value)); } } else { - PRINT_D("resetprop: New prop [%s]\n", name); + LOGD("resetprop: New prop [%s]\n", name); if (trigger) { ret = __system_property_set(name, value); } else { @@ -226,11 +226,11 @@ int setprop2(const char *name, const char *value, const int trigger) { } } - PRINT_D("resetprop: setprop [%s]: [%s] by %s\n", name, value, + LOGD("resetprop: setprop [%s]: [%s] by %s\n", name, value, trigger ? "property_service" : "modifing prop data structure"); if (ret) - PRINT_E("resetprop: setprop error\n"); + LOGE("resetprop: setprop error\n"); return ret; } @@ -245,7 +245,7 @@ int deleteprop2(const char *name, int persist) { if (init_resetprop()) return -1; char path[PATH_MAX]; path[0] = '\0'; - PRINT_D("resetprop: deleteprop [%s]\n", name); + LOGD("resetprop: deleteprop [%s]\n", name); if (persist && strncmp(name, "persist.", 8) == 0) persist = persist_deleteprop(name); return __system_property_del(name) && !(persist && strncmp(name, "persist.", 8) == 0); @@ -253,10 +253,10 @@ int deleteprop2(const char *name, int persist) { int read_prop_file(const char* filename, const int trigger) { if (init_resetprop()) return -1; - PRINT_D("resetprop: Load prop file [%s]\n", filename); + LOGD("resetprop: Load prop file [%s]\n", filename); FILE *fp = fopen(filename, "r"); if (fp == NULL) { - PRINT_E("Cannot open [%s]\n", filename); + LOGE("Cannot open [%s]\n", filename); return 1; } char *line = NULL, *pch; @@ -292,7 +292,14 @@ int read_prop_file(const char* filename, const int trigger) { return 0; } +static int verbose_logging(const char *fmt, va_list ap) { + return prop_verbose ? vfprintf(stderr, fmt, ap) : 0; +} + int resetprop_main(int argc, char *argv[]) { + cmdline_logging(); + log_cb.d = verbose_logging; + int trigger = 1, persist = 0; char *argv0 = argv[0], *prop; diff --git a/native/jni/utils/img.c b/native/jni/utils/img.c index 27fa0059f..4e993f780 100644 --- a/native/jni/utils/img.c +++ b/native/jni/utils/img.c @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include #include #include @@ -97,6 +99,7 @@ static void usage() { } int imgtool_main(int argc, char *argv[]) { + cmdline_logging(); if (argc < 2) usage(); if (strcmp(argv[1], "create") == 0) { diff --git a/native/jni/utils/logging.c b/native/jni/utils/logging.c new file mode 100644 index 000000000..682fb7905 --- /dev/null +++ b/native/jni/utils/logging.c @@ -0,0 +1,88 @@ +#include +#include +#include + +#include "logging.h" + +int nop_log(const char *fmt, va_list ap) { + return 0; +} + +void nop_ex(int i) {} + +struct log_callback log_cb = { + .d = nop_log, + .i = nop_log, + .w = nop_log, + .e = nop_log, + .ex = nop_ex +}; + +void no_logging() { + log_cb.d = nop_log; + log_cb.i = nop_log; + log_cb.w = nop_log; + log_cb.e = nop_log; + log_cb.ex = nop_ex; +} + +#define LOG_TAG "Magisk" + +static int log_d(const char *fmt, va_list ap) { + return __android_log_vprint(ANDROID_LOG_DEBUG, LOG_TAG, fmt, ap); +} + +static int log_i(const char *fmt, va_list ap) { + return __android_log_vprint(ANDROID_LOG_INFO, LOG_TAG, fmt, ap); +} + +static int log_w(const char *fmt, va_list ap) { + return __android_log_vprint(ANDROID_LOG_WARN, LOG_TAG, fmt, ap); +} + +static int log_e(const char *fmt, va_list ap) { + return __android_log_vprint(ANDROID_LOG_ERROR, LOG_TAG, fmt, ap); +} + +void android_logging() { + log_cb.d = log_d; + log_cb.i = log_i; + log_cb.w = log_w; + log_cb.e = log_e; + log_cb.ex = nop_ex; +} + +static int vprinte(const char *fmt, va_list ap) { + return vfprintf(stderr, fmt, ap); +} + +void cmdline_logging() { + log_cb.d = vprinte; + log_cb.i = vprintf; + log_cb.w = vprinte; + log_cb.e = vprinte; + log_cb.ex = exit; +} + +int log_handler(log_type t, const char *fmt, ...) { + va_list argv; + int ret = 0; + va_start(argv, fmt); + switch (t) { + case L_DEBUG: + ret = log_cb.d(fmt, argv); + break; + case L_INFO: + ret = log_cb.i(fmt, argv); + break; + case L_WARN: + ret = log_cb.w(fmt, argv); + break; + case L_ERR: + ret = log_cb.e(fmt, argv); + log_cb.ex(1); + break; + } + va_end(argv); + return ret; +} diff --git a/native/jni/utils/selinux.c b/native/jni/utils/selinux.c index f25a4fd08..ebb86592c 100644 --- a/native/jni/utils/selinux.c +++ b/native/jni/utils/selinux.c @@ -1,9 +1,9 @@ #include #include +#include #include "magisk.h" #include "utils.h" -#include "logging.h" #include "selinux.h" #define UNLABEL_CON "u:object_r:unlabeled:s0"