mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-25 00:47:38 +00:00
Fix MULTIUSER_MODE_OWNER_MANAGED
This commit is contained in:
parent
3eb1a7e384
commit
a7392ed3d7
@ -20,10 +20,6 @@ exe, "/system/bin", "com.android.commands.am.Am", \
|
|||||||
|
|
||||||
// 0x18000020 = FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_MULTIPLE_TASK|FLAG_INCLUDE_STOPPED_PACKAGES
|
// 0x18000020 = FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_MULTIPLE_TASK|FLAG_INCLUDE_STOPPED_PACKAGES
|
||||||
|
|
||||||
#define get_user(info) \
|
|
||||||
((info)->cfg[SU_MULTIUSER_MODE] == MULTIUSER_MODE_USER \
|
|
||||||
? to_user_id((info)->uid) : 0)
|
|
||||||
|
|
||||||
#define get_cmd(to) \
|
#define get_cmd(to) \
|
||||||
((to).command.empty() ? \
|
((to).command.empty() ? \
|
||||||
((to).shell.empty() ? DEFAULT_SHELL : (to).shell.data()) : \
|
((to).shell.empty() ? DEFAULT_SHELL : (to).shell.data()) : \
|
||||||
@ -108,7 +104,7 @@ static void exec_cmd(const char *action, vector<Extra> &data,
|
|||||||
char exe[128];
|
char exe[128];
|
||||||
char target[128];
|
char target[128];
|
||||||
char user[4];
|
char user[4];
|
||||||
snprintf(user, sizeof(user), "%d", get_user(info));
|
snprintf(user, sizeof(user), "%d", to_user_id(info->eval_uid));
|
||||||
|
|
||||||
if (zygisk_enabled) {
|
if (zygisk_enabled) {
|
||||||
#if defined(__LP64__)
|
#if defined(__LP64__)
|
||||||
@ -206,7 +202,7 @@ int app_request(const shared_ptr<su_info> &info) {
|
|||||||
vector<Extra> extras;
|
vector<Extra> extras;
|
||||||
extras.reserve(2);
|
extras.reserve(2);
|
||||||
extras.emplace_back("fifo", fifo);
|
extras.emplace_back("fifo", fifo);
|
||||||
extras.emplace_back("uid", info->uid);
|
extras.emplace_back("uid", info->eval_uid);
|
||||||
exec_cmd("request", extras, info, false);
|
exec_cmd("request", extras, info, false);
|
||||||
|
|
||||||
// Wait for data input for at most 70 seconds
|
// Wait for data input for at most 70 seconds
|
||||||
|
@ -15,26 +15,29 @@
|
|||||||
|
|
||||||
class su_info {
|
class su_info {
|
||||||
public:
|
public:
|
||||||
/* Unique key */
|
// Unique key
|
||||||
const int uid;
|
const int uid;
|
||||||
|
|
||||||
/* These should be guarded with internal lock */
|
// These should be guarded with internal lock
|
||||||
|
int eval_uid; // The effective UID, taking multiuser settings into consideration
|
||||||
db_settings cfg;
|
db_settings cfg;
|
||||||
su_access access;
|
su_access access;
|
||||||
std::string mgr_pkg;
|
std::string mgr_pkg;
|
||||||
struct stat mgr_st;
|
struct stat mgr_st;
|
||||||
|
void check_db();
|
||||||
|
|
||||||
/* This should be guarded with global cache lock */
|
// These should be guarded with global cache lock
|
||||||
long timestamp;
|
|
||||||
|
|
||||||
su_info(unsigned uid = 0);
|
|
||||||
~su_info();
|
|
||||||
mutex_guard lock();
|
|
||||||
bool is_fresh();
|
bool is_fresh();
|
||||||
void refresh();
|
void refresh();
|
||||||
|
|
||||||
|
su_info(int uid);
|
||||||
|
~su_info();
|
||||||
|
mutex_guard lock();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
pthread_mutex_t _lock; /* Internal lock */
|
long timestamp;
|
||||||
|
// Internal lock
|
||||||
|
pthread_mutex_t _lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct su_req_base {
|
struct su_req_base {
|
||||||
|
@ -19,9 +19,9 @@ using namespace std;
|
|||||||
static pthread_mutex_t cache_lock = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t cache_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
static shared_ptr<su_info> cached;
|
static shared_ptr<su_info> cached;
|
||||||
|
|
||||||
su_info::su_info(unsigned uid) :
|
su_info::su_info(int uid) :
|
||||||
uid(uid), access(DEFAULT_SU_ACCESS), mgr_st({}),
|
uid(uid), eval_uid(-1), access(DEFAULT_SU_ACCESS), mgr_st{},
|
||||||
timestamp(0), _lock(PTHREAD_MUTEX_INITIALIZER) {}
|
timestamp(0), _lock(PTHREAD_MUTEX_INITIALIZER) {}
|
||||||
|
|
||||||
su_info::~su_info() {
|
su_info::~su_info() {
|
||||||
pthread_mutex_destroy(&_lock);
|
pthread_mutex_destroy(&_lock);
|
||||||
@ -44,47 +44,45 @@ void su_info::refresh() {
|
|||||||
timestamp = ts.tv_sec * 1000L + ts.tv_nsec / 1000000L;
|
timestamp = ts.tv_sec * 1000L + ts.tv_nsec / 1000000L;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void database_check(const shared_ptr<su_info> &info) {
|
void su_info::check_db() {
|
||||||
int uid = info->uid;
|
eval_uid = uid;
|
||||||
get_db_settings(info->cfg);
|
get_db_settings(cfg);
|
||||||
|
|
||||||
// Check multiuser settings
|
// Check multiuser settings
|
||||||
switch (info->cfg[SU_MULTIUSER_MODE]) {
|
switch (cfg[SU_MULTIUSER_MODE]) {
|
||||||
case MULTIUSER_MODE_OWNER_ONLY:
|
case MULTIUSER_MODE_OWNER_ONLY:
|
||||||
if (to_user_id(uid) != 0) {
|
if (to_user_id(uid) != 0) {
|
||||||
uid = -1;
|
eval_uid = -1;
|
||||||
info->access = NO_SU_ACCESS;
|
access = NO_SU_ACCESS;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MULTIUSER_MODE_OWNER_MANAGED:
|
case MULTIUSER_MODE_OWNER_MANAGED:
|
||||||
uid = to_app_id(uid);
|
eval_uid = to_app_id(uid);
|
||||||
break;
|
break;
|
||||||
case MULTIUSER_MODE_USER:
|
case MULTIUSER_MODE_USER:
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
su_access &su = info->access;
|
if (eval_uid > 0) {
|
||||||
|
|
||||||
if (uid > 0) {
|
|
||||||
char query[256], *err;
|
char query[256], *err;
|
||||||
sprintf(query,
|
snprintf(query, sizeof(query),
|
||||||
"SELECT policy, logging, notification FROM policies "
|
"SELECT policy, logging, notification FROM policies "
|
||||||
"WHERE uid=%d AND (until=0 OR until>%li)", uid, time(nullptr));
|
"WHERE uid=%d AND (until=0 OR until>%li)", eval_uid, time(nullptr));
|
||||||
err = db_exec(query, [&](db_row &row) -> bool {
|
err = db_exec(query, [&](db_row &row) -> bool {
|
||||||
su.policy = (policy_t) parse_int(row["policy"]);
|
access.policy = (policy_t) parse_int(row["policy"]);
|
||||||
su.log = parse_int(row["logging"]);
|
access.log = parse_int(row["logging"]);
|
||||||
su.notify = parse_int(row["notification"]);
|
access.notify = parse_int(row["notification"]);
|
||||||
LOGD("magiskdb: query policy=[%d] log=[%d] notify=[%d]\n",
|
LOGD("magiskdb: query policy=[%d] log=[%d] notify=[%d]\n",
|
||||||
su.policy, su.log, su.notify);
|
access.policy, access.log, access.notify);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
db_err_cmd(err, return);
|
db_err_cmd(err, return);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to check our manager
|
// We need to check our manager
|
||||||
if (su.log || su.notify)
|
if (access.log || access.notify)
|
||||||
get_manager(to_user_id(uid), &info->mgr_pkg, &info->mgr_st);
|
get_manager(to_user_id(eval_uid), &mgr_pkg, &mgr_st);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool uid_granted_root(int uid) {
|
bool uid_granted_root(int uid) {
|
||||||
@ -156,7 +154,7 @@ static shared_ptr<su_info> get_su_info(unsigned uid) {
|
|||||||
|
|
||||||
if (info->access.policy == QUERY) {
|
if (info->access.policy == QUERY) {
|
||||||
// Not cached, get data from database
|
// Not cached, get data from database
|
||||||
database_check(info);
|
info->check_db();
|
||||||
|
|
||||||
// If it's root or the manager, allow it silently
|
// If it's root or the manager, allow it silently
|
||||||
if (info->uid == UID_ROOT || to_app_id(info->uid) == to_app_id(info->mgr_st.st_uid)) {
|
if (info->uid == UID_ROOT || to_app_id(info->uid) == to_app_id(info->mgr_st.st_uid)) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user