Optimize logging in Magisk Manager

This commit is contained in:
topjohnwu 2018-10-27 22:06:24 -04:00
parent 1046dd5eda
commit bf4a46d57c
8 changed files with 105 additions and 46 deletions

View File

@ -19,6 +19,7 @@ public class SuLogEntry {
fromUid = policy.uid; fromUid = policy.uid;
packageName = policy.packageName; packageName = policy.packageName;
appName = policy.appName; appName = policy.appName;
action = policy.policy == Policy.ALLOW;
} }
public SuLogEntry(ContentValues values) { public SuLogEntry(ContentValues values) {

View File

@ -14,8 +14,13 @@ public class BootReceiver extends BroadcastReceiver {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
if (intent == null)
return;
if (TextUtils.equals(intent.getAction(), Intent.ACTION_BOOT_COMPLETED)) { if (TextUtils.equals(intent.getAction(), Intent.ACTION_BOOT_COMPLETED)) {
switch (intent.getExtras().getString("action", "boot")) { String action = intent.getStringExtra("action");
if (action == null)
action = "boot";
switch (action) {
case "request": case "request":
Intent i = new Intent(context, Data.classMap.get(SuRequestActivity.class)) Intent i = new Intent(context, Data.classMap.get(SuRequestActivity.class))
.putExtra("socket", intent.getStringExtra("socket")) .putExtra("socket", intent.getStringExtra("socket"))
@ -26,6 +31,9 @@ public class BootReceiver extends BroadcastReceiver {
case "log": case "log":
SuConnector.handleLogs(intent, 2); SuConnector.handleLogs(intent, 2);
break; break;
case "notify":
SuConnector.handleNotify(intent);
break;
case "boot": case "boot":
OnBootService.enqueueWork(context); OnBootService.enqueueWork(context);
break; break;

View File

@ -10,6 +10,7 @@ public class SuReceiver extends BroadcastReceiver {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
if (intent != null)
SuConnector.handleLogs(intent, 1); SuConnector.handleLogs(intent, 1);
} }
} }

View File

@ -50,58 +50,56 @@ public abstract class SuConnector {
public abstract void response(); public abstract void response();
public static void handleLogs(Intent intent, int version) { public static void handleLogs(Intent intent, int version) {
MagiskManager mm = Data.MM();
if (intent == null) return;
int fromUid = intent.getIntExtra("from.uid", -1); int fromUid = intent.getIntExtra("from.uid", -1);
if (fromUid < 0) return; if (fromUid < 0) return;
if (fromUid == Process.myUid()) return; if (fromUid == Process.myUid()) return;
Policy policy = mm.mDB.getPolicy(fromUid); MagiskManager mm = Data.MM();
if (policy == null) { PackageManager pm = mm.getPackageManager();
Policy policy;
boolean notify;
Bundle data = intent.getExtras();
if (data.containsKey("notify")) {
notify = data.getBoolean("notify");
try { try {
policy = new Policy(fromUid, mm.getPackageManager()); policy = new Policy(fromUid, pm);
} catch (PackageManager.NameNotFoundException e) { } catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return; return;
} }
} else {
// Doesn't report whether notify or not, check database ourselves
policy = mm.mDB.getPolicy(fromUid);
if (policy == null)
return;
notify = policy.notification;
} }
SuLogEntry log = new SuLogEntry(policy);
if (version == 1) { if (version == 1) {
String action = intent.getStringExtra("action"); String action = intent.getStringExtra("action");
if (action == null) return; if (action == null) return;
switch (action) { switch (action) {
case "allow": case "allow":
log.action = true; policy.policy = Policy.ALLOW;
break; break;
case "deny": case "deny":
log.action = false; policy.policy = Policy.DENY;
break; break;
default: default:
return; return;
} }
} else { } else {
switch (intent.getIntExtra("policy", -1)) { policy.policy = data.getInt("policy", -1);
case Policy.ALLOW: if (policy.policy < 0)
log.action = true;
break;
case Policy.DENY:
log.action = false;
break;
default:
return; return;
} }
}
String message = mm.getString(log.action ? if (notify)
R.string.su_allow_toast : R.string.su_deny_toast, policy.appName); handleNotify(policy);
if (policy.notification && Data.suNotificationType == Const.Value.NOTIFICATION_TOAST) SuLogEntry log = new SuLogEntry(policy);
Utils.toast(message, Toast.LENGTH_SHORT);
if (policy.logging) {
int toUid = intent.getIntExtra("to.uid", -1); int toUid = intent.getIntExtra("to.uid", -1);
if (toUid < 0) return; if (toUid < 0) return;
int pid = intent.getIntExtra("pid", -1); int pid = intent.getIntExtra("pid", -1);
@ -114,5 +112,25 @@ public abstract class SuConnector {
log.date = new Date(); log.date = new Date();
mm.mDB.addLog(log); mm.mDB.addLog(log);
} }
private static void handleNotify(Policy policy) {
MagiskManager mm = Data.MM();
String message = mm.getString(policy.policy == Policy.ALLOW ?
R.string.su_allow_toast : R.string.su_deny_toast, policy.appName);
if (policy.notification && Data.suNotificationType == Const.Value.NOTIFICATION_TOAST)
Utils.toast(message, Toast.LENGTH_SHORT);
}
public static void handleNotify(Intent intent) {
MagiskManager mm = Data.MM();
int fromUid = intent.getIntExtra("from.uid", -1);
if (fromUid < 0) return;
if (fromUid == Process.myUid()) return;
try {
Policy policy = new Policy(fromUid, mm.getPackageManager());
policy.policy = intent.getIntExtra("policy", -1);
if (policy.policy >= 0)
handleNotify(policy);
} catch (PackageManager.NameNotFoundException ignored) {}
} }
} }

View File

@ -15,32 +15,31 @@ static int ver_cb(void *v, int col_num, char **data, char **col_name) {
sqlite3 *get_magiskdb() { sqlite3 *get_magiskdb() {
sqlite3 *db; sqlite3 *db;
char *err;
int ret = sqlite3_open(MAGISKDB, &db); int ret = sqlite3_open(MAGISKDB, &db);
if (ret) { if (ret) {
LOGE("sqlite3 open failure: %s\n", sqlite3_errstr(ret)); LOGE("sqlite3 open failure: %s\n", sqlite3_errstr(ret));
return NULL; return NULL;
} }
int ver, upgrade = 0; int ver, upgrade = 0;
sqlite3_exec(db, "PRAGMA user_version", ver_cb, &ver, &err); sqlite3_exec(db, "PRAGMA user_version", ver_cb, &ver, NULL);
if (ver < 3) { if (ver < 3) {
// Policies // Policies
sqlite3_exec(db, sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS policies " "CREATE TABLE IF NOT EXISTS policies "
"(uid INT, package_name TEXT, policy INT, until INT, " "(uid INT, package_name TEXT, policy INT, until INT, "
"logging INT, notification INT, PRIMARY KEY(uid))", "logging INT, notification INT, PRIMARY KEY(uid))",
NULL, NULL, &err); NULL, NULL, NULL);
// Logs // Logs
sqlite3_exec(db, sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS logs " "CREATE TABLE IF NOT EXISTS logs "
"(from_uid INT, package_name TEXT, app_name TEXT, from_pid INT, " "(from_uid INT, package_name TEXT, app_name TEXT, from_pid INT, "
"to_uid INT, action INT, time INT, command TEXT)", "to_uid INT, action INT, time INT, command TEXT)",
NULL, NULL, &err); NULL, NULL, NULL);
// Settings // Settings
sqlite3_exec(db, sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS settings " "CREATE TABLE IF NOT EXISTS settings "
"(key TEXT, value INT, PRIMARY KEY(key))", "(key TEXT, value INT, PRIMARY KEY(key))",
NULL, NULL, &err); NULL, NULL, NULL);
ver = 3; ver = 3;
upgrade = 1; upgrade = 1;
} }
@ -49,12 +48,12 @@ sqlite3 *get_magiskdb() {
sqlite3_exec(db, sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS strings " "CREATE TABLE IF NOT EXISTS strings "
"(key TEXT, value TEXT, PRIMARY KEY(key))", "(key TEXT, value TEXT, PRIMARY KEY(key))",
NULL, NULL, &err); NULL, NULL, NULL);
ver = 4; ver = 4;
upgrade = 1; upgrade = 1;
} }
if (ver == 4) { if (ver == 4) {
sqlite3_exec(db, "UPDATE policies SET uid=uid%100000", NULL, NULL, &err); sqlite3_exec(db, "UPDATE policies SET uid=uid%100000", NULL, NULL, NULL);
/* Skip version 5 */ /* Skip version 5 */
ver = 6; ver = 6;
upgrade = 1; upgrade = 1;
@ -64,7 +63,7 @@ sqlite3 *get_magiskdb() {
// Set version // Set version
char query[32]; char query[32];
sprintf(query, "PRAGMA user_version=%d", ver); sprintf(query, "PRAGMA user_version=%d", ver);
sqlite3_exec(db, query, NULL, NULL, &err); sqlite3_exec(db, query, NULL, NULL, NULL);
} }
return db; return db;
} }
@ -102,6 +101,7 @@ int get_db_settings(sqlite3 *db, int key, struct db_settings *dbs) {
} }
if (err) { if (err) {
LOGE("sqlite3_exec: %s\n", err); LOGE("sqlite3_exec: %s\n", err);
sqlite3_free(err);
return 1; return 1;
} }
return 0; return 0;
@ -141,6 +141,7 @@ int get_db_strings(sqlite3 *db, int key, struct db_strings *str) {
} }
if (err) { if (err) {
LOGE("sqlite3_exec: %s\n", err); LOGE("sqlite3_exec: %s\n", err);
sqlite3_free(err);
return 1; return 1;
} }
return 0; return 0;
@ -169,6 +170,7 @@ int get_uid_policy(sqlite3 *db, int uid, struct su_access *su) {
sqlite3_exec(db, query, policy_cb, su, &err); sqlite3_exec(db, query, policy_cb, su, &err);
if (err) { if (err) {
LOGE("sqlite3_exec: %s\n", err); LOGE("sqlite3_exec: %s\n", err);
sqlite3_free(err);
return 1; return 1;
} }
return 0; return 0;

View File

@ -82,6 +82,32 @@ void app_log(struct su_context *ctx) {
"--ei", "pid", pid, "--ei", "pid", pid,
"--ei", "policy", policy, "--ei", "policy", policy,
"--es", "command", get_command(&ctx->req), "--es", "command", get_command(&ctx->req),
"--ez", "notify", ctx->info->access.notify ? "true" : "false",
NULL
};
silent_run(cmd);
}
void app_notify(struct su_context *ctx) {
char user[8];
setup_user(user, ctx->info);
char fromUid[8];
sprintf(fromUid, "%d",
DB_SET(ctx->info, SU_MULTIUSER_MODE) == MULTIUSER_MODE_OWNER_MANAGED ?
ctx->info->uid % 100000 : ctx->info->uid);
char policy[2];
sprintf(policy, "%d", ctx->info->access.policy);
char *cmd[] = {
AM_PATH, "broadcast",
"-a", "android.intent.action.BOOT_COMPLETED",
"-p", DB_STR(ctx->info, SU_MANAGER),
"--user", user,
"--es", "action", "notify",
"--ei", "from.uid", fromUid,
"--ei", "policy", policy,
NULL NULL
}; };
silent_run(cmd); silent_run(cmd);

View File

@ -54,6 +54,7 @@ struct su_context {
// connect.c // connect.c
void app_log(struct su_context *ctx); void app_log(struct su_context *ctx);
void app_notify(struct su_context *ctx);
void app_connect(const char *socket, struct su_info *info); void app_connect(const char *socket, struct su_info *info);
void socket_send_request(int fd, struct su_info *info); void socket_send_request(int fd, struct su_info *info);

View File

@ -361,8 +361,10 @@ void su_daemon_handler(int client, struct ucred *credential) {
break; break;
} }
if (info->access.notify || info->access.log) if (info->access.log)
app_log(&ctx); app_log(&ctx);
else if (info->access.notify)
app_notify(&ctx);
if (info->access.policy == ALLOW) { if (info->access.policy == ALLOW) {
char* argv[] = { NULL, NULL, NULL, NULL }; char* argv[] = { NULL, NULL, NULL, NULL };