mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-29 07:27:38 +00:00
Update denylist config implementation
This commit is contained in:
parent
c0be5383de
commit
706a492218
@ -6,9 +6,9 @@ import android.util.Xml
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.core.content.edit
|
||||
import com.topjohnwu.magisk.BuildConfig
|
||||
import com.topjohnwu.magisk.core.utils.BiometricHelper
|
||||
import com.topjohnwu.magisk.core.utils.refreshLocale
|
||||
import com.topjohnwu.magisk.data.preference.PreferenceModel
|
||||
import com.topjohnwu.magisk.data.repository.DBBoolSettingsNoWrite
|
||||
import com.topjohnwu.magisk.data.repository.DBConfig
|
||||
import com.topjohnwu.magisk.di.ServiceLocator
|
||||
import com.topjohnwu.magisk.ui.theme.Theme
|
||||
@ -38,6 +38,7 @@ object Config : PreferenceModel, DBConfig {
|
||||
const val SU_MNT_NS = "mnt_ns"
|
||||
const val SU_BIOMETRIC = "su_biometric"
|
||||
const val ZYGISK = "zygisk"
|
||||
const val DENYLIST = "denylist"
|
||||
const val SU_MANAGER = "requester"
|
||||
const val KEYSTORE = "keystore"
|
||||
|
||||
@ -145,6 +146,7 @@ object Config : PreferenceModel, DBConfig {
|
||||
var suMultiuserMode by dbSettings(Key.SU_MULTIUSER_MODE, Value.MULTIUSER_MODE_OWNER_ONLY)
|
||||
var suBiometric by dbSettings(Key.SU_BIOMETRIC, false)
|
||||
var zygisk by dbSettings(Key.ZYGISK, false)
|
||||
var denyList by DBBoolSettingsNoWrite(Key.DENYLIST, false)
|
||||
var suManager by dbStrings(Key.SU_MANAGER, "", true)
|
||||
var keyStoreRaw by dbStrings(Key.KEYSTORE, "", true)
|
||||
|
||||
@ -169,12 +171,6 @@ object Config : PreferenceModel, DBConfig {
|
||||
else if (it.toInt() > Value.CANARY_CHANNEL)
|
||||
putString(Key.UPDATE_CHANNEL, Value.CANARY_CHANNEL.toString())
|
||||
}
|
||||
|
||||
// Write database configs
|
||||
putString(Key.ROOT_ACCESS, rootMode.toString())
|
||||
putString(Key.SU_MNT_NS, suMntNamespaceMode.toString())
|
||||
putString(Key.SU_MULTIUSER_MODE, suMultiuserMode.toString())
|
||||
putBoolean(Key.SU_BIOMETRIC, BiometricHelper.isEnabled)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,9 +64,5 @@ object Info {
|
||||
}
|
||||
val isUnsupported = code > 0 && code < Const.Version.MIN_VERCODE
|
||||
val isActive = magiskVersionCode >= 0
|
||||
var denyListEnforced = if (Const.Version.isCanary(code))
|
||||
Shell.su("magisk --denylist status").exec().isSuccess
|
||||
else
|
||||
false
|
||||
}
|
||||
}
|
||||
|
@ -35,14 +35,12 @@ class DBSettingsValue(
|
||||
private val default: Int
|
||||
) : ReadWriteProperty<DBConfig, Int> {
|
||||
|
||||
private var value: Int? = null
|
||||
var value: Int? = null
|
||||
|
||||
@Synchronized
|
||||
override fun getValue(thisRef: DBConfig, property: KProperty<*>): Int {
|
||||
if (value == null)
|
||||
value = runBlocking {
|
||||
thisRef.settingsDB.fetch(name, default)
|
||||
}
|
||||
value = runBlocking { thisRef.settingsDB.fetch(name, default) }
|
||||
return value as Int
|
||||
}
|
||||
|
||||
@ -56,7 +54,7 @@ class DBSettingsValue(
|
||||
}
|
||||
}
|
||||
|
||||
class DBBoolSettings(
|
||||
open class DBBoolSettings(
|
||||
name: String,
|
||||
default: Boolean
|
||||
) : ReadWriteProperty<DBConfig, Boolean> {
|
||||
@ -70,6 +68,17 @@ class DBBoolSettings(
|
||||
base.setValue(thisRef, property, if (value) 1 else 0)
|
||||
}
|
||||
|
||||
class DBBoolSettingsNoWrite(
|
||||
name: String,
|
||||
default: Boolean
|
||||
) : DBBoolSettings(name, default) {
|
||||
override fun setValue(thisRef: DBConfig, property: KProperty<*>, value: Boolean) {
|
||||
synchronized(base) {
|
||||
base.value = if (value) 1 else 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DBStringsValue(
|
||||
private val name: String,
|
||||
private val default: String,
|
||||
|
@ -251,11 +251,11 @@ object DenyList : BaseSettingsItem.Toggle() {
|
||||
if (isEnabled) R.string.settings_denylist_summary.asText()
|
||||
else R.string.settings_denylist_error.asText(R.string.zygisk.asText())
|
||||
|
||||
override var value = Info.env.denyListEnforced
|
||||
override var value = Config.denyList
|
||||
set(value) = setV(value, field, { field = it }) {
|
||||
val cmd = if (it) "enable" else "disable"
|
||||
Shell.su("magisk --denylist $cmd").submit { result ->
|
||||
if (result.isSuccess) Info.env.denyListEnforced = it
|
||||
if (result.isSuccess) Config.denyList = it
|
||||
else field = !it
|
||||
}
|
||||
DenyListConfig.isEnabled = it
|
||||
|
@ -304,10 +304,8 @@ void post_fs_data(int client) {
|
||||
exec_common_scripts("post-fs-data");
|
||||
db_settings dbs;
|
||||
get_db_settings(dbs, ZYGISK_CONFIG);
|
||||
if (dbs[ZYGISK_CONFIG]) {
|
||||
zygisk_enabled = true;
|
||||
check_enforce_denylist();
|
||||
}
|
||||
zygisk_enabled = dbs[ZYGISK_CONFIG];
|
||||
initialize_denylist();
|
||||
handle_modules();
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,15 @@
|
||||
|
||||
extern bool RECOVERY_MODE;
|
||||
extern int DAEMON_STATE;
|
||||
extern bool zygisk_enabled;
|
||||
|
||||
// Daemon state
|
||||
enum : int {
|
||||
STATE_NONE,
|
||||
STATE_POST_FS_DATA,
|
||||
STATE_POST_FS_DATA_DONE,
|
||||
STATE_LATE_START_DONE,
|
||||
STATE_BOOT_COMPLETE
|
||||
};
|
||||
|
||||
void unlock_blocks();
|
||||
void reboot();
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include <utils.hpp>
|
||||
#include <magisk.hpp>
|
||||
#include <daemon.hpp>
|
||||
#include <selinux.hpp>
|
||||
#include <resetprop.hpp>
|
||||
|
||||
|
@ -35,11 +35,10 @@ void denylist_handler(int client, ucred *cred) {
|
||||
int res = DAEMON_ERROR;
|
||||
|
||||
switch (req) {
|
||||
case DISABLE_DENY:
|
||||
case ADD_LIST:
|
||||
case RM_LIST:
|
||||
case LS_LIST:
|
||||
if (!deny_enforced()) {
|
||||
if (!denylist_enabled) {
|
||||
write_int(client, DENY_NOT_ENFORCED);
|
||||
close(client);
|
||||
return;
|
||||
@ -48,7 +47,7 @@ void denylist_handler(int client, ucred *cred) {
|
||||
|
||||
switch (req) {
|
||||
case ENFORCE_DENY:
|
||||
res = enable_hide();
|
||||
res = enable_deny();
|
||||
break;
|
||||
case DISABLE_DENY:
|
||||
res = disable_deny();
|
||||
@ -63,7 +62,7 @@ void denylist_handler(int client, ucred *cred) {
|
||||
ls_list(client);
|
||||
return;
|
||||
case DENY_STATUS:
|
||||
res = deny_enforced() ? DENY_IS_ENFORCED : DENY_NOT_ENFORCED;
|
||||
res = (zygisk_enabled && denylist_enabled) ? DENY_IS_ENFORCED : DENY_NOT_ENFORCED;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -4,26 +4,28 @@
|
||||
#include <string_view>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <atomic>
|
||||
|
||||
#include <daemon.hpp>
|
||||
|
||||
#define ISOLATED_MAGIC "isolated"
|
||||
|
||||
// CLI entries
|
||||
int enable_hide();
|
||||
int enable_deny();
|
||||
int disable_deny();
|
||||
int add_list(int client);
|
||||
int rm_list(int client);
|
||||
void ls_list(int client);
|
||||
|
||||
// Utility functions
|
||||
bool deny_enforced();
|
||||
bool is_deny_target(int uid, std::string_view process);
|
||||
|
||||
// Revert
|
||||
void revert_daemon(int pid, int client);
|
||||
void revert_unmount(int pid = -1);
|
||||
|
||||
extern std::atomic<bool> denylist_enabled;
|
||||
|
||||
enum : int {
|
||||
ENFORCE_DENY,
|
||||
DISABLE_DENY,
|
||||
|
@ -19,7 +19,7 @@ static map<int, vector<string_view>> *uid_proc_map; /* uid -> list of process *
|
||||
// Locks the variables above
|
||||
static pthread_mutex_t data_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static atomic<bool> enforcement_status = false;
|
||||
atomic<bool> denylist_enabled = false;
|
||||
|
||||
static void rebuild_uid_map() {
|
||||
uid_proc_map->clear();
|
||||
@ -147,7 +147,6 @@ static int add_list(const char *pkg, const char *proc) {
|
||||
return DENYLIST_INVALID_PKG;
|
||||
|
||||
{
|
||||
// Critical region
|
||||
mutex_guard lock(data_lock);
|
||||
for (const auto &hide : *deny_set)
|
||||
if (hide.first == pkg && hide.second == proc)
|
||||
@ -172,9 +171,8 @@ int add_list(int client) {
|
||||
}
|
||||
|
||||
static int rm_list(const char *pkg, const char *proc) {
|
||||
bool remove = false;
|
||||
{
|
||||
// Critical region
|
||||
bool remove = false;
|
||||
mutex_guard lock(data_lock);
|
||||
for (auto it = deny_set->begin(); it != deny_set->end();) {
|
||||
if (it->first == pkg && (proc[0] == '\0' || it->second == proc)) {
|
||||
@ -248,63 +246,68 @@ void ls_list(int client) {
|
||||
close(client);
|
||||
}
|
||||
|
||||
static void update_hide_config() {
|
||||
static void update_deny_config() {
|
||||
char sql[64];
|
||||
sprintf(sql, "REPLACE INTO settings (key,value) VALUES('%s',%d)",
|
||||
DB_SETTING_KEYS[DENYLIST_CONFIG], enforcement_status.load());
|
||||
DB_SETTING_KEYS[DENYLIST_CONFIG], denylist_enabled.load());
|
||||
char *err = db_exec(sql);
|
||||
db_err(err);
|
||||
}
|
||||
|
||||
int enable_hide() {
|
||||
if (enforcement_status)
|
||||
return DENY_IS_ENFORCED;
|
||||
int enable_deny() {
|
||||
if (denylist_enabled) {
|
||||
return DAEMON_SUCCESS;
|
||||
} else {
|
||||
mutex_guard lock(data_lock);
|
||||
|
||||
if (access("/proc/self/ns/mnt", F_OK) != 0)
|
||||
return DENY_NO_NS;
|
||||
if (access("/proc/self/ns/mnt", F_OK) != 0) {
|
||||
LOGW("The kernel does not support mount namespace\n");
|
||||
return DENY_NO_NS;
|
||||
}
|
||||
|
||||
if (procfp == nullptr && (procfp = opendir("/proc")) == nullptr)
|
||||
return DAEMON_ERROR;
|
||||
if (procfp == nullptr && (procfp = opendir("/proc")) == nullptr)
|
||||
return DAEMON_ERROR;
|
||||
|
||||
LOGI("* Enforce DenyList\n");
|
||||
LOGI("* Enable DenyList\n");
|
||||
|
||||
mutex_guard lock(data_lock);
|
||||
default_new(deny_set);
|
||||
default_new(uid_proc_map);
|
||||
default_new(deny_set);
|
||||
if (!init_list()) {
|
||||
delete deny_set;
|
||||
deny_set = nullptr;
|
||||
return DAEMON_ERROR;
|
||||
}
|
||||
|
||||
// Initialize the hide list
|
||||
if (!init_list())
|
||||
return DAEMON_ERROR;
|
||||
denylist_enabled = true;
|
||||
|
||||
enforcement_status = true;
|
||||
update_hide_config();
|
||||
default_new(uid_proc_map);
|
||||
rebuild_uid_map();
|
||||
}
|
||||
|
||||
rebuild_uid_map();
|
||||
update_deny_config();
|
||||
return DAEMON_SUCCESS;
|
||||
}
|
||||
|
||||
int disable_deny() {
|
||||
mutex_guard lock(data_lock);
|
||||
|
||||
if (enforcement_status) {
|
||||
if (denylist_enabled) {
|
||||
denylist_enabled = false;
|
||||
LOGI("* Disable DenyList\n");
|
||||
|
||||
mutex_guard lock(data_lock);
|
||||
delete uid_proc_map;
|
||||
delete deny_set;
|
||||
uid_proc_map = nullptr;
|
||||
deny_set = nullptr;
|
||||
}
|
||||
|
||||
enforcement_status = false;
|
||||
update_hide_config();
|
||||
update_deny_config();
|
||||
return DAEMON_SUCCESS;
|
||||
}
|
||||
|
||||
void check_enforce_denylist() {
|
||||
if (!enforcement_status) {
|
||||
void initialize_denylist() {
|
||||
if (!denylist_enabled) {
|
||||
db_settings dbs;
|
||||
get_db_settings(dbs, DENYLIST_CONFIG);
|
||||
if (dbs[DENYLIST_CONFIG])
|
||||
enable_hide();
|
||||
enable_deny();
|
||||
}
|
||||
}
|
||||
|
||||
@ -333,7 +336,3 @@ bool is_deny_target(int uid, string_view process) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool deny_enforced() {
|
||||
return enforcement_status;
|
||||
}
|
||||
|
@ -39,14 +39,7 @@ enum : int {
|
||||
DAEMON_LAST
|
||||
};
|
||||
|
||||
// Daemon state
|
||||
enum : int {
|
||||
STATE_NONE,
|
||||
STATE_POST_FS_DATA,
|
||||
STATE_POST_FS_DATA_DONE,
|
||||
STATE_LATE_START_DONE,
|
||||
STATE_BOOT_COMPLETE
|
||||
};
|
||||
extern bool zygisk_enabled;
|
||||
|
||||
int connect_daemon(bool create = false);
|
||||
|
||||
@ -63,6 +56,6 @@ void su_daemon_handler(int client, ucred *credential);
|
||||
void zygisk_handler(int client, ucred *cred);
|
||||
|
||||
// Denylist
|
||||
void check_enforce_denylist();
|
||||
void initialize_denylist();
|
||||
int disable_deny();
|
||||
int denylist_cli(int argc, char **argv);
|
||||
|
@ -26,7 +26,7 @@ int fd_pathat(int dirfd, const char *name, char *path, size_t size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mkdirs(string_view path, mode_t mode) {
|
||||
int mkdirs(string path, mode_t mode) {
|
||||
errno = 0;
|
||||
for (char *p = path.data() + 1; *p; ++p) {
|
||||
if (*p == '/') {
|
||||
|
@ -32,7 +32,7 @@ struct raw_file {
|
||||
|
||||
ssize_t fd_path(int fd, char *path, size_t size);
|
||||
int fd_pathat(int dirfd, const char *name, char *path, size_t size);
|
||||
int mkdirs(std::string_view path, mode_t mode);
|
||||
int mkdirs(std::string path, mode_t mode);
|
||||
void rm_rf(const char *path);
|
||||
void mv_path(const char *src, const char *dest);
|
||||
void mv_dir(int src, int dest);
|
||||
|
@ -255,7 +255,7 @@ static void setup_files(int client, ucred *cred) {
|
||||
}
|
||||
|
||||
static void check_denylist(int client) {
|
||||
if (!deny_enforced()) {
|
||||
if (!denylist_enabled) {
|
||||
write_int(client, DENY_NOT_ENFORCED);
|
||||
return;
|
||||
}
|
||||
@ -266,7 +266,7 @@ static void check_denylist(int client) {
|
||||
}
|
||||
|
||||
static void do_unmount(int client, ucred *cred) {
|
||||
if (deny_enforced()) {
|
||||
if (denylist_enabled) {
|
||||
LOGD("zygisk: cleanup mount namespace for pid=[%d]\n", cred->pid);
|
||||
revert_daemon(cred->pid, client);
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user