mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-25 01:07:55 +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
|
||||
|
||||
#define get_user(info) \
|
||||
((info)->cfg[SU_MULTIUSER_MODE] == MULTIUSER_MODE_USER \
|
||||
? to_user_id((info)->uid) : 0)
|
||||
|
||||
#define get_cmd(to) \
|
||||
((to).command.empty() ? \
|
||||
((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 target[128];
|
||||
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 defined(__LP64__)
|
||||
@ -206,7 +202,7 @@ int app_request(const shared_ptr<su_info> &info) {
|
||||
vector<Extra> extras;
|
||||
extras.reserve(2);
|
||||
extras.emplace_back("fifo", fifo);
|
||||
extras.emplace_back("uid", info->uid);
|
||||
extras.emplace_back("uid", info->eval_uid);
|
||||
exec_cmd("request", extras, info, false);
|
||||
|
||||
// Wait for data input for at most 70 seconds
|
||||
|
@ -15,26 +15,29 @@
|
||||
|
||||
class su_info {
|
||||
public:
|
||||
/* Unique key */
|
||||
// Unique key
|
||||
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;
|
||||
su_access access;
|
||||
std::string mgr_pkg;
|
||||
struct stat mgr_st;
|
||||
void check_db();
|
||||
|
||||
/* This should be guarded with global cache lock */
|
||||
long timestamp;
|
||||
|
||||
su_info(unsigned uid = 0);
|
||||
~su_info();
|
||||
mutex_guard lock();
|
||||
// These should be guarded with global cache lock
|
||||
bool is_fresh();
|
||||
void refresh();
|
||||
|
||||
su_info(int uid);
|
||||
~su_info();
|
||||
mutex_guard lock();
|
||||
|
||||
private:
|
||||
pthread_mutex_t _lock; /* Internal lock */
|
||||
long timestamp;
|
||||
// Internal lock
|
||||
pthread_mutex_t _lock;
|
||||
};
|
||||
|
||||
struct su_req_base {
|
||||
|
@ -19,9 +19,9 @@ using namespace std;
|
||||
static pthread_mutex_t cache_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static shared_ptr<su_info> cached;
|
||||
|
||||
su_info::su_info(unsigned uid) :
|
||||
uid(uid), access(DEFAULT_SU_ACCESS), mgr_st({}),
|
||||
timestamp(0), _lock(PTHREAD_MUTEX_INITIALIZER) {}
|
||||
su_info::su_info(int uid) :
|
||||
uid(uid), eval_uid(-1), access(DEFAULT_SU_ACCESS), mgr_st{},
|
||||
timestamp(0), _lock(PTHREAD_MUTEX_INITIALIZER) {}
|
||||
|
||||
su_info::~su_info() {
|
||||
pthread_mutex_destroy(&_lock);
|
||||
@ -44,47 +44,45 @@ void su_info::refresh() {
|
||||
timestamp = ts.tv_sec * 1000L + ts.tv_nsec / 1000000L;
|
||||
}
|
||||
|
||||
static void database_check(const shared_ptr<su_info> &info) {
|
||||
int uid = info->uid;
|
||||
get_db_settings(info->cfg);
|
||||
void su_info::check_db() {
|
||||
eval_uid = uid;
|
||||
get_db_settings(cfg);
|
||||
|
||||
// Check multiuser settings
|
||||
switch (info->cfg[SU_MULTIUSER_MODE]) {
|
||||
case MULTIUSER_MODE_OWNER_ONLY:
|
||||
if (to_user_id(uid) != 0) {
|
||||
uid = -1;
|
||||
info->access = NO_SU_ACCESS;
|
||||
}
|
||||
break;
|
||||
case MULTIUSER_MODE_OWNER_MANAGED:
|
||||
uid = to_app_id(uid);
|
||||
break;
|
||||
case MULTIUSER_MODE_USER:
|
||||
default:
|
||||
break;
|
||||
switch (cfg[SU_MULTIUSER_MODE]) {
|
||||
case MULTIUSER_MODE_OWNER_ONLY:
|
||||
if (to_user_id(uid) != 0) {
|
||||
eval_uid = -1;
|
||||
access = NO_SU_ACCESS;
|
||||
}
|
||||
break;
|
||||
case MULTIUSER_MODE_OWNER_MANAGED:
|
||||
eval_uid = to_app_id(uid);
|
||||
break;
|
||||
case MULTIUSER_MODE_USER:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
su_access &su = info->access;
|
||||
|
||||
if (uid > 0) {
|
||||
if (eval_uid > 0) {
|
||||
char query[256], *err;
|
||||
sprintf(query,
|
||||
snprintf(query, sizeof(query),
|
||||
"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 {
|
||||
su.policy = (policy_t) parse_int(row["policy"]);
|
||||
su.log = parse_int(row["logging"]);
|
||||
su.notify = parse_int(row["notification"]);
|
||||
access.policy = (policy_t) parse_int(row["policy"]);
|
||||
access.log = parse_int(row["logging"]);
|
||||
access.notify = parse_int(row["notification"]);
|
||||
LOGD("magiskdb: query policy=[%d] log=[%d] notify=[%d]\n",
|
||||
su.policy, su.log, su.notify);
|
||||
access.policy, access.log, access.notify);
|
||||
return true;
|
||||
});
|
||||
db_err_cmd(err, return);
|
||||
}
|
||||
|
||||
// We need to check our manager
|
||||
if (su.log || su.notify)
|
||||
get_manager(to_user_id(uid), &info->mgr_pkg, &info->mgr_st);
|
||||
if (access.log || access.notify)
|
||||
get_manager(to_user_id(eval_uid), &mgr_pkg, &mgr_st);
|
||||
}
|
||||
|
||||
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) {
|
||||
// Not cached, get data from database
|
||||
database_check(info);
|
||||
info->check_db();
|
||||
|
||||
// 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)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user