Skip to content
This repository has been archived by the owner on Jul 18, 2018. It is now read-only.

Commit

Permalink
Support changing requester in DB
Browse files Browse the repository at this point in the history
  • Loading branch information
topjohnwu committed Oct 28, 2017
1 parent 6de95e0 commit 4335c58
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 169 deletions.
88 changes: 33 additions & 55 deletions activity.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@
#include "su.h"

/* intent actions */
#define ACTION_REQUEST "start", "-n", REQUESTOR "/" REQUESTOR_PREFIX ".RequestActivity"
#define ACTION_NOTIFY "start", "-n", REQUESTOR "/" REQUESTOR_PREFIX ".NotifyActivity"
#define ACTION_RESULT "broadcast", "-n", REQUESTOR "/" REQUESTOR_PREFIX ".SuReceiver"
#define ACTION_REQUEST "%s/" REQUESTOR_PREFIX ".RequestActivity"
#define ACTION_RESULT "%s/" REQUESTOR_PREFIX ".SuReceiver"

#define AM_PATH "/system/bin/app_process", "/system/bin", "com.android.commands.am.Am"

Expand Down Expand Up @@ -73,30 +72,20 @@ void app_send_result(struct su_context *ctx, policy_t policy) {
char user[16];
int notify = setup_user(ctx, user);

char activity[128];
sprintf(activity, ACTION_RESULT, ctx->path.pkg_name);

// Send notice to manager, enable logging
char *result_command[] = {
AM_PATH,
ACTION_RESULT,
"--user",
user,
"--ei",
"mode",
"0",
"--ei",
"from.uid",
fromUid,
"--ei",
"to.uid",
toUid,
"--ei",
"pid",
pid,
"--es",
"command",
get_command(&ctx->to),
"--es",
"action",
policy == ALLOW ? "allow" : "deny",
AM_PATH, "broadcast", "-n",
activity,
"--user", user,
"--ei", "mode", "0",
"--ei", "from.uid", fromUid,
"--ei", "to.uid", toUid,
"--ei", "pid", pid,
"--es", "command", get_command(&ctx->to),
"--es", "action", policy == ALLOW ? "allow" : "deny",
NULL
};
silent_run(result_command);
Expand All @@ -105,19 +94,12 @@ void app_send_result(struct su_context *ctx, policy_t policy) {
if (notify) {
sprintf(user, "%d", notify);
char *notify_command[] = {
AM_PATH,
ACTION_RESULT,
"--user",
user,
"--ei",
"mode",
"1",
"--ei",
"from.uid",
fromUid,
"--es",
"action",
policy == ALLOW ? "allow" : "deny",
AM_PATH, "broadcast", "-n",
activity,
"--user", user,
"--ei", "mode", "1",
"--ei", "from.uid", fromUid,
"--es", "action", policy == ALLOW ? "allow" : "deny",
NULL
};
silent_run(notify_command);
Expand All @@ -128,32 +110,28 @@ void app_send_request(struct su_context *ctx) {
char user[16];
int notify = setup_user(ctx, user);

char activity[128];
sprintf(activity, ACTION_REQUEST, ctx->path.pkg_name);

char *request_command[] = {
AM_PATH,
ACTION_REQUEST,
"--user",
user,
"--es",
"socket",
ctx->path.sock_path,
"--ez",
"timeout",
notify ? "false" : "true",
AM_PATH, "start", "-n",
activity,
"--user", user,
"--es", "socket", ctx->path.sock_path,
"--ez", "timeout", notify ? "false" : "true",
NULL
};
silent_run(request_command);

// Send notice to user to tell them root is managed by owner
if (notify) {
sprintf(user, "%d", notify);
sprintf(activity, ACTION_RESULT, ctx->path.pkg_name);
char *notify_command[] = {
AM_PATH,
ACTION_RESULT,
"--user",
user,
"--ei",
"mode",
"2",
AM_PATH, "broadcast", "-n",
activity,
"--user", user,
"--ei", "mode", "2",
NULL
};
silent_run(notify_command);
Expand Down
95 changes: 72 additions & 23 deletions db.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,60 +58,109 @@ static int settings_callback(void *v, int argc, char **argv, char **azColName) {
return 0;
}

static int strings_callback(void *v, int argc, char **argv, char **azColName) {
struct su_context *ctx = (struct su_context *) v;
char *entry, *target, *value;
for (int i = 0; i < argc; ++i) {
if (strcmp(azColName[i], "key") == 0) {
if (strcmp(argv[i], REQUESTER_ENTRY) == 0)
target = ctx->path.pkg_name;
entry = argv[i];
} else if (strcmp(azColName[i], "value") == 0) {
value = argv[i];
}
}
LOGD("su_db: query %s=[%s]\n", entry, value);
strcpy(target, value);
return 0;
}

#define BASE_FMT "/data/user%s/%d"
#define USE_MULTI(info) (info->uid / 100000 != 0 && info->multiuser_mode == MULTIUSER_MODE_USER)

void database_check(struct su_context *ctx) {
sqlite3 *db = NULL;
int ret;
char query[512], *err = NULL;
char buffer[PATH_MAX], *err = NULL;

// Set default values
ctx->info->root_access = ROOT_ACCESS_APPS_AND_ADB;
ctx->info->multiuser_mode = MULTIUSER_MODE_OWNER_ONLY;
ctx->info->mnt_ns = NAMESPACE_MODE_REQUESTER;
ctx->info->policy = QUERY;
strcpy(ctx->path.pkg_name, "???"); /* bad string so it doesn't exist */

// Populate paths
sprintf(ctx->path.base_path, BASE_FMT, "_de", 0);
if (access(ctx->path.base_path, R_OK) == -1)
sprintf(ctx->path.base_path, BASE_FMT, "", 0);

sprintf(ctx->path.multiuser_path, BASE_FMT, "_de", ctx->info->uid / 100000);
if (access(ctx->path.multiuser_path, R_OK) == -1)
sprintf(ctx->path.multiuser_path, BASE_FMT, "", ctx->info->uid / 100000);

// Open database
ret = sqlite3_open_v2(ctx->path.base_db, &db, SQLITE_OPEN_READONLY, NULL);
sprintf(buffer, "%s/magisk.db", ctx->path.base_path);
LOGD("su_db: open %s", buffer);
ret = sqlite3_open_v2(buffer, &db, SQLITE_OPEN_READONLY, NULL);
if (ret) {
LOGD("sqlite3 open failure: %s\n", sqlite3_errstr(ret));
sqlite3_close(db);
return;
goto stat_requester;
}

// Check multiuser mode settings
snprintf(query, sizeof(query), "SELECT key, value FROM settings WHERE key='%s'", MULTIUSER_MODE_ENTRY);
sqlite3_exec(db, query, settings_callback, ctx, &err);

sprintf(buffer, "SELECT key, value FROM settings WHERE key='%s'", MULTIUSER_MODE_ENTRY);
sqlite3_exec(db, buffer, settings_callback, ctx, &err);
if (err != NULL)
LOGE("sqlite3_exec: %s\n", err);
err = NULL;

if (ctx->info->uid / 100000 != 0 && ctx->info->multiuser_mode == MULTIUSER_MODE_USER) {
// Open database based on multiuser settings
if (USE_MULTI(ctx->info)) {
sqlite3_close(db);

// Open database
ret = sqlite3_open_v2(ctx->path.multiuser_db, &db, SQLITE_OPEN_READONLY, NULL);
sprintf(buffer, "%s/magisk.db", ctx->path.multiuser_path);
LOGD("su_db: open %s", buffer);
ret = sqlite3_open_v2(buffer, &db, SQLITE_OPEN_READONLY, NULL);
if (ret) {
LOGD("sqlite3 open failure: %s\n", sqlite3_errstr(ret));
sqlite3_close(db);
return;
goto stat_requester;
}
}

// Query for policy
snprintf(query, sizeof(query), "SELECT policy, until FROM policies WHERE uid=%d", ctx->info->uid % 100000);
sqlite3_exec(db, query, policy_callback, ctx, &err);
if (err != NULL) {
// Read PKG name from DB
strcpy(buffer, "SELECT key, value FROM strings");
sqlite3_exec(db, buffer, strings_callback, ctx, &err);
if (err != NULL)
LOGE("sqlite3_exec: %s\n", err);
return;
}
err = NULL;

// Query for policy
sprintf(buffer, "SELECT policy, until FROM policies WHERE uid=%d", ctx->info->uid % 100000);
sqlite3_exec(db, buffer, policy_callback, ctx, &err);
if (err != NULL)
LOGE("sqlite3_exec: %s\n", err);
err = NULL;

// Query for settings
snprintf(query, sizeof(query), "SELECT key, value FROM settings WHERE key!='%s'", MULTIUSER_MODE_ENTRY);
sqlite3_exec(db, query, settings_callback, ctx, &err);
if (err != NULL) {
sprintf(buffer, "SELECT key, value FROM settings WHERE key!='%s'", MULTIUSER_MODE_ENTRY);
sqlite3_exec(db, buffer, settings_callback, ctx, &err);
if (err != NULL)
LOGE("sqlite3_exec: %s\n", err);
return;
}

sqlite3_close(db);

stat_requester:
// We prefer the orignal name
sprintf(buffer, "%s/%s", USE_MULTI(ctx->info) ? ctx->path.multiuser_path : ctx->path.base_path, JAVA_PACKAGE_NAME);
if (stat(buffer, &ctx->st) == -1) {
sprintf(buffer, "%s/%s", USE_MULTI(ctx->info) ? ctx->path.multiuser_path : ctx->path.base_path, ctx->path.pkg_name);
if (stat(buffer, &ctx->st) == -1) {
LOGE("su: cannot find requester");
ctx->info->policy = DENY;
ctx->notify = 0;
}
} else {
strcpy(ctx->path.pkg_name, JAVA_PACKAGE_NAME);
}
}
25 changes: 6 additions & 19 deletions su.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,9 @@ static void cleanup_signal(int sig) {
__attribute__ ((noreturn)) void exit2(int status) {
// Handle the pipe, or the daemon will get stuck
if (su_ctx->info->policy == QUERY) {
xwrite(pipefd[1], &su_ctx->info->policy, sizeof(su_ctx->info->policy));
close(pipefd[0]);
close(pipefd[1]);
xwrite(su_ctx->pipefd[1], &su_ctx->info->policy, sizeof(su_ctx->info->policy));
close(su_ctx->pipefd[0]);
close(su_ctx->pipefd[1]);
}
exit(status);
}
Expand Down Expand Up @@ -352,19 +352,6 @@ int su_daemon_main(int argc, char **argv) {

// New request or no db exist, notify user for response
if (su_ctx->info->policy == QUERY) {
mkdir(REQUESTOR_CACHE_PATH, 0770);
if (chown(REQUESTOR_CACHE_PATH, su_ctx->st.st_uid, su_ctx->st.st_gid))
PLOGE("chown (%s, %u, %u)", REQUESTOR_CACHE_PATH, su_ctx->st.st_uid, su_ctx->st.st_gid);

if (setgroups(0, NULL))
PLOGE("setgroups");

if (setegid(su_ctx->st.st_gid))
PLOGE("setegid (%u)", su_ctx->st.st_gid);

if (seteuid(su_ctx->st.st_uid))
PLOGE("seteuid (%u)", su_ctx->st.st_uid);

socket_serv_fd = socket_create_temp(su_ctx->path.sock_path, sizeof(su_ctx->path.sock_path));
setup_sighandlers(cleanup_signal);

Expand All @@ -387,9 +374,9 @@ int su_daemon_main(int argc, char **argv) {
su_ctx->info->policy = DENY;

// Report the policy to main daemon
xwrite(pipefd[1], &su_ctx->info->policy, sizeof(su_ctx->info->policy));
close(pipefd[0]);
close(pipefd[1]);
xwrite(su_ctx->pipefd[1], &su_ctx->info->policy, sizeof(su_ctx->info->policy));
close(su_ctx->pipefd[0]);
close(su_ctx->pipefd[1]);
}

if (su_ctx->info->policy == ALLOW)
Expand Down
14 changes: 5 additions & 9 deletions su.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,14 @@
#define NAMESPACE_MODE_REQUESTER 1
#define NAMESPACE_MODE_ISOLATE 2

// DB entry for requester
#define REQUESTER_ENTRY "requester"

// DO NOT CHANGE LINE BELOW, java package name will always be the same
#define JAVA_PACKAGE_NAME "com.topjohnwu.magisk"

// If --rename-manifest-package is used in AAPT, this
// must be changed to correspond to the new APK package name
// See the two Android.mk files for more details.
#define REQUESTOR JAVA_PACKAGE_NAME
// This is used if wrapping the fragment classes and activities
// with classes in another package.
#define REQUESTOR_PREFIX JAVA_PACKAGE_NAME ".superuser"
#define REQUESTOR_CACHE_PATH "/dev/" REQUESTOR

#define DEFAULT_SHELL "/system/bin/sh"

Expand Down Expand Up @@ -80,9 +77,8 @@ struct su_request {

struct su_path {
char base_path[PATH_MAX];
char base_db[PATH_MAX];
char multiuser_path[PATH_MAX];
char multiuser_db[PATH_MAX];
char pkg_name[PATH_MAX];
char sock_path[PATH_MAX];
};

Expand All @@ -95,10 +91,10 @@ struct su_context {
mode_t umask;
char *cwd;
struct stat st;
int pipefd[2];
};

extern struct su_context *su_ctx;
extern int pipefd[2];

// su.c

Expand Down
Loading

0 comments on commit 4335c58

Please sign in to comment.