sulog: add more info

This commit is contained in:
vvb2060 2023-06-20 01:52:58 +08:00 committed by John Wu
parent a5acf33ccd
commit c6efb51f61
7 changed files with 92 additions and 49 deletions

View File

@ -6,7 +6,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.util.*
@Database(version = 1, entities = [SuLog::class], exportSchema = false)
@Database(version = 2, entities = [SuLog::class], exportSchema = false)
abstract class SuLogDatabase : RoomDatabase() {
abstract fun suLogDao(): SuLogDao

View File

@ -14,7 +14,10 @@ class SuLog(
val packageName: String,
val appName: String,
val command: String,
val action: Boolean,
val action: Int,
val target: Int,
val context: String,
val gids: String,
val time: Long = System.currentTimeMillis()
) {
@PrimaryKey(autoGenerate = true) var id: Int = 0
@ -25,7 +28,10 @@ fun PackageManager.createSuLog(
toUid: Int,
fromPid: Int,
command: String,
policy: Int
policy: Int,
target: Int,
context: String,
gids: String,
): SuLog {
val appInfo = info.applicationInfo
return SuLog(
@ -35,7 +41,10 @@ fun PackageManager.createSuLog(
packageName = getNameForUid(appInfo.uid)!!,
appName = appInfo.getLabel(this),
command = command,
action = policy == SuPolicy.ALLOW
action = policy,
target = target,
context = context,
gids = gids,
)
}
@ -44,7 +53,10 @@ fun createSuLog(
toUid: Int,
fromPid: Int,
command: String,
policy: Int
policy: Int,
target: Int,
context: String,
gids: String,
): SuLog {
return SuLog(
fromUid = fromUid,
@ -53,6 +65,9 @@ fun createSuLog(
packageName = "[UID] $fromUid",
appName = "[UID] $fromUid",
command = command,
action = policy == SuPolicy.ALLOW
action = policy,
target = target,
context = context,
gids = gids,
)
}

View File

@ -57,17 +57,20 @@ object SuCallbackHandler {
val toUid = data.getIntComp("to.uid", -1)
val pid = data.getIntComp("pid", -1)
val command = data.getString("command", "")
val target = data.getIntComp("target", -1)
val seContext = data.getString("context", "")
val gids = data.getString("gids", "")
val pm = context.packageManager
val log = runCatching {
pm.getPackageInfo(fromUid, pid)?.let {
pm.createSuLog(it, toUid, pid, command, policy)
pm.createSuLog(it, toUid, pid, command, policy, target, seContext, gids)
}
}.getOrNull() ?: createSuLog(fromUid, toUid, pid, command, policy)
}.getOrNull() ?: createSuLog(fromUid, toUid, pid, command, policy, target, seContext, gids)
if (notify)
notify(context, log.action, log.appName)
notify(context, log.action == SuPolicy.ALLOW, log.appName)
runBlocking { ServiceLocator.logRepo.insert(log) }
}

View File

@ -3,6 +3,7 @@ package com.topjohnwu.magisk.ui.log
import androidx.databinding.Bindable
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.di.AppContext
import com.topjohnwu.magisk.core.ktx.timeDateFormat
import com.topjohnwu.magisk.core.ktx.toTime
import com.topjohnwu.magisk.core.model.su.SuLog
@ -14,7 +15,7 @@ class SuLogRvItem(val log: SuLog) : ObservableRvItem(), DiffItem<SuLogRvItem> {
override val layoutRes = R.layout.item_log_access_md2
val date = log.time.toTime(timeDateFormat)
val info = genInfo()
@get:Bindable
var isTop = false
@ -25,4 +26,28 @@ class SuLogRvItem(val log: SuLog) : ObservableRvItem(), DiffItem<SuLogRvItem> {
set(value) = set(value, field, { field = it }, BR.bottom)
override fun itemSameAs(other: SuLogRvItem) = log.appName == other.log.appName
private fun genInfo(): String {
val res = AppContext.resources
val sb = StringBuilder()
val date = log.time.toTime(timeDateFormat)
val toUid = res.getString(R.string.target_uid, log.toUid)
val fromPid = res.getString(R.string.pid, log.fromPid)
sb.append("$date\n$toUid $fromPid")
if (log.target != -1) {
val pid = if (log.target == 0) "magiskd" else log.target.toString()
val target = res.getString(R.string.target_pid, pid)
sb.append(" $target")
}
if (log.context.isNotEmpty()) {
val context = res.getString(R.string.selinux_context, log.context)
sb.append("\n$context")
}
if (log.gids.isNotEmpty()) {
val gids = res.getString(R.string.supp_group, log.gids)
sb.append("\n$gids")
}
sb.append("\n${log.command}")
return sb.toString()
}
}

View File

@ -25,9 +25,9 @@
<include
android:id="@+id/log_track_container"
bullet="@{item.log.action ? R.drawable.ic_check_md2 : R.drawable.ic_close_md2}"
bullet="@{item.log.action == 2 ? R.drawable.ic_check_md2 : R.drawable.ic_close_md2}"
isBottom="@{item.isBottom}"
isSelected="@{!item.log.action}"
isSelected="@{item.log.action != 2}"
isTop="@{item.isTop}"
layout="@layout/item_log_track_md2"
android:layout_width="wrap_content"
@ -54,48 +54,22 @@
android:text="@{item.log.appName}"
android:textAppearance="@style/AppearanceFoundation.Body"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@+id/log_date"
app:layout_constraintBottom_toTopOf="@+id/log_info"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="@string/magisk" />
<TextView
android:id="@+id/log_date"
android:id="@+id/log_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{item.date}"
android:text="@{item.info}"
android:textAppearance="@style/AppearanceFoundation.Caption.Variant"
app:layout_constraintBottom_toTopOf="@+id/log_app_details"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@+id/log_app_name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:text="06:00 PM, 10 Oct 2019" />
<TextView
android:id="@+id/log_app_details"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@{String.format(`%s %s`, @string/pid(item.log.fromPid), @string/target_uid(item.log.toUid))}"
android:textAppearance="@style/AppearanceFoundation.Caption.Variant"
app:layout_constraintBottom_toTopOf="@id/log_command"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/log_date"
tools:text="PID: 7196 Target UID: 0" />
<TextView
android:id="@+id/log_command"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:fontFamily="monospace"
android:text="@{item.log.command}"
android:textAppearance="@style/AppearanceFoundation.Caption.Variant"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/log_app_details"
app:layout_constraintBottom_toBottomOf="parent"
tools:text="/system/bin/sh" />
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -88,6 +88,9 @@
<string name="logs_cleared">Log successfully cleared</string>
<string name="pid">PID: %1$d</string>
<string name="target_uid">Target UID: %1$d</string>
<string name="target_pid">Mount ns target PID: %s</string>
<string name="selinux_context">SELinux context: %s</string>
<string name="supp_group">Supplementary group: %s</string>
<!--SafetyNet-->

View File

@ -32,27 +32,28 @@ class Extra {
enum {
INT,
BOOL,
STRING
STRING,
INTLIST,
} type;
union {
int int_val;
bool bool_val;
const char *str_val;
const vector<uint32_t> *intlist_val;
};
string str;
public:
Extra(const char *k, int v): key(k), type(INT), int_val(v) {}
Extra(const char *k, bool v): key(k), type(BOOL), bool_val(v) {}
Extra(const char *k, const char *v): key(k), type(STRING), str_val(v) {}
Extra(const char *k, const vector<uint32_t> *v): key(k), type(INTLIST), intlist_val(v) {}
void add_intent(vector<const char *> &vec) {
char buf[32];
const char *val;
switch (type) {
case INT:
vec.push_back("--ei");
ssprintf(buf, sizeof(buf), "%d", int_val);
str = buf;
str = to_string(int_val);
val = str.data();
break;
case BOOL:
@ -63,6 +64,15 @@ public:
vec.push_back("--es");
val = str_val;
break;
case INTLIST:
vec.push_back("--es");
for (auto i : *intlist_val) {
str += to_string(i);
str += ",";
}
if (!str.empty()) str.pop_back();
val = str.data();
break;
}
vec.push_back(key);
vec.push_back(val);
@ -92,6 +102,14 @@ public:
str += str_val;
}
break;
case INTLIST:
str += ":s:";
for (auto i : *intlist_val) {
str += to_string(i);
str += ",";
}
if (str.back() == ',') str.pop_back();
break;
}
vec.push_back("--extra");
vec.push_back(str.data());
@ -102,9 +120,11 @@ static bool check_no_error(int fd) {
char buf[1024];
auto out = xopen_file(fd, "r");
while (fgets(buf, sizeof(buf), out.get())) {
if (strncmp(buf, "Error", 5) == 0)
if (strncasecmp(buf, "Error", 5) == 0) {
LOGD("exec_cmd: %s\n", buf);
return false;
}
}
return true;
}
@ -163,11 +183,14 @@ static void exec_cmd(const char *action, vector<Extra> &data,
void app_log(const su_context &ctx) {
if (fork_dont_care() == 0) {
vector<Extra> extras;
extras.reserve(6);
extras.reserve(9);
extras.emplace_back("from.uid", ctx.info->uid);
extras.emplace_back("to.uid", static_cast<int>(ctx.req.uid));
extras.emplace_back("pid", ctx.pid);
extras.emplace_back("policy", ctx.info->access.policy);
extras.emplace_back("target", ctx.req.target);
extras.emplace_back("context", ctx.req.context.data());
extras.emplace_back("gids", &ctx.req.gids);
extras.emplace_back("command", get_cmd(ctx.req));
extras.emplace_back("notify", (bool) ctx.info->access.notify);