Skip to content

Commit

Permalink
Use SQLite's internal time function
Browse files Browse the repository at this point in the history
  • Loading branch information
topjohnwu committed Jan 5, 2025
1 parent b782e7d commit 0d31d35
Show file tree
Hide file tree
Showing 10 changed files with 62 additions and 48 deletions.
2 changes: 1 addition & 1 deletion app/core/src/main/java/com/topjohnwu/magisk/core/Config.kt
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ object Config : PreferenceConfig, DBConfig {
const val SU_AUTO_ALLOW = 2

// su timeout
val TIMEOUT_LIST = intArrayOf(0, -1, 10, 20, 30, 60)
val TIMEOUT_LIST = longArrayOf(0, -1, 10, 20, 30, 60)
}

private val defaultChannel =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@ import kotlinx.coroutines.withContext

open class MagiskDB {

suspend fun <R> exec(
class Literal(
val str: String
)

suspend inline fun <R> exec(
query: String,
mapper: suspend (Map<String, String>) -> R
crossinline mapper: (Map<String, String>) -> R
): List<R> {
return withContext(Dispatchers.IO) {
val out = Shell.cmd("magisk --sqlite '$query'").await().out
Expand All @@ -18,13 +22,15 @@ open class MagiskDB {
.map { it.split("=", limit = 2) }
.filter { it.size == 2 }
.associate { it[0] to it[1] }
.let { mapper(it) }
.let(mapper)
}
}
}

suspend inline fun exec(query: String) {
exec(query) {}
suspend fun exec(query: String) {
withContext(Dispatchers.IO) {
Shell.cmd("magisk --sqlite '$query'").await()
}
}

fun Map<String, Any>.toQuery(): String {
Expand All @@ -33,6 +39,7 @@ open class MagiskDB {
when (it) {
is Boolean -> if (it) "1" else "0"
is Number -> it.toString()
is Literal -> it.str
else -> "\"$it\""
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,24 @@ package com.topjohnwu.magisk.core.data.magiskdb
import com.topjohnwu.magisk.core.AppContext
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.model.su.SuPolicy
import java.util.concurrent.TimeUnit

private const val SELECT_QUERY = "SELECT (until - strftime(\"%s\", \"now\")) AS remain, *"

class PolicyDao : MagiskDB() {

suspend fun deleteOutdated() {
val nowSeconds = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())
val query = "DELETE FROM ${Table.POLICY} WHERE " +
"(until > 0 AND until < $nowSeconds) OR until < 0"
"(until > 0 AND until < strftime(\"%s\", \"now\")) OR until < 0"
exec(query)
}

suspend fun delete(uid: Int) {
val query = "DELETE FROM ${Table.POLICY} WHERE uid == $uid"
val query = "DELETE FROM ${Table.POLICY} WHERE uid=$uid"
exec(query)
}

suspend fun fetch(uid: Int): SuPolicy? {
val query = "SELECT * FROM ${Table.POLICY} WHERE uid == $uid LIMIT 1"
val query = "$SELECT_QUERY FROM ${Table.POLICY} WHERE uid=$uid LIMIT 1"
return exec(query, ::toPolicy).firstOrNull()
}

Expand All @@ -35,16 +35,23 @@ class PolicyDao : MagiskDB() {
}

suspend fun fetchAll(): List<SuPolicy> {
val query = "SELECT * FROM ${Table.POLICY} WHERE uid/100000 == ${Const.USER_ID}"
val query = "$SELECT_QUERY FROM ${Table.POLICY} WHERE uid/100000=${Const.USER_ID}"
return exec(query, ::toPolicy).filterNotNull()
}

private fun toPolicy(map: Map<String, String>): SuPolicy? {
val uid = map["uid"]?.toInt() ?: return null
val policy = SuPolicy(uid)

map["until"]?.toLong()?.let { until ->
if (until <= 0) {
policy.remain = until
} else {
map["remain"]?.toLong()?.let { policy.remain = it }
}
}

map["policy"]?.toInt()?.let { policy.policy = it }
map["until"]?.toLong()?.let { policy.until = it }
map["logging"]?.toInt()?.let { policy.logging = it != 0 }
map["notification"]?.toInt()?.let { policy.notification = it != 0 }
return policy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.topjohnwu.magisk.core.data.magiskdb
class SettingsDao : MagiskDB() {

suspend fun delete(key: String) {
val query = "DELETE FROM ${Table.SETTINGS} WHERE key == \"$key\""
val query = "DELETE FROM ${Table.SETTINGS} WHERE key=\"$key\""
exec(query)
}

Expand All @@ -14,7 +14,7 @@ class SettingsDao : MagiskDB() {
}

suspend fun fetch(key: String, default: Int = -1): Int {
val query = "SELECT value FROM ${Table.SETTINGS} WHERE key == \"$key\" LIMIT 1"
val query = "SELECT value FROM ${Table.SETTINGS} WHERE key=\"$key\" LIMIT 1"
return exec(query) { it["value"]?.toInt() }.firstOrNull() ?: default
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.topjohnwu.magisk.core.data.magiskdb
class StringDao : MagiskDB() {

suspend fun delete(key: String) {
val query = "DELETE FROM ${Table.STRINGS} WHERE key == \"$key\""
val query = "DELETE FROM ${Table.STRINGS} WHERE key=\"$key\""
exec(query)
}

Expand All @@ -14,7 +14,7 @@ class StringDao : MagiskDB() {
}

suspend fun fetch(key: String, default: String = ""): String {
val query = "SELECT value FROM ${Table.STRINGS} WHERE key == \"$key\" LIMIT 1"
val query = "SELECT value FROM ${Table.STRINGS} WHERE key=\"$key\" LIMIT 1"
return exec(query) { it["value"] }.firstOrNull() ?: default
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.topjohnwu.magisk.core.model.su

import com.topjohnwu.magisk.core.data.magiskdb.MagiskDB

class SuPolicy(
val uid: Int,
var policy: Int = INTERACTIVE,
var until: Long = -1L,
var remain: Long = -1L,
var logging: Boolean = true,
var notification: Boolean = true,
) {
Expand All @@ -13,11 +15,18 @@ class SuPolicy(
const val ALLOW = 2
}

fun toMap(): MutableMap<String, Any> = mutableMapOf(
"uid" to uid,
"policy" to policy,
"until" to until,
"logging" to logging,
"notification" to notification
)
fun toMap(): MutableMap<String, Any> {
val until = if (remain <= 0) {
remain
} else {
MagiskDB.Literal("(strftime(\"%s\", \"now\") + $remain)")
}
return mutableMapOf(
"uid" to uid,
"policy" to policy,
"until" to until,
"logging" to logging,
"notification" to notification
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,13 @@ class SuRequestHandler(
return true
}

suspend fun respond(action: Int, time: Int) {
val until = if (time > 0)
TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()) +
TimeUnit.MINUTES.toSeconds(time.toLong())
else
time.toLong()

suspend fun respond(action: Int, time: Long) {
policy.policy = action
policy.until = until
if (time >= 0) {
policy.remain = TimeUnit.MINUTES.toSeconds(time)
} else {
policy.remain = time
}

withContext(Dispatchers.IO) {
try {
Expand All @@ -100,7 +98,7 @@ class SuRequestHandler(
} catch (e: IOException) {
Timber.e(e)
}
if (until >= 0) {
if (time >= 0) {
policyDB.update(policy)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class MagiskAppTest : BaseTest {
uid = 2000,
logging = false,
notification = false,
until = 0L
remain = 0L
)
runBlocking {
ServiceLocator.policyDB.update(policy)
Expand Down
10 changes: 3 additions & 7 deletions native/src/core/su/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ use crate::daemon::MagiskD;
use crate::db::DbArg::Integer;
use crate::db::{SqlTable, SqliteResult, SqliteReturn};
use crate::ffi::{DbValues, RootSettings, SuPolicy};
use base::{libc, ResultExt};
use std::ptr;
use base::ResultExt;

impl Default for SuPolicy {
fn default() -> Self {
Expand Down Expand Up @@ -40,11 +39,8 @@ impl MagiskD {
fn get_root_settings(&self, uid: i32, settings: &mut RootSettings) -> SqliteResult {
self.db_exec_with_rows(
"SELECT policy, logging, notification FROM policies \
WHERE uid=? AND (until=0 OR until>?)",
&[
Integer(uid as i64),
Integer(unsafe { libc::time(ptr::null_mut()).into() }),
],
WHERE uid=? AND (until=0 OR until>strftime('%s', 'now'))",
&[Integer(uid as i64)],
settings,
)
.sql_result()
Expand Down
9 changes: 3 additions & 6 deletions native/src/core/su/su_daemon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,8 @@ bool uid_granted_root(int uid) {
}

bool granted = false;
db_exec("SELECT policy FROM policies WHERE uid=? AND (until=0 OR until>?)",
{ uid, time(nullptr) },
[&](auto, const DbValues &values) { granted = values.get_int(0) == +SuPolicy::Allow; });
db_exec("SELECT policy FROM policies WHERE uid=? AND (until=0 OR until>strftime('%s', 'now'))",
{ uid }, [&](auto, const DbValues &v) { granted = v.get_int(0) == +SuPolicy::Allow; });
return granted;
}

Expand Down Expand Up @@ -141,9 +140,7 @@ void prune_su_access() {
}
}
for (int uid : rm_uids) {
char query[256];
ssprintf(query, sizeof(query), "DELETE FROM policies WHERE uid == %d", uid);
db_exec(query);
db_exec("DELETE FROM policies WHERE uid=?", { uid });
}
}

Expand Down

0 comments on commit 0d31d35

Please sign in to comment.