X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fbus-proxyd%2Fbus-proxyd.c;h=b6b0056362f8f071af4092e67b2261b910f0dc65;hb=484adfd914504cd7e95867cea20ca7af71b888f2;hp=702f021a6bdcfed8df3082e4a7a53394b80fc546;hpb=a8a1a43f482af480c375a97921df6b42452c7092;p=elogind.git diff --git a/src/bus-proxyd/bus-proxyd.c b/src/bus-proxyd/bus-proxyd.c index 702f021a6..b6b005636 100644 --- a/src/bus-proxyd/bus-proxyd.c +++ b/src/bus-proxyd/bus-proxyd.c @@ -29,7 +29,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -60,13 +61,15 @@ static char **arg_configuration = NULL; typedef struct { int fd; + SharedPolicy *policy; + uid_t bus_uid; } ClientContext; static ClientContext *client_context_free(ClientContext *c) { if (!c) return NULL; - close(c->fd); + safe_close(c->fd); free(c); return NULL; @@ -74,14 +77,14 @@ static ClientContext *client_context_free(ClientContext *c) { DEFINE_TRIVIAL_CLEANUP_FUNC(ClientContext*, client_context_free); -static int client_context_new(ClientContext **out, int fd) { +static int client_context_new(ClientContext **out) { _cleanup_(client_context_freep) ClientContext *c = NULL; c = new0(ClientContext, 1); if (!c) return log_oom(); - c->fd = fd; + c->fd = -1; *out = c; c = NULL; @@ -91,17 +94,26 @@ static int client_context_new(ClientContext **out, int fd) { static void *run_client(void *userdata) { _cleanup_(client_context_freep) ClientContext *c = userdata; _cleanup_(proxy_freep) Proxy *p = NULL; + char comm[16]; int r; r = proxy_new(&p, c->fd, c->fd, arg_address); if (r < 0) goto exit; - r = proxy_load_policy(p, arg_configuration); + c->fd = -1; + + /* set comm to "p$PIDu$UID" and suffix with '*' if truncated */ + r = snprintf(comm, sizeof(comm), "p" PID_FMT "u" UID_FMT, p->local_creds.pid, p->local_creds.uid); + if (r >= (ssize_t)sizeof(comm)) + comm[sizeof(comm) - 2] = '*'; + (void) prctl(PR_SET_NAME, comm); + + r = proxy_set_policy(p, c->policy, arg_configuration); if (r < 0) goto exit; - r = proxy_hello_policy(p, getuid()); + r = proxy_hello_policy(p, c->bus_uid); if (r < 0) goto exit; @@ -111,22 +123,26 @@ exit: return NULL; } -static int loop_clients(int accept_fd) { +static int loop_clients(int accept_fd, uid_t bus_uid) { + _cleanup_(shared_policy_freep) SharedPolicy *sp = NULL; pthread_attr_t attr; int r; r = pthread_attr_init(&attr); if (r < 0) { - r = log_error_errno(errno, "Cannot initialize pthread attributes: %m"); - goto exit; + return log_error_errno(errno, "Cannot initialize pthread attributes: %m"); } r = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); if (r < 0) { r = log_error_errno(errno, "Cannot mark pthread attributes as detached: %m"); - goto exit_attr; + goto finish; } + r = shared_policy_new(&sp); + if (r < 0) + goto finish; + for (;;) { ClientContext *c; pthread_t tid; @@ -138,16 +154,20 @@ static int loop_clients(int accept_fd) { continue; r = log_error_errno(errno, "accept4() failed: %m"); - break; + goto finish; } - r = client_context_new(&c, fd); + r = client_context_new(&c); if (r < 0) { log_oom(); close(fd); continue; } + c->fd = fd; + c->policy = sp; + c->bus_uid = bus_uid; + r = pthread_create(&tid, &attr, run_client, c); if (r < 0) { log_error("Cannot spawn thread: %m"); @@ -156,9 +176,8 @@ static int loop_clients(int accept_fd) { } } -exit_attr: +finish: pthread_attr_destroy(&attr); -exit: return r; } @@ -213,17 +232,11 @@ static int parse_argv(int argc, char *argv[]) { puts(SYSTEMD_FEATURES); return 0; - case ARG_ADDRESS: { - char *a; - - a = strdup(optarg); - if (!a) + case ARG_ADDRESS: + r = free_and_strdup(&arg_address, optarg); + if (r < 0) return log_oom(); - - free(arg_address); - arg_address = a; break; - } case ARG_CONFIGURATION: r = strv_extend(&arg_configuration, optarg); @@ -276,11 +289,31 @@ static int parse_argv(int argc, char *argv[]) { int main(int argc, char *argv[]) { int r, accept_fd; + uid_t uid, bus_uid; + gid_t gid; log_set_target(LOG_TARGET_JOURNAL_OR_KMSG); log_parse_environment(); log_open(); + bus_uid = getuid(); + + if (geteuid() == 0) { + const char *user = "systemd-bus-proxy"; + + r = get_user_creds(&user, &uid, &gid, NULL, NULL); + if (r < 0) { + log_error_errno(r, "Cannot resolve user name %s: %m", user); + goto finish; + } + + r = drop_privileges(uid, gid, 1ULL << CAP_IPC_OWNER); + if (r < 0) { + log_error_errno(r, "Cannot drop privileges: %m"); + goto finish; + } + } + r = parse_argv(argc, argv); if (r <= 0) goto finish; @@ -292,13 +325,14 @@ int main(int argc, char *argv[]) { } accept_fd = SD_LISTEN_FDS_START; + r = fd_nonblock(accept_fd, false); if (r < 0) { log_error_errno(r, "Cannot mark accept-fd non-blocking: %m"); goto finish; } - r = loop_clients(accept_fd); + r = loop_clients(accept_fd, bus_uid); finish: sd_notify(false,