Commit b39f4075 authored by topjohnwu's avatar topjohnwu

Load libsqlite dynamically

parent 615ad0cc
...@@ -13,6 +13,7 @@ LIBNANOPB := $(EXT_PATH)/nanopb ...@@ -13,6 +13,7 @@ LIBNANOPB := $(EXT_PATH)/nanopb
LIBSYSTEMPROPERTIES := jni/systemproperties/include LIBSYSTEMPROPERTIES := jni/systemproperties/include
LIBUTILS := jni/utils/include LIBUTILS := jni/utils/include
LIBMINCRYPT := $(EXT_PATH)/mincrypt/include LIBMINCRYPT := $(EXT_PATH)/mincrypt/include
LIBXZ := $(EXT_PATH)/xz-embedded
######################## ########################
# Binaries # Binaries
...@@ -22,11 +23,9 @@ ifdef B_MAGISK ...@@ -22,11 +23,9 @@ ifdef B_MAGISK
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_MODULE := magisk LOCAL_MODULE := magisk
LOCAL_SHARED_LIBRARIES := libsqlite
LOCAL_STATIC_LIBRARIES := libnanopb libsystemproperties libutils LOCAL_STATIC_LIBRARIES := libnanopb libsystemproperties libutils
LOCAL_C_INCLUDES := \ LOCAL_C_INCLUDES := \
jni/include \ jni/include \
$(EXT_PATH)/include \
$(LIBNANOPB) \ $(LIBNANOPB) \
$(LIBSYSTEMPROPERTIES) \ $(LIBSYSTEMPROPERTIES) \
$(LIBUTILS) $(LIBUTILS)
...@@ -98,9 +97,9 @@ ifdef BB_INIT ...@@ -98,9 +97,9 @@ ifdef BB_INIT
LOCAL_STATIC_LIBRARIES := libsepol libxz libutils LOCAL_STATIC_LIBRARIES := libsepol libxz libutils
LOCAL_C_INCLUDES := \ LOCAL_C_INCLUDES := \
jni/include \ jni/include \
$(EXT_PATH)/include \
out \ out \
out/$(TARGET_ARCH_ABI) \ out/$(TARGET_ARCH_ABI) \
$(LIBXZ) \
$(LIBSEPOL) \ $(LIBSEPOL) \
$(LIBUTILS) $(LIBUTILS)
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include <time.h> #include <time.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <dlfcn.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <magisk.h> #include <magisk.h>
...@@ -14,8 +15,93 @@ ...@@ -14,8 +15,93 @@
using namespace std; using namespace std;
typedef struct sqlite3 sqlite3;
static sqlite3 *mDB = nullptr; static sqlite3 *mDB = nullptr;
// SQLite APIs
#define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */
static int (*sqlite3_open_v2)(
const char *filename,
sqlite3 **ppDb,
int flags,
const char *zVfs);
static const char *(*sqlite3_errmsg)(sqlite3 *db);
static int (*sqlite3_close)(sqlite3 *db);
static void (*sqlite3_free)(void *v);
static int (*sqlite3_exec)(
sqlite3 *db,
const char *sql,
int (*callback)(void*, int, char**, char**),
void *v,
char **errmsg);
// Internal Android linker APIs
static void (*android_get_LD_LIBRARY_PATH)(char *buffer, size_t buffer_size);
static void (*android_update_LD_LIBRARY_PATH)(const char *ld_library_path);
#define DLERR(ptr) if (!(ptr)) { \
LOGE("db: %s\n", dlerror()); \
return false; \
}
#define DLOAD(handle, arg) {\
auto f = dlsym(handle, #arg); \
DLERR(f) \
*(void **) &(arg) = f; \
}
#if defined(__aarch64__) || defined(__x86_64__)
constexpr char apex_path[] = ":/apex/com.android.runtime/lib64";
#else
constexpr char apex_path[] = ":/apex/com.android.runtime/lib";
#endif
static int dl_init = 0;
static bool dload_sqlite() {
if (dl_init)
return dl_init > 0;
dl_init = -1;
auto sqlite = dlopen("libsqlite.so", RTLD_LAZY);
if (!sqlite) {
// Should only happen on Android 10+
auto dl = dlopen("libdl_android.so", RTLD_LAZY);
DLERR(dl);
DLOAD(dl, android_get_LD_LIBRARY_PATH);
DLOAD(dl, android_update_LD_LIBRARY_PATH);
// Inject APEX into LD_LIBRARY_PATH
char ld_path[4096];
android_get_LD_LIBRARY_PATH(ld_path, sizeof(ld_path));
int len = strlen(ld_path);
strcpy(ld_path + len, apex_path);
android_update_LD_LIBRARY_PATH(ld_path);
sqlite = dlopen("libsqlite.so", RTLD_LAZY);
// Revert LD_LIBRARY_PATH just in case
ld_path[len] = '\0';
android_update_LD_LIBRARY_PATH(ld_path);
}
DLERR(sqlite);
DLOAD(sqlite, sqlite3_open_v2);
DLOAD(sqlite, sqlite3_errmsg);
DLOAD(sqlite, sqlite3_close);
DLOAD(sqlite, sqlite3_exec);
DLOAD(sqlite, sqlite3_free);
dl_init = 1;
return true;
}
int db_strings::getKeyIdx(string_view key) const { int db_strings::getKeyIdx(string_view key) const {
int idx = DB_STRING_NUM; int idx = DB_STRING_NUM;
for (int i = 0; i < DB_STRING_NUM; ++i) { for (int i = 0; i < DB_STRING_NUM; ++i) {
...@@ -50,6 +136,9 @@ static int ver_cb(void *ver, int, char **data, char **) { ...@@ -50,6 +136,9 @@ static int ver_cb(void *ver, int, char **data, char **) {
#define err_ret(e) if (e) return e; #define err_ret(e) if (e) return e;
static char *open_and_init_db(sqlite3 *&db) { static char *open_and_init_db(sqlite3 *&db) {
if (!dload_sqlite())
return strdup("Cannot load libsqlite.so");
int ret = sqlite3_open_v2(MAGISKDB, &db, int ret = sqlite3_open_v2(MAGISKDB, &db,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, nullptr); SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, nullptr);
if (ret) if (ret)
...@@ -304,3 +393,12 @@ void exec_sql(int client) { ...@@ -304,3 +393,12 @@ void exec_sql(int client) {
write_int(client, 0); write_int(client, 0);
db_err_cmd(err, return; ); db_err_cmd(err, return; );
} }
bool db_err(char *e) {
if (e) {
LOGE("sqlite3_exec: %s\n", e);
sqlite3_free(e);
return true;
}
return false;
}
LOCAL_PATH := $(call my-dir) LOCAL_PATH := $(call my-dir)
ifdef B_MAGISK
# libsqlite.so (stub)
include $(CLEAR_VARS)
LOCAL_MODULE:= libsqlite
LOCAL_C_INCLUDES := $(EXT_PATH)/include
LOCAL_SRC_FILES := stubs/sqlite3_stub.c
include $(BUILD_SHARED_LIBRARY)
endif
# libselinux.so (stub)
#include $(CLEAR_VARS)
#LOCAL_MODULE:= libselinux
#LOCAL_C_INCLUDES := $(LIBSELINUX)
#LOCAL_SRC_FILES := stubs/selinux_stub.c
#include $(BUILD_SHARED_LIBRARY)
# libxz.a # libxz.a
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_MODULE:= libxz LOCAL_MODULE:= libxz
LOCAL_C_INCLUDES := $(EXT_PATH)/include LOCAL_C_INCLUDES := $(LIBXZ)
LOCAL_SRC_FILES := \ LOCAL_SRC_FILES := \
xz-embedded/xz_crc32.c \ xz-embedded/xz_crc32.c \
xz-embedded/xz_dec_lzma2.c \ xz-embedded/xz_dec_lzma2.c \
...@@ -83,7 +65,7 @@ include $(BUILD_STATIC_LIBRARY) ...@@ -83,7 +65,7 @@ include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_MODULE := liblzma LOCAL_MODULE := liblzma
LOCAL_C_INCLUDES += \ LOCAL_C_INCLUDES += \
$(EXT_PATH)/include/xz_config \ $(EXT_PATH)/xz_config \
$(EXT_PATH)/xz/src/common \ $(EXT_PATH)/xz/src/common \
$(EXT_PATH)/xz/src/liblzma/api \ $(EXT_PATH)/xz/src/liblzma/api \
$(EXT_PATH)/xz/src/liblzma/check \ $(EXT_PATH)/xz/src/liblzma/check \
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#pragma once #pragma once
#include <sqlite3.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <map> #include <map>
#include <string> #include <string>
#include <string_view> #include <string_view>
#include <functional> #include <functional>
#define db_err(e) db_err_cmd(e, )
#define db_err_cmd(e, cmd) if (e) { \
LOGE("sqlite3_exec: %s\n", e); \
sqlite3_free(e); \
cmd;\
}
template <class T, size_t num> template <class T, size_t num>
class db_data_base { class db_data_base {
public: public:
...@@ -160,4 +152,6 @@ bool validate_manager(std::string &pkg, int userid, struct stat *st); ...@@ -160,4 +152,6 @@ bool validate_manager(std::string &pkg, int userid, struct stat *st);
void exec_sql(int client); void exec_sql(int client);
char *db_exec(const char *sql); char *db_exec(const char *sql);
char *db_exec(const char *sql, const db_row_cb &fn); char *db_exec(const char *sql, const db_row_cb &fn);
bool db_err(char *e);
#define db_err_cmd(e, cmd) if (db_err(e)) { cmd; }
...@@ -182,12 +182,6 @@ bool MagiskInit::patch_sepolicy(const char *file) { ...@@ -182,12 +182,6 @@ bool MagiskInit::patch_sepolicy(const char *file) {
return patch_init; return patch_init;
} }
constexpr const char wrapper[] =
"#!/system/bin/sh\n"
"export LD_LIBRARY_PATH=\"$LD_LIBRARY_PATH:/apex/com.android.runtime/" LIBNAME "\"\n"
"exec /sbin/magisk.bin \"$0\" \"$@\"\n"
;
static void sbin_overlay(const raw_data &self, const raw_data &config) { static void sbin_overlay(const raw_data &self, const raw_data &config) {
mount_sbin(); mount_sbin();
...@@ -199,17 +193,8 @@ static void sbin_overlay(const raw_data &self, const raw_data &config) { ...@@ -199,17 +193,8 @@ static void sbin_overlay(const raw_data &self, const raw_data &config) {
fd = xopen("/sbin/magiskinit", O_WRONLY | O_CREAT, 0755); fd = xopen("/sbin/magiskinit", O_WRONLY | O_CREAT, 0755);
xwrite(fd, self.buf, self.sz); xwrite(fd, self.buf, self.sz);
close(fd); close(fd);
if (access("/system/apex", F_OK) == 0) { dump_magisk("/sbin/magisk", 0755);
LOGD("APEX detected, use wrapper\n"); patch_socket_name("/sbin/magisk");
dump_magisk("/sbin/magisk.bin", 0755);
patch_socket_name("/sbin/magisk.bin");
fd = xopen("/sbin/magisk", O_WRONLY | O_CREAT, 0755);
xwrite(fd, wrapper, sizeof(wrapper) - 1);
close(fd);
} else {
dump_magisk("/sbin/magisk", 0755);
patch_socket_name("/sbin/magisk");
}
// Create applet symlinks // Create applet symlinks
char path[64]; char path[64];
......
...@@ -96,17 +96,7 @@ else ...@@ -96,17 +96,7 @@ else
fi fi
# Magisk stuffs # Magisk stuffs
if [ -e /apex ]; then ./magiskinit -x magisk /sbin/magisk
./magiskinit -x magisk /sbin/magisk.bin
[ -e /system/lib64 ] && LIB=lib64 || LIB=lib
cat <<EOF > /sbin/magisk
#!/system/bin/sh
export LD_LIBRARY_PATH="\$LD_LIBRARY_PATH:/apex/com.android.runtime/$LIB"
exec /sbin/magisk.bin "\$0" "\$@"
EOF
else
./magiskinit -x magisk /sbin/magisk
fi
chmod 755 /sbin/magisk chmod 755 /sbin/magisk
ln -s ./magisk /sbin/su ln -s ./magisk /sbin/su
ln -s ./magisk /sbin/resetprop ln -s ./magisk /sbin/resetprop
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment