bus: use EUID over UID and fix unix-creds
Whenever a process performs an action on an object, the kernel uses the EUID of the process to do permission checks and to apply on any newly created objects. The UID of a process is only used if someone *ELSE* acts on the process. That is, the UID of a process defines who owns the process, the EUID defines what privileges are used by this process when performing an action. Process limits, on the other hand, are always applied to the real UID, not the effective UID. This is, because a process has a user object linked, which always corresponds to its UID. A process never has a user object linked for its EUID. Thus, accounting (and limits) is always done on the real UID. This commit fixes all sd-bus users to use the EUID when performing privilege checks and alike. Furthermore, it fixes unix-creds to be parsed as EUID, not UID (as the kernel always takes the EUID on UDS). Anyone using UID (eg., to do user-accounting) has to fall back to the EUID as UDS does not transmit the UID.
This commit is contained in:
parent
e23f4bb525
commit
05bae4a60c
|
@ -252,7 +252,7 @@ int bus_proxy_process_driver(sd_bus *a, sd_bus *b, sd_bus_message *m, SharedPoli
|
|||
if (!sd_bus_message_has_signature(m, "s"))
|
||||
return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
|
||||
|
||||
r = get_creds_by_message(a, m, SD_BUS_CREDS_UID, &creds, &error);
|
||||
r = get_creds_by_message(a, m, SD_BUS_CREDS_EUID, &creds, &error);
|
||||
if (r < 0)
|
||||
return synthetic_reply_method_errno(m, r, &error);
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ static int proxy_create_dest(Proxy *p, const char *dest, const char *local_sec,
|
|||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set FD negotiation: %m");
|
||||
|
||||
r = sd_bus_negotiate_creds(b, true, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_GID|SD_BUS_CREDS_SELINUX_CONTEXT);
|
||||
r = sd_bus_negotiate_creds(b, true, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SELINUX_CONTEXT);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set credential negotiation: %m");
|
||||
|
||||
|
@ -134,7 +134,7 @@ static int proxy_create_local(Proxy *p, int in_fd, int out_fd, bool negotiate_fd
|
|||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set FD negotiation: %m");
|
||||
|
||||
r = sd_bus_negotiate_creds(b, true, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_GID|SD_BUS_CREDS_SELINUX_CONTEXT);
|
||||
r = sd_bus_negotiate_creds(b, true, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SELINUX_CONTEXT);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set credential negotiation: %m");
|
||||
|
||||
|
@ -433,8 +433,8 @@ static int process_policy_unlocked(sd_bus *from, sd_bus *to, sd_bus_message *m,
|
|||
/* The message came from the kernel, and is sent to our legacy client. */
|
||||
sd_bus_creds_get_well_known_names(&m->creds, &sender_names);
|
||||
|
||||
(void) sd_bus_creds_get_uid(&m->creds, &sender_uid);
|
||||
(void) sd_bus_creds_get_gid(&m->creds, &sender_gid);
|
||||
(void) sd_bus_creds_get_euid(&m->creds, &sender_uid);
|
||||
(void) sd_bus_creds_get_egid(&m->creds, &sender_gid);
|
||||
|
||||
if (sender_uid == UID_INVALID || sender_gid == GID_INVALID) {
|
||||
_cleanup_bus_creds_unref_ sd_bus_creds *sender_creds = NULL;
|
||||
|
@ -446,12 +446,12 @@ static int process_policy_unlocked(sd_bus *from, sd_bus *to, sd_bus_message *m,
|
|||
* case, query the creds of the peer
|
||||
* instead. */
|
||||
|
||||
r = bus_get_name_creds_kdbus(from, m->sender, SD_BUS_CREDS_UID|SD_BUS_CREDS_GID, true, &sender_creds);
|
||||
r = bus_get_name_creds_kdbus(from, m->sender, SD_BUS_CREDS_EUID|SD_BUS_CREDS_EGID, true, &sender_creds);
|
||||
if (r < 0)
|
||||
return handle_policy_error(m, r);
|
||||
|
||||
(void) sd_bus_creds_get_uid(sender_creds, &sender_uid);
|
||||
(void) sd_bus_creds_get_gid(sender_creds, &sender_gid);
|
||||
(void) sd_bus_creds_get_euid(sender_creds, &sender_uid);
|
||||
(void) sd_bus_creds_get_egid(sender_creds, &sender_gid);
|
||||
}
|
||||
|
||||
/* First check whether the sender can send the message to our name */
|
||||
|
@ -483,7 +483,7 @@ static int process_policy_unlocked(sd_bus *from, sd_bus *to, sd_bus_message *m,
|
|||
if (m->destination) {
|
||||
r = bus_get_name_creds_kdbus(to, m->destination,
|
||||
SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME|
|
||||
SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID,
|
||||
SD_BUS_CREDS_EUID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_PID,
|
||||
true, &destination_creds);
|
||||
if (r < 0)
|
||||
return handle_policy_error(m, r);
|
||||
|
@ -494,8 +494,8 @@ static int process_policy_unlocked(sd_bus *from, sd_bus *to, sd_bus_message *m,
|
|||
|
||||
sd_bus_creds_get_well_known_names(destination_creds, &destination_names);
|
||||
|
||||
(void) sd_bus_creds_get_uid(destination_creds, &destination_uid);
|
||||
(void) sd_bus_creds_get_gid(destination_creds, &destination_gid);
|
||||
(void) sd_bus_creds_get_euid(destination_creds, &destination_uid);
|
||||
(void) sd_bus_creds_get_egid(destination_creds, &destination_gid);
|
||||
}
|
||||
|
||||
/* First check if we (the sender) can send to this name */
|
||||
|
|
|
@ -174,11 +174,11 @@ static int rename_service(sd_bus *a, sd_bus *b) {
|
|||
assert(a);
|
||||
assert(b);
|
||||
|
||||
r = sd_bus_get_owner_creds(b, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_CMDLINE|SD_BUS_CREDS_COMM|SD_BUS_CREDS_AUGMENT, &creds);
|
||||
r = sd_bus_get_owner_creds(b, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID|SD_BUS_CREDS_CMDLINE|SD_BUS_CREDS_COMM|SD_BUS_CREDS_AUGMENT, &creds);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_creds_get_uid(creds, &uid);
|
||||
r = sd_bus_creds_get_euid(creds, &uid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -70,9 +70,9 @@ static int audit_callback(
|
|||
|
||||
if (sd_bus_creds_get_audit_login_uid(audit->creds, &login_uid) >= 0)
|
||||
snprintf(login_uid_buf, sizeof(login_uid_buf), UID_FMT, login_uid);
|
||||
if (sd_bus_creds_get_uid(audit->creds, &uid) >= 0)
|
||||
if (sd_bus_creds_get_euid(audit->creds, &uid) >= 0)
|
||||
snprintf(uid_buf, sizeof(uid_buf), UID_FMT, uid);
|
||||
if (sd_bus_creds_get_gid(audit->creds, &gid) >= 0)
|
||||
if (sd_bus_creds_get_egid(audit->creds, &gid) >= 0)
|
||||
snprintf(gid_buf, sizeof(gid_buf), GID_FMT, gid);
|
||||
|
||||
snprintf(msgbuf, msgbufsize,
|
||||
|
@ -203,7 +203,7 @@ int mac_selinux_generic_access_check(
|
|||
|
||||
r = sd_bus_query_sender_creds(
|
||||
message,
|
||||
SD_BUS_CREDS_PID|SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|
|
||||
SD_BUS_CREDS_PID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_EGID|
|
||||
SD_BUS_CREDS_CMDLINE|SD_BUS_CREDS_AUDIT_LOGIN_UID|
|
||||
SD_BUS_CREDS_SELINUX_CONTEXT|
|
||||
SD_BUS_CREDS_AUGMENT /* get more bits from /proc */,
|
||||
|
|
|
@ -762,7 +762,7 @@ static int bus_get_name_creds_dbus1(
|
|||
|
||||
if ((mask & SD_BUS_CREDS_PID) ||
|
||||
((mask & SD_BUS_CREDS_AUGMENT) &&
|
||||
(mask & (SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
|
||||
(mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
|
||||
SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID|
|
||||
SD_BUS_CREDS_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE|
|
||||
SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID|
|
||||
|
@ -798,7 +798,7 @@ static int bus_get_name_creds_dbus1(
|
|||
reply = sd_bus_message_unref(reply);
|
||||
}
|
||||
|
||||
if (mask & SD_BUS_CREDS_UID) {
|
||||
if (mask & SD_BUS_CREDS_EUID) {
|
||||
uint32_t u;
|
||||
|
||||
r = sd_bus_call_method(
|
||||
|
@ -818,8 +818,8 @@ static int bus_get_name_creds_dbus1(
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
c->uid = u;
|
||||
c->mask |= SD_BUS_CREDS_UID;
|
||||
c->euid = u;
|
||||
c->mask |= SD_BUS_CREDS_EUID;
|
||||
|
||||
reply = sd_bus_message_unref(reply);
|
||||
}
|
||||
|
@ -961,13 +961,13 @@ static int bus_get_owner_creds_dbus1(sd_bus *bus, uint64_t mask, sd_bus_creds **
|
|||
}
|
||||
|
||||
if (bus->ucred.uid != UID_INVALID) {
|
||||
c->uid = bus->ucred.uid;
|
||||
c->mask |= SD_BUS_CREDS_UID & mask;
|
||||
c->euid = bus->ucred.uid;
|
||||
c->mask |= SD_BUS_CREDS_EUID & mask;
|
||||
}
|
||||
|
||||
if (bus->ucred.gid != GID_INVALID) {
|
||||
c->gid = bus->ucred.gid;
|
||||
c->mask |= SD_BUS_CREDS_GID & mask;
|
||||
c->egid = bus->ucred.gid;
|
||||
c->mask |= SD_BUS_CREDS_EGID & mask;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -424,19 +424,19 @@ int bus_message_from_header(
|
|||
|
||||
if (ucred) {
|
||||
m->creds.pid = ucred->pid;
|
||||
m->creds.uid = ucred->uid;
|
||||
m->creds.gid = ucred->gid;
|
||||
m->creds.euid = ucred->uid;
|
||||
m->creds.egid = ucred->gid;
|
||||
|
||||
/* Due to namespace translations some data might be
|
||||
* missing from this ucred record. */
|
||||
if (m->creds.pid > 0)
|
||||
m->creds.mask |= SD_BUS_CREDS_PID;
|
||||
|
||||
if (m->creds.uid != UID_INVALID)
|
||||
m->creds.mask |= SD_BUS_CREDS_UID;
|
||||
if (m->creds.euid != UID_INVALID)
|
||||
m->creds.mask |= SD_BUS_CREDS_EUID;
|
||||
|
||||
if (m->creds.gid != GID_INVALID)
|
||||
m->creds.mask |= SD_BUS_CREDS_GID;
|
||||
if (m->creds.egid != GID_INVALID)
|
||||
m->creds.mask |= SD_BUS_CREDS_EGID;
|
||||
}
|
||||
|
||||
if (label) {
|
||||
|
|
|
@ -160,7 +160,7 @@ static int list_bus_names(sd_bus *bus, char **argv) {
|
|||
r = sd_bus_get_name_creds(
|
||||
bus, *i,
|
||||
(arg_augment_creds ? SD_BUS_CREDS_AUGMENT : 0) |
|
||||
SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_COMM|
|
||||
SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID|SD_BUS_CREDS_COMM|
|
||||
SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_SESSION|
|
||||
SD_BUS_CREDS_DESCRIPTION, &creds);
|
||||
if (r >= 0) {
|
||||
|
@ -178,7 +178,7 @@ static int list_bus_names(sd_bus *bus, char **argv) {
|
|||
} else
|
||||
fputs(" - - ", stdout);
|
||||
|
||||
r = sd_bus_creds_get_uid(creds, &uid);
|
||||
r = sd_bus_creds_get_euid(creds, &uid);
|
||||
if (r >= 0) {
|
||||
_cleanup_free_ char *u = NULL;
|
||||
|
||||
|
|
|
@ -1606,11 +1606,11 @@ static int method_do_shutdown_or_sleep(
|
|||
return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
|
||||
}
|
||||
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_creds_get_uid(creds, &uid);
|
||||
r = sd_bus_creds_get_euid(creds, &uid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -1759,11 +1759,11 @@ static int method_can_shutdown_or_sleep(
|
|||
return sd_bus_reply_method_return(message, "s", "na");
|
||||
}
|
||||
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_creds_get_uid(creds, &uid);
|
||||
r = sd_bus_creds_get_euid(creds, &uid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -1938,11 +1938,11 @@ static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata,
|
|||
if (r == 0)
|
||||
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
|
||||
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID, &creds);
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_creds_get_uid(creds, &uid);
|
||||
r = sd_bus_creds_get_euid(creds, &uid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -239,11 +239,11 @@ static int method_set_idle_hint(sd_bus *bus, sd_bus_message *message, void *user
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_creds_get_uid(creds, &uid);
|
||||
r = sd_bus_creds_get_euid(creds, &uid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -302,11 +302,11 @@ static int method_take_control(sd_bus *bus, sd_bus_message *message, void *userd
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_creds_get_uid(creds, &uid);
|
||||
r = sd_bus_creds_get_euid(creds, &uid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
|
Loading…
Reference in a new issue