]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udev-rules: ignore non-system user/group in OWNER=/GROUP=
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 22 Jan 2025 21:08:23 +0000 (06:08 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 23 Jan 2025 17:33:18 +0000 (02:33 +0900)
Recently, we introduce 'clock' system group, and set it for rtc/ptp
devices. See af96ccfc24bc4803078a46b4ef2cdeb5decdfbcd.

However, if non-system group with the same name is already exist,
previously the devices were owned by the non-system group. That may
possibly happen on updating systemd.

Let's avoid accidentally devices being owned by non-system user/group.

src/udev/udev-rules.c

index 91a0d1f01aac1fe85af19630ff58b9a1822e253c..f8afe923d8457e8068209a7b9383b799bc7aa479 100644 (file)
@@ -42,6 +42,7 @@
 #include "udev-trace.h"
 #include "udev-util.h"
 #include "udev-worker.h"
+#include "uid-classification.h"
 #include "user-util.h"
 #include "virt.h"
 
@@ -500,6 +501,9 @@ static int rule_resolve_user(UdevRuleLine *rule_line, const char *name, uid_t *r
                 return log_line_error_errno(rule_line, r, "Unknown user '%s', ignoring.", name);
         if (r < 0)
                 return log_line_error_errno(rule_line, r, "Failed to resolve user '%s', ignoring: %m", name);
+        if (!uid_is_system(uid))
+                return log_line_error_errno(rule_line, SYNTHETIC_ERRNO(EINVAL),
+                                            "User '%s' is not a system user (UID="UID_FMT"), ignoring.", name, uid);
 
         n = strdup(name);
         if (!n)
@@ -535,6 +539,9 @@ static int rule_resolve_group(UdevRuleLine *rule_line, const char *name, gid_t *
                 return log_line_error_errno(rule_line, r, "Unknown group '%s', ignoring.", name);
         if (r < 0)
                 return log_line_error_errno(rule_line, r, "Failed to resolve group '%s', ignoring: %m", name);
+        if (!gid_is_system(gid))
+                return log_line_error_errno(rule_line, SYNTHETIC_ERRNO(EINVAL),
+                                            "Group '%s' is not a system group (GID="GID_FMT"), ignoring.", name, gid);
 
         n = strdup(name);
         if (!n)
@@ -1038,9 +1045,13 @@ static int parse_token(
                         op = OP_ASSIGN;
                 }
 
-                if (parse_uid(value, &uid) >= 0)
+                if (parse_uid(value, &uid) >= 0) {
+                        if (!uid_is_system(uid))
+                                return log_line_error_errno(rule_line, SYNTHETIC_ERRNO(EINVAL),
+                                                            "UID="UID_FMT" is not in the system user range, ignoring.", uid);
+
                         r = rule_line_add_token(rule_line, TK_A_OWNER_ID, op, NULL, UID_TO_PTR(uid), /* is_case_insensitive = */ false, token_str);
-                else if (resolve_name_timing == RESOLVE_NAME_EARLY &&
+                else if (resolve_name_timing == RESOLVE_NAME_EARLY &&
                            rule_get_substitution_type(value) == SUBST_TYPE_PLAIN) {
 
                         r = rule_resolve_user(rule_line, value, &uid);
@@ -1067,9 +1078,13 @@ static int parse_token(
                         op = OP_ASSIGN;
                 }
 
-                if (parse_gid(value, &gid) >= 0)
+                if (parse_gid(value, &gid) >= 0) {
+                        if (!gid_is_system(gid))
+                                return log_line_error_errno(rule_line, SYNTHETIC_ERRNO(EINVAL),
+                                                            "GID="GID_FMT" is not in the system group range, ignoring.", gid);
+
                         r = rule_line_add_token(rule_line, TK_A_GROUP_ID, op, NULL, GID_TO_PTR(gid), /* is_case_insensitive = */ false, token_str);
-                else if (resolve_name_timing == RESOLVE_NAME_EARLY &&
+                else if (resolve_name_timing == RESOLVE_NAME_EARLY &&
                            rule_get_substitution_type(value) == SUBST_TYPE_PLAIN) {
 
                         r = rule_resolve_group(rule_line, value, &gid);
@@ -2656,9 +2671,10 @@ static int udev_rule_apply_token_to_event(
                 if (!apply_format_value(event, token, owner, sizeof(owner), "user name"))
                         return true;
 
+                uid_t uid;
                 r = get_user_creds(
                                 &ow,
-                                &event->uid,
+                                &uid,
                                 /* ret_gid = */ NULL,
                                 /* ret_home = */ NULL,
                                 /* ret_shell = */ NULL,
@@ -2667,8 +2683,12 @@ static int udev_rule_apply_token_to_event(
                         log_event_error_errno(event, token, r, "Unknown user \"%s\", ignoring.", owner);
                 else if (r < 0)
                         log_event_error_errno(event, token, r, "Failed to resolve user \"%s\", ignoring: %m", owner);
-                else
+                else if (!uid_is_system(uid))
+                        log_event_error(event, token, "User \"%s\" is not a system user (UID="UID_FMT"), ignoring.", owner, uid);
+                else {
+                        event->uid = uid;
                         log_event_debug(event, token, "Set owner: %s(%u)", owner, event->uid);
+                }
                 return true;
         }
         case TK_A_GROUP: {
@@ -2684,13 +2704,18 @@ static int udev_rule_apply_token_to_event(
                 if (!apply_format_value(event, token, group, sizeof(group), "group name"))
                         return true;
 
-                r = get_group_creds(&gr, &event->gid, USER_CREDS_ALLOW_MISSING);
+                gid_t gid;
+                r = get_group_creds(&gr, &gid, USER_CREDS_ALLOW_MISSING);
                 if (r == -ESRCH)
                         log_event_error_errno(event, token, r, "Unknown group \"%s\", ignoring.", group);
                 else if (r < 0)
                         log_event_error_errno(event, token, r, "Failed to resolve group \"%s\", ignoring: %m", group);
-                else
+                else if (!gid_is_system(gid))
+                        log_event_error(event, token, "Group \"%s\" is not a system group (GID="GID_FMT"), ignoring.", group, gid);
+                else {
+                        event->gid = gid;
                         log_event_debug(event, token, "Set group: %s(%u)", group, event->gid);
+                }
                 return true;
         }
         case TK_A_MODE: {