Add preliminary shared UID app support

This commit is contained in:
topjohnwu
2022-03-25 13:08:13 -07:00
parent f2c15c7701
commit 9f1740cc4f
19 changed files with 337 additions and 461 deletions

View File

@@ -191,6 +191,7 @@ void app_notify(const su_context &ctx) {
vector<Extra> extras;
extras.reserve(2);
extras.emplace_back("from.uid", ctx.info->uid);
extras.emplace_back("pid", ctx.pid);
extras.emplace_back("policy", ctx.info->access.policy);
exec_cmd("notify", extras, ctx.info);
@@ -198,21 +199,22 @@ void app_notify(const su_context &ctx) {
}
}
int app_request(const shared_ptr<su_info> &info) {
int app_request(const su_context &ctx) {
// Create FIFO
char fifo[64];
strcpy(fifo, "/dev/socket/");
gen_rand_str(fifo + 12, 32, true);
mkfifo(fifo, 0600);
chown(fifo, info->mgr_st.st_uid, info->mgr_st.st_gid);
chown(fifo, ctx.info->mgr_st.st_uid, ctx.info->mgr_st.st_gid);
setfilecon(fifo, "u:object_r:" SEPOL_FILE_TYPE ":s0");
// Send request
vector<Extra> extras;
extras.reserve(2);
extras.emplace_back("fifo", fifo);
extras.emplace_back("uid", info->eval_uid);
exec_cmd("request", extras, info, false);
extras.emplace_back("uid", ctx.info->eval_uid);
extras.emplace_back("pid", ctx.pid);
exec_cmd("request", extras, ctx.info, false);
// Wait for data input for at most 70 seconds
int fd = xopen(fifo, O_RDONLY | O_CLOEXEC | O_NONBLOCK);

View File

@@ -60,4 +60,4 @@ struct su_context {
void app_log(const su_context &ctx);
void app_notify(const su_context &ctx);
int app_request(const std::shared_ptr<su_info> &info);
int app_request(const su_context &ctx);

View File

@@ -193,20 +193,7 @@ static shared_ptr<su_info> get_su_info(unsigned uid) {
info->access = NO_SU_ACCESS;
return info;
}
} else {
return info;
}
// If still not determined, ask manager
int fd = app_request(info);
if (fd < 0) {
info->access.policy = DENY;
} else {
int ret = read_int_be(fd);
info->access.policy = ret < 0 ? DENY : static_cast<policy_t>(ret);
close(fd);
}
return info;
}
@@ -237,6 +224,18 @@ void su_daemon_handler(int client, const sock_cred *cred) {
read_string(client, ctx.req.shell);
read_string(client, ctx.req.command);
// If still not determined, ask manager
if (ctx.info->access.policy == QUERY) {
int fd = app_request(ctx);
if (fd < 0) {
ctx.info->access.policy = DENY;
} else {
int ret = read_int_be(fd);
ctx.info->access.policy = ret < 0 ? DENY : static_cast<policy_t>(ret);
close(fd);
}
}
if (ctx.info->access.log)
app_log(ctx);
else if (ctx.info->access.notify)