mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-24 04:29:45 +00:00
sulog: add more info
This commit is contained in:
parent
a5acf33ccd
commit
c6efb51f61
@ -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
|
||||
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
@ -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) }
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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-->
|
||||
|
||||
|
@ -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,8 +120,10 @@ 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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user