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;
packageName = policy.packageName;
appName = policy.appName;
action = policy.policy == Policy.ALLOW;
}
public SuLogEntry(ContentValues values) {

View File

@ -14,8 +14,13 @@ public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent == null)
return;
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":
Intent i = new Intent(context, Data.classMap.get(SuRequestActivity.class))
.putExtra("socket", intent.getStringExtra("socket"))
@ -26,6 +31,9 @@ public class BootReceiver extends BroadcastReceiver {
case "log":
SuConnector.handleLogs(intent, 2);
break;
case "notify":
SuConnector.handleNotify(intent);
break;
case "boot":
OnBootService.enqueueWork(context);
break;

View File

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

View File

@ -50,69 +50,87 @@ public abstract class SuConnector {
public abstract void response();
public static void handleLogs(Intent intent, int version) {
MagiskManager mm = Data.MM();
if (intent == null) return;
int fromUid = intent.getIntExtra("from.uid", -1);
if (fromUid < 0) return;
if (fromUid == Process.myUid()) return;
Policy policy = mm.mDB.getPolicy(fromUid);
if (policy == null) {
MagiskManager mm = Data.MM();
PackageManager pm = mm.getPackageManager();
Policy policy;
boolean notify;
Bundle data = intent.getExtras();
if (data.containsKey("notify")) {
notify = data.getBoolean("notify");
try {
policy = new Policy(fromUid, mm.getPackageManager());
policy = new Policy(fromUid, pm);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
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) {
String action = intent.getStringExtra("action");
if (action == null) return;
switch (action) {
case "allow":
log.action = true;
policy.policy = Policy.ALLOW;
break;
case "deny":
log.action = false;
policy.policy = Policy.DENY;
break;
default:
return;
}
} else {
switch (intent.getIntExtra("policy", -1)) {
case Policy.ALLOW:
log.action = true;
break;
case Policy.DENY:
log.action = false;
break;
default:
return;
}
policy.policy = data.getInt("policy", -1);
if (policy.policy < 0)
return;
}
String message = mm.getString(log.action ?
R.string.su_allow_toast : R.string.su_deny_toast, policy.appName);
if (notify)
handleNotify(policy);
SuLogEntry log = new SuLogEntry(policy);
int toUid = intent.getIntExtra("to.uid", -1);
if (toUid < 0) return;
int pid = intent.getIntExtra("pid", -1);
if (pid < 0) return;
String command = intent.getStringExtra("command");
if (command == null) return;
log.toUid = toUid;
log.fromPid = pid;
log.command = command;
log.date = new Date();
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);
}
if (policy.logging) {
int toUid = intent.getIntExtra("to.uid", -1);
if (toUid < 0) return;
int pid = intent.getIntExtra("pid", -1);
if (pid < 0) return;
String command = intent.getStringExtra("command");
if (command == null) return;
log.toUid = toUid;
log.fromPid = pid;
log.command = command;
log.date = new Date();
mm.mDB.addLog(log);
}
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 *db;
char *err;
int ret = sqlite3_open(MAGISKDB, &db);
if (ret) {
LOGE("sqlite3 open failure: %s\n", sqlite3_errstr(ret));
return NULL;
}
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) {
// Policies
sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS policies "
"(uid INT, package_name TEXT, policy INT, until INT, "
"logging INT, notification INT, PRIMARY KEY(uid))",
NULL, NULL, &err);
NULL, NULL, NULL);
// Logs
sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS logs "
"(from_uid INT, package_name TEXT, app_name TEXT, from_pid INT, "
"to_uid INT, action INT, time INT, command TEXT)",
NULL, NULL, &err);
NULL, NULL, NULL);
// Settings
sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS settings "
"(key TEXT, value INT, PRIMARY KEY(key))",
NULL, NULL, &err);
NULL, NULL, NULL);
ver = 3;
upgrade = 1;
}
@ -49,12 +48,12 @@ sqlite3 *get_magiskdb() {
sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS strings "
"(key TEXT, value TEXT, PRIMARY KEY(key))",
NULL, NULL, &err);
NULL, NULL, NULL);
ver = 4;
upgrade = 1;
}
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 */
ver = 6;
upgrade = 1;
@ -64,7 +63,7 @@ sqlite3 *get_magiskdb() {
// Set version
char query[32];
sprintf(query, "PRAGMA user_version=%d", ver);
sqlite3_exec(db, query, NULL, NULL, &err);
sqlite3_exec(db, query, NULL, NULL, NULL);
}
return db;
}
@ -102,6 +101,7 @@ int get_db_settings(sqlite3 *db, int key, struct db_settings *dbs) {
}
if (err) {
LOGE("sqlite3_exec: %s\n", err);
sqlite3_free(err);
return 1;
}
return 0;
@ -141,6 +141,7 @@ int get_db_strings(sqlite3 *db, int key, struct db_strings *str) {
}
if (err) {
LOGE("sqlite3_exec: %s\n", err);
sqlite3_free(err);
return 1;
}
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);
if (err) {
LOGE("sqlite3_exec: %s\n", err);
sqlite3_free(err);
return 1;
}
return 0;

View File

@ -82,11 +82,37 @@ void app_log(struct su_context *ctx) {
"--ei", "pid", pid,
"--ei", "policy", policy,
"--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
};
silent_run(cmd);
}
void app_connect(const char *socket, struct su_info *info) {
char user[8];
setup_user(user, info);

View File

@ -54,6 +54,7 @@ struct su_context {
// connect.c
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 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;
}
if (info->access.notify || info->access.log)
if (info->access.log)
app_log(&ctx);
else if (info->access.notify)
app_notify(&ctx);
if (info->access.policy == ALLOW) {
char* argv[] = { NULL, NULL, NULL, NULL };