Support changing requester in DB
This commit is contained in:
parent
6b7b71b1f8
commit
84ca8e1f3e
88
activity.c
88
activity.c
@ -18,9 +18,8 @@
|
||||
#include "su.h"
|
||||
|
||||
/* intent actions */
|
||||
#define ACTION_REQUEST "start", "-n", REQUESTOR "/" REQUESTOR_PREFIX ".RequestActivity"
|
||||
#define ACTION_NOTIFY "start", "-n", REQUESTOR "/" REQUESTOR_PREFIX ".NotifyActivity"
|
||||
#define ACTION_RESULT "broadcast", "-n", REQUESTOR "/" REQUESTOR_PREFIX ".SuReceiver"
|
||||
#define ACTION_REQUEST "%s/" REQUESTOR_PREFIX ".RequestActivity"
|
||||
#define ACTION_RESULT "%s/" REQUESTOR_PREFIX ".SuReceiver"
|
||||
|
||||
#define AM_PATH "/system/bin/app_process", "/system/bin", "com.android.commands.am.Am"
|
||||
|
||||
@ -73,30 +72,20 @@ void app_send_result(struct su_context *ctx, policy_t policy) {
|
||||
char user[16];
|
||||
int notify = setup_user(ctx, user);
|
||||
|
||||
char activity[128];
|
||||
sprintf(activity, ACTION_RESULT, ctx->path.pkg_name);
|
||||
|
||||
// Send notice to manager, enable logging
|
||||
char *result_command[] = {
|
||||
AM_PATH,
|
||||
ACTION_RESULT,
|
||||
"--user",
|
||||
user,
|
||||
"--ei",
|
||||
"mode",
|
||||
"0",
|
||||
"--ei",
|
||||
"from.uid",
|
||||
fromUid,
|
||||
"--ei",
|
||||
"to.uid",
|
||||
toUid,
|
||||
"--ei",
|
||||
"pid",
|
||||
pid,
|
||||
"--es",
|
||||
"command",
|
||||
get_command(&ctx->to),
|
||||
"--es",
|
||||
"action",
|
||||
policy == ALLOW ? "allow" : "deny",
|
||||
AM_PATH, "broadcast", "-n",
|
||||
activity,
|
||||
"--user", user,
|
||||
"--ei", "mode", "0",
|
||||
"--ei", "from.uid", fromUid,
|
||||
"--ei", "to.uid", toUid,
|
||||
"--ei", "pid", pid,
|
||||
"--es", "command", get_command(&ctx->to),
|
||||
"--es", "action", policy == ALLOW ? "allow" : "deny",
|
||||
NULL
|
||||
};
|
||||
silent_run(result_command);
|
||||
@ -105,19 +94,12 @@ void app_send_result(struct su_context *ctx, policy_t policy) {
|
||||
if (notify) {
|
||||
sprintf(user, "%d", notify);
|
||||
char *notify_command[] = {
|
||||
AM_PATH,
|
||||
ACTION_RESULT,
|
||||
"--user",
|
||||
user,
|
||||
"--ei",
|
||||
"mode",
|
||||
"1",
|
||||
"--ei",
|
||||
"from.uid",
|
||||
fromUid,
|
||||
"--es",
|
||||
"action",
|
||||
policy == ALLOW ? "allow" : "deny",
|
||||
AM_PATH, "broadcast", "-n",
|
||||
activity,
|
||||
"--user", user,
|
||||
"--ei", "mode", "1",
|
||||
"--ei", "from.uid", fromUid,
|
||||
"--es", "action", policy == ALLOW ? "allow" : "deny",
|
||||
NULL
|
||||
};
|
||||
silent_run(notify_command);
|
||||
@ -128,17 +110,15 @@ void app_send_request(struct su_context *ctx) {
|
||||
char user[16];
|
||||
int notify = setup_user(ctx, user);
|
||||
|
||||
char activity[128];
|
||||
sprintf(activity, ACTION_REQUEST, ctx->path.pkg_name);
|
||||
|
||||
char *request_command[] = {
|
||||
AM_PATH,
|
||||
ACTION_REQUEST,
|
||||
"--user",
|
||||
user,
|
||||
"--es",
|
||||
"socket",
|
||||
ctx->path.sock_path,
|
||||
"--ez",
|
||||
"timeout",
|
||||
notify ? "false" : "true",
|
||||
AM_PATH, "start", "-n",
|
||||
activity,
|
||||
"--user", user,
|
||||
"--es", "socket", ctx->path.sock_path,
|
||||
"--ez", "timeout", notify ? "false" : "true",
|
||||
NULL
|
||||
};
|
||||
silent_run(request_command);
|
||||
@ -146,14 +126,12 @@ void app_send_request(struct su_context *ctx) {
|
||||
// Send notice to user to tell them root is managed by owner
|
||||
if (notify) {
|
||||
sprintf(user, "%d", notify);
|
||||
sprintf(activity, ACTION_RESULT, ctx->path.pkg_name);
|
||||
char *notify_command[] = {
|
||||
AM_PATH,
|
||||
ACTION_RESULT,
|
||||
"--user",
|
||||
user,
|
||||
"--ei",
|
||||
"mode",
|
||||
"2",
|
||||
AM_PATH, "broadcast", "-n",
|
||||
activity,
|
||||
"--user", user,
|
||||
"--ei", "mode", "2",
|
||||
NULL
|
||||
};
|
||||
silent_run(notify_command);
|
||||
|
95
db.c
95
db.c
@ -58,60 +58,109 @@ static int settings_callback(void *v, int argc, char **argv, char **azColName) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int strings_callback(void *v, int argc, char **argv, char **azColName) {
|
||||
struct su_context *ctx = (struct su_context *) v;
|
||||
char *entry, *target, *value;
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
if (strcmp(azColName[i], "key") == 0) {
|
||||
if (strcmp(argv[i], REQUESTER_ENTRY) == 0)
|
||||
target = ctx->path.pkg_name;
|
||||
entry = argv[i];
|
||||
} else if (strcmp(azColName[i], "value") == 0) {
|
||||
value = argv[i];
|
||||
}
|
||||
}
|
||||
LOGD("su_db: query %s=[%s]\n", entry, value);
|
||||
strcpy(target, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define BASE_FMT "/data/user%s/%d"
|
||||
#define USE_MULTI(info) (info->uid / 100000 != 0 && info->multiuser_mode == MULTIUSER_MODE_USER)
|
||||
|
||||
void database_check(struct su_context *ctx) {
|
||||
sqlite3 *db = NULL;
|
||||
int ret;
|
||||
char query[512], *err = NULL;
|
||||
char buffer[PATH_MAX], *err = NULL;
|
||||
|
||||
// Set default values
|
||||
ctx->info->root_access = ROOT_ACCESS_APPS_AND_ADB;
|
||||
ctx->info->multiuser_mode = MULTIUSER_MODE_OWNER_ONLY;
|
||||
ctx->info->mnt_ns = NAMESPACE_MODE_REQUESTER;
|
||||
ctx->info->policy = QUERY;
|
||||
strcpy(ctx->path.pkg_name, "???"); /* bad string so it doesn't exist */
|
||||
|
||||
// Populate paths
|
||||
sprintf(ctx->path.base_path, BASE_FMT, "_de", 0);
|
||||
if (access(ctx->path.base_path, R_OK) == -1)
|
||||
sprintf(ctx->path.base_path, BASE_FMT, "", 0);
|
||||
|
||||
sprintf(ctx->path.multiuser_path, BASE_FMT, "_de", ctx->info->uid / 100000);
|
||||
if (access(ctx->path.multiuser_path, R_OK) == -1)
|
||||
sprintf(ctx->path.multiuser_path, BASE_FMT, "", ctx->info->uid / 100000);
|
||||
|
||||
// Open database
|
||||
ret = sqlite3_open_v2(ctx->path.base_db, &db, SQLITE_OPEN_READONLY, NULL);
|
||||
sprintf(buffer, "%s/magisk.db", ctx->path.base_path);
|
||||
LOGD("su_db: open %s", buffer);
|
||||
ret = sqlite3_open_v2(buffer, &db, SQLITE_OPEN_READONLY, NULL);
|
||||
if (ret) {
|
||||
LOGD("sqlite3 open failure: %s\n", sqlite3_errstr(ret));
|
||||
sqlite3_close(db);
|
||||
return;
|
||||
goto stat_requester;
|
||||
}
|
||||
|
||||
// Check multiuser mode settings
|
||||
snprintf(query, sizeof(query), "SELECT key, value FROM settings WHERE key='%s'", MULTIUSER_MODE_ENTRY);
|
||||
sqlite3_exec(db, query, settings_callback, ctx, &err);
|
||||
|
||||
sprintf(buffer, "SELECT key, value FROM settings WHERE key='%s'", MULTIUSER_MODE_ENTRY);
|
||||
sqlite3_exec(db, buffer, settings_callback, ctx, &err);
|
||||
if (err != NULL)
|
||||
LOGE("sqlite3_exec: %s\n", err);
|
||||
err = NULL;
|
||||
|
||||
if (ctx->info->uid / 100000 != 0 && ctx->info->multiuser_mode == MULTIUSER_MODE_USER) {
|
||||
// Open database based on multiuser settings
|
||||
if (USE_MULTI(ctx->info)) {
|
||||
sqlite3_close(db);
|
||||
|
||||
// Open database
|
||||
ret = sqlite3_open_v2(ctx->path.multiuser_db, &db, SQLITE_OPEN_READONLY, NULL);
|
||||
sprintf(buffer, "%s/magisk.db", ctx->path.multiuser_path);
|
||||
LOGD("su_db: open %s", buffer);
|
||||
ret = sqlite3_open_v2(buffer, &db, SQLITE_OPEN_READONLY, NULL);
|
||||
if (ret) {
|
||||
LOGD("sqlite3 open failure: %s\n", sqlite3_errstr(ret));
|
||||
sqlite3_close(db);
|
||||
return;
|
||||
goto stat_requester;
|
||||
}
|
||||
}
|
||||
|
||||
// Query for policy
|
||||
snprintf(query, sizeof(query), "SELECT policy, until FROM policies WHERE uid=%d", ctx->info->uid % 100000);
|
||||
sqlite3_exec(db, query, policy_callback, ctx, &err);
|
||||
if (err != NULL) {
|
||||
// Read PKG name from DB
|
||||
strcpy(buffer, "SELECT key, value FROM strings");
|
||||
sqlite3_exec(db, buffer, strings_callback, ctx, &err);
|
||||
if (err != NULL)
|
||||
LOGE("sqlite3_exec: %s\n", err);
|
||||
return;
|
||||
}
|
||||
err = NULL;
|
||||
|
||||
// Query for policy
|
||||
sprintf(buffer, "SELECT policy, until FROM policies WHERE uid=%d", ctx->info->uid % 100000);
|
||||
sqlite3_exec(db, buffer, policy_callback, ctx, &err);
|
||||
if (err != NULL)
|
||||
LOGE("sqlite3_exec: %s\n", err);
|
||||
err = NULL;
|
||||
|
||||
// Query for settings
|
||||
snprintf(query, sizeof(query), "SELECT key, value FROM settings WHERE key!='%s'", MULTIUSER_MODE_ENTRY);
|
||||
sqlite3_exec(db, query, settings_callback, ctx, &err);
|
||||
if (err != NULL) {
|
||||
sprintf(buffer, "SELECT key, value FROM settings WHERE key!='%s'", MULTIUSER_MODE_ENTRY);
|
||||
sqlite3_exec(db, buffer, settings_callback, ctx, &err);
|
||||
if (err != NULL)
|
||||
LOGE("sqlite3_exec: %s\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
sqlite3_close(db);
|
||||
|
||||
stat_requester:
|
||||
// We prefer the orignal name
|
||||
sprintf(buffer, "%s/%s", USE_MULTI(ctx->info) ? ctx->path.multiuser_path : ctx->path.base_path, JAVA_PACKAGE_NAME);
|
||||
if (stat(buffer, &ctx->st) == -1) {
|
||||
sprintf(buffer, "%s/%s", USE_MULTI(ctx->info) ? ctx->path.multiuser_path : ctx->path.base_path, ctx->path.pkg_name);
|
||||
if (stat(buffer, &ctx->st) == -1) {
|
||||
LOGE("su: cannot find requester");
|
||||
ctx->info->policy = DENY;
|
||||
ctx->notify = 0;
|
||||
}
|
||||
} else {
|
||||
strcpy(ctx->path.pkg_name, JAVA_PACKAGE_NAME);
|
||||
}
|
||||
}
|
||||
|
25
su.c
25
su.c
@ -162,9 +162,9 @@ static void cleanup_signal(int sig) {
|
||||
__attribute__ ((noreturn)) void exit2(int status) {
|
||||
// Handle the pipe, or the daemon will get stuck
|
||||
if (su_ctx->info->policy == QUERY) {
|
||||
xwrite(pipefd[1], &su_ctx->info->policy, sizeof(su_ctx->info->policy));
|
||||
close(pipefd[0]);
|
||||
close(pipefd[1]);
|
||||
xwrite(su_ctx->pipefd[1], &su_ctx->info->policy, sizeof(su_ctx->info->policy));
|
||||
close(su_ctx->pipefd[0]);
|
||||
close(su_ctx->pipefd[1]);
|
||||
}
|
||||
exit(status);
|
||||
}
|
||||
@ -352,19 +352,6 @@ int su_daemon_main(int argc, char **argv) {
|
||||
|
||||
// New request or no db exist, notify user for response
|
||||
if (su_ctx->info->policy == QUERY) {
|
||||
mkdir(REQUESTOR_CACHE_PATH, 0770);
|
||||
if (chown(REQUESTOR_CACHE_PATH, su_ctx->st.st_uid, su_ctx->st.st_gid))
|
||||
PLOGE("chown (%s, %u, %u)", REQUESTOR_CACHE_PATH, su_ctx->st.st_uid, su_ctx->st.st_gid);
|
||||
|
||||
if (setgroups(0, NULL))
|
||||
PLOGE("setgroups");
|
||||
|
||||
if (setegid(su_ctx->st.st_gid))
|
||||
PLOGE("setegid (%u)", su_ctx->st.st_gid);
|
||||
|
||||
if (seteuid(su_ctx->st.st_uid))
|
||||
PLOGE("seteuid (%u)", su_ctx->st.st_uid);
|
||||
|
||||
socket_serv_fd = socket_create_temp(su_ctx->path.sock_path, sizeof(su_ctx->path.sock_path));
|
||||
setup_sighandlers(cleanup_signal);
|
||||
|
||||
@ -387,9 +374,9 @@ int su_daemon_main(int argc, char **argv) {
|
||||
su_ctx->info->policy = DENY;
|
||||
|
||||
// Report the policy to main daemon
|
||||
xwrite(pipefd[1], &su_ctx->info->policy, sizeof(su_ctx->info->policy));
|
||||
close(pipefd[0]);
|
||||
close(pipefd[1]);
|
||||
xwrite(su_ctx->pipefd[1], &su_ctx->info->policy, sizeof(su_ctx->info->policy));
|
||||
close(su_ctx->pipefd[0]);
|
||||
close(su_ctx->pipefd[1]);
|
||||
}
|
||||
|
||||
if (su_ctx->info->policy == ALLOW)
|
||||
|
14
su.h
14
su.h
@ -31,17 +31,14 @@
|
||||
#define NAMESPACE_MODE_REQUESTER 1
|
||||
#define NAMESPACE_MODE_ISOLATE 2
|
||||
|
||||
// DB entry for requester
|
||||
#define REQUESTER_ENTRY "requester"
|
||||
|
||||
// DO NOT CHANGE LINE BELOW, java package name will always be the same
|
||||
#define JAVA_PACKAGE_NAME "com.topjohnwu.magisk"
|
||||
|
||||
// If --rename-manifest-package is used in AAPT, this
|
||||
// must be changed to correspond to the new APK package name
|
||||
// See the two Android.mk files for more details.
|
||||
#define REQUESTOR JAVA_PACKAGE_NAME
|
||||
// This is used if wrapping the fragment classes and activities
|
||||
// with classes in another package.
|
||||
#define REQUESTOR_PREFIX JAVA_PACKAGE_NAME ".superuser"
|
||||
#define REQUESTOR_CACHE_PATH "/dev/" REQUESTOR
|
||||
|
||||
#define DEFAULT_SHELL "/system/bin/sh"
|
||||
|
||||
@ -80,9 +77,8 @@ struct su_request {
|
||||
|
||||
struct su_path {
|
||||
char base_path[PATH_MAX];
|
||||
char base_db[PATH_MAX];
|
||||
char multiuser_path[PATH_MAX];
|
||||
char multiuser_db[PATH_MAX];
|
||||
char pkg_name[PATH_MAX];
|
||||
char sock_path[PATH_MAX];
|
||||
};
|
||||
|
||||
@ -95,10 +91,10 @@ struct su_context {
|
||||
mode_t umask;
|
||||
char *cwd;
|
||||
struct stat st;
|
||||
int pipefd[2];
|
||||
};
|
||||
|
||||
extern struct su_context *su_ctx;
|
||||
extern int pipefd[2];
|
||||
|
||||
// su.c
|
||||
|
||||
|
83
su_daemon.c
83
su_daemon.c
@ -90,28 +90,6 @@ static void *collector(void *args) {
|
||||
}
|
||||
}
|
||||
|
||||
#define BASE_FMT "/data/user%s/%d/" REQUESTOR
|
||||
#define DB_FMT BASE_FMT "/databases/su.db"
|
||||
#define CAT_PATH(dest, fmt, ...) snprintf(dest, sizeof(dest), fmt, __VA_ARGS__)
|
||||
|
||||
static void populate_paths(struct su_context *ctx) {
|
||||
CAT_PATH(ctx->path.base_path, BASE_FMT, "_de", 0);
|
||||
if (access(ctx->path.base_path, R_OK) == -1)
|
||||
CAT_PATH(ctx->path.base_path, BASE_FMT, "", 0);
|
||||
|
||||
CAT_PATH(ctx->path.base_db, DB_FMT, "_de", 0);
|
||||
if (access(ctx->path.base_db, R_OK) == -1)
|
||||
CAT_PATH(ctx->path.base_db, DB_FMT, "", 0);
|
||||
|
||||
CAT_PATH(ctx->path.multiuser_path, BASE_FMT, "_de", ctx->info->uid / 100000);
|
||||
if (access(ctx->path.multiuser_path, R_OK) == -1)
|
||||
CAT_PATH(ctx->path.multiuser_path, BASE_FMT, "", ctx->info->uid / 100000);
|
||||
|
||||
CAT_PATH(ctx->path.multiuser_db, DB_FMT, "_de", ctx->info->uid / 100000);
|
||||
if (access(ctx->path.multiuser_db, R_OK) == -1)
|
||||
CAT_PATH(ctx->path.multiuser_db, DB_FMT, "", ctx->info->uid / 100000);
|
||||
}
|
||||
|
||||
void su_daemon_receiver(int client) {
|
||||
LOGD("su: request from client: %d\n", client);
|
||||
|
||||
@ -170,16 +148,6 @@ void su_daemon_receiver(int client) {
|
||||
.umask = 022,
|
||||
.notify = new_request,
|
||||
};
|
||||
su_ctx = &ctx;
|
||||
|
||||
populate_paths(su_ctx);
|
||||
|
||||
// Check main Magisk Manager
|
||||
xstat(su_ctx->path.base_path, &su_ctx->st);
|
||||
if (su_ctx->st.st_gid != su_ctx->st.st_uid) {
|
||||
LOGE("Bad uid/gid %d/%d for Superuser Requestor application", su_ctx->st.st_uid, su_ctx->st.st_gid);
|
||||
info->policy = DENY;
|
||||
}
|
||||
|
||||
// Lock before the policy is determined
|
||||
LOCK_UID();
|
||||
@ -187,41 +155,38 @@ void su_daemon_receiver(int client) {
|
||||
// Not cached, do the checks
|
||||
if (info->policy == QUERY) {
|
||||
// Get data from database
|
||||
database_check(su_ctx);
|
||||
|
||||
if (su_ctx->info->multiuser_mode == MULTIUSER_MODE_USER) {
|
||||
// Check the user installed Magisk Manager
|
||||
xstat(su_ctx->path.multiuser_path, &su_ctx->st);
|
||||
if (su_ctx->st.st_gid != su_ctx->st.st_uid) {
|
||||
LOGE("Bad uid/gid %d/%d for Superuser Requestor application", su_ctx->st.st_uid, su_ctx->st.st_gid);
|
||||
info->policy = DENY;
|
||||
}
|
||||
}
|
||||
database_check(&ctx);
|
||||
|
||||
// Handle multiuser denies
|
||||
if (su_ctx->info->uid / 100000 &&
|
||||
su_ctx->info->multiuser_mode == MULTIUSER_MODE_OWNER_ONLY) {
|
||||
if (info->uid / 100000 &&
|
||||
info->multiuser_mode == MULTIUSER_MODE_OWNER_ONLY) {
|
||||
info->policy = DENY;
|
||||
su_ctx->notify = 0;
|
||||
ctx.notify = 0;
|
||||
}
|
||||
|
||||
// always allow if this is Magisk Manager
|
||||
if (info->policy == QUERY && (info->uid % 100000) == (su_ctx->st.st_uid % 100000)) {
|
||||
info->policy = ALLOW;
|
||||
info->root_access = ROOT_ACCESS_APPS_AND_ADB;
|
||||
su_ctx->notify = 0;
|
||||
// Check requester
|
||||
if (info->policy == QUERY) {
|
||||
if (ctx.st.st_gid != ctx.st.st_uid) {
|
||||
LOGE("Bad uid/gid %d/%d for Superuser Requestor", ctx.st.st_uid, ctx.st.st_gid);
|
||||
info->policy = DENY;
|
||||
ctx.notify = 0;
|
||||
} else if ((info->uid % 100000) == (ctx.st.st_uid % 100000)) {
|
||||
info->policy = ALLOW;
|
||||
info->root_access = ROOT_ACCESS_APPS_AND_ADB;
|
||||
ctx.notify = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// always allow if it's root
|
||||
if (info->uid == UID_ROOT) {
|
||||
info->policy = ALLOW;
|
||||
info->root_access = ROOT_ACCESS_APPS_AND_ADB;
|
||||
su_ctx->notify = 0;
|
||||
ctx.notify = 0;
|
||||
}
|
||||
|
||||
// If still not determined, open a pipe and wait for results
|
||||
if (info->policy == QUERY)
|
||||
xpipe2(pipefd, O_CLOEXEC);
|
||||
xpipe2(ctx.pipefd, O_CLOEXEC);
|
||||
}
|
||||
|
||||
// Fork a new process, the child process will need to setsid,
|
||||
@ -235,9 +200,9 @@ void su_daemon_receiver(int client) {
|
||||
if (child) {
|
||||
// Wait for results
|
||||
if (info->policy == QUERY) {
|
||||
xxread(pipefd[0], &info->policy, sizeof(info->policy));
|
||||
close(pipefd[0]);
|
||||
close(pipefd[1]);
|
||||
xxread(ctx.pipefd[0], &info->policy, sizeof(info->policy));
|
||||
close(ctx.pipefd[0]);
|
||||
close(ctx.pipefd[1]);
|
||||
}
|
||||
|
||||
// The policy is determined, unlock
|
||||
@ -308,8 +273,8 @@ void su_daemon_receiver(int client) {
|
||||
}
|
||||
|
||||
// Get cwd
|
||||
su_ctx->cwd = read_string(client);
|
||||
LOGD("su: cwd=[%s]\n", su_ctx->cwd);
|
||||
ctx.cwd = read_string(client);
|
||||
LOGD("su: cwd=[%s]\n", ctx.cwd);
|
||||
|
||||
// Get pts_slave
|
||||
char *pts_slave = read_string(client);
|
||||
@ -330,7 +295,7 @@ void su_daemon_receiver(int client) {
|
||||
xstat(pts_slave, &stbuf);
|
||||
|
||||
//If caller is not root, ensure the owner of pts_slave is the caller
|
||||
if(stbuf.st_uid != credential.uid && credential.uid != 0) {
|
||||
if(stbuf.st_uid != info->uid && info->uid != 0) {
|
||||
LOGE("su: Wrong permission of pts_slave");
|
||||
exit2(1);
|
||||
}
|
||||
@ -363,6 +328,8 @@ void su_daemon_receiver(int client) {
|
||||
|
||||
close(ptsfd);
|
||||
|
||||
// Give main the reference
|
||||
su_ctx = &ctx;
|
||||
su_daemon_main(argc, argv);
|
||||
}
|
||||
|
||||
|
11
su_socket.c
11
su_socket.c
@ -29,21 +29,22 @@ int socket_create_temp(char *path, size_t len) {
|
||||
|
||||
memset(&sun, 0, sizeof(sun));
|
||||
sun.sun_family = AF_LOCAL;
|
||||
snprintf(path, len, "%s/.socket%d", REQUESTOR_CACHE_PATH, (int) syscall(SYS_gettid));
|
||||
snprintf(sun.sun_path, sizeof(sun.sun_path), "%s", path);
|
||||
snprintf(path, len, "/dev/.socket%d", (int) syscall(SYS_gettid));
|
||||
strcpy(sun.sun_path, path);
|
||||
|
||||
/*
|
||||
* Delete the socket to protect from situations when
|
||||
* something bad occured previously and the kernel reused pid from that process.
|
||||
* Small probability, isn't it.
|
||||
*/
|
||||
unlink(sun.sun_path);
|
||||
unlink(path);
|
||||
|
||||
xbind(fd, (struct sockaddr*) &sun, sizeof(sun));
|
||||
xlisten(fd, 1);
|
||||
|
||||
// Set context to su_device, so apps can access it
|
||||
setfilecon(sun.sun_path, "u:object_r:su_device:s0");
|
||||
// Set attributes so requester can access it
|
||||
setfilecon(path, "u:object_r:su_device:s0");
|
||||
chown(path, su_ctx->st.st_uid, su_ctx->st.st_gid);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user