chiark / gitweb /
bus: use EUID over UID and fix unix-creds
authorDavid Herrmann <dh.herrmann@gmail.com>
Sun, 18 Jan 2015 12:55:55 +0000 (13:55 +0100)
committerDavid Herrmann <dh.herrmann@gmail.com>
Sun, 18 Jan 2015 12:55:55 +0000 (13:55 +0100)
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.

src/bus-proxyd/driver.c
src/bus-proxyd/proxy.c
src/bus-proxyd/stdio-bridge.c
src/core/selinux-access.c
src/libsystemd/sd-bus/bus-control.c
src/libsystemd/sd-bus/bus-message.c
src/libsystemd/sd-bus/busctl.c
src/login/logind-dbus.c
src/login/logind-session-dbus.c

index 361b14c1317d650de2083bc692bfeb9cd3fe5ae9..b2a44563c0371fc6215eaddf32d9bb765adfd007 100644 (file)
@@ -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);
 
index 329188ecf8ef2362126ff33cd527453dff504b01..bd02ee12b37754b5fb47fbd174de75d8879d0605 100644 (file)
@@ -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 */
index c17047b7e9f9878b033a900ef766c3f4df73613e..6fb83033d9e84fdf96ae07a5faea5f2e8806c712 100644 (file)
@@ -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;
 
index b45a4513e28a5b40ebb03e620c5ac6a3141e3fd8..f6389584f75ae4a77bb7fffd9c1a9eaea70eaea1 100644 (file)
@@ -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 */,
index b45014078d063fedb11b14173a44f6cf10b3d9ac..35c79cf899551c1c4903a065c4a9500f228c1b6c 100644 (file)
@@ -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;
                 }
         }
 
index f352c7298139b9a25594d578bc04cecaef9fbac0..23076d25ddb3360b4a6848485633f79bed77a05c 100644 (file)
@@ -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) {
index c0d51e06a3b2a068dba479ac7cc51d0742b5c27d..f0bc2a76a56956a5e17d20b4a0d873aae1ef6615 100644 (file)
@@ -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;
 
index bc985a3754b552e62b2247c6f57bbaa19753afb9..f2f91d5ded05fc1a5705b14529987ad7f3023330 100644 (file)
@@ -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;
 
index e3486fe5fc3ed5e640ce385627555d5b95452699..4e7edef52d7a8f22f357ff7d3a84d67cfe96f67c 100644 (file)
@@ -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;