diff options
Diffstat (limited to 'src/libnm-systemd-core/src/libsystemd/sd-id128/sd-id128.c')
-rw-r--r-- | src/libnm-systemd-core/src/libsystemd/sd-id128/sd-id128.c | 81 |
1 files changed, 43 insertions, 38 deletions
diff --git a/src/libnm-systemd-core/src/libsystemd/sd-id128/sd-id128.c b/src/libnm-systemd-core/src/libsystemd/sd-id128/sd-id128.c index 709c8ffb57..ec3a496dba 100644 --- a/src/libnm-systemd-core/src/libsystemd/sd-id128/sd-id128.c +++ b/src/libnm-systemd-core/src/libsystemd/sd-id128/sd-id128.c @@ -15,18 +15,21 @@ #include "macro.h" #include "missing_syscall.h" #include "random-util.h" +#include "stat-util.h" #include "user-util.h" -#include "util.h" _public_ char *sd_id128_to_string(sd_id128_t id, char s[_SD_ARRAY_STATIC SD_ID128_STRING_MAX]) { + size_t k = 0; + assert_return(s, NULL); - for (size_t n = 0; n < 16; n++) { - s[n*2] = hexchar(id.bytes[n] >> 4); - s[n*2+1] = hexchar(id.bytes[n] & 0xF); + for (size_t n = 0; n < sizeof(sd_id128_t); n++) { + s[k++] = hexchar(id.bytes[n] >> 4); + s[k++] = hexchar(id.bytes[n] & 0xF); } - s[SD_ID128_STRING_MAX-1] = 0; + assert(k == SD_ID128_STRING_MAX - 1); + s[k] = 0; return s; } @@ -38,7 +41,7 @@ _public_ char *sd_id128_to_uuid_string(sd_id128_t id, char s[_SD_ARRAY_STATIC SD /* Similar to sd_id128_to_string() but formats the result as UUID instead of plain hex chars */ - for (size_t n = 0; n < 16; n++) { + for (size_t n = 0; n < sizeof(sd_id128_t); n++) { if (IN_SET(n, 4, 6, 8, 10)) s[k++] = '-'; @@ -53,14 +56,14 @@ _public_ char *sd_id128_to_uuid_string(sd_id128_t id, char s[_SD_ARRAY_STATIC SD return s; } -_public_ int sd_id128_from_string(const char s[], sd_id128_t *ret) { - unsigned n, i; +_public_ int sd_id128_from_string(const char *s, sd_id128_t *ret) { + size_t n, i; sd_id128_t t; bool is_guid = false; assert_return(s, -EINVAL); - for (n = 0, i = 0; n < 16;) { + for (n = 0, i = 0; n < sizeof(sd_id128_t);) { int a, b; if (s[i] == '-') { @@ -90,7 +93,7 @@ _public_ int sd_id128_from_string(const char s[], sd_id128_t *ret) { t.bytes[n++] = (a << 4) | b; } - if (i != (is_guid ? 36 : 32)) + if (i != (is_guid ? SD_ID128_UUID_STRING_MAX : SD_ID128_STRING_MAX) - 1) return -EINVAL; if (s[i] != 0) @@ -121,10 +124,8 @@ _public_ int sd_id128_get_machine(sd_id128_t *ret) { static thread_local sd_id128_t saved_machine_id = {}; int r; - assert_return(ret, -EINVAL); - if (sd_id128_is_null(saved_machine_id)) { - r = id128_read("/etc/machine-id", ID128_PLAIN, &saved_machine_id); + r = id128_read("/etc/machine-id", ID128_FORMAT_PLAIN, &saved_machine_id); if (r < 0) return r; @@ -132,7 +133,8 @@ _public_ int sd_id128_get_machine(sd_id128_t *ret) { return -ENOMEDIUM; } - *ret = saved_machine_id; + if (ret) + *ret = saved_machine_id; return 0; } @@ -140,15 +142,19 @@ _public_ int sd_id128_get_boot(sd_id128_t *ret) { static thread_local sd_id128_t saved_boot_id = {}; int r; - assert_return(ret, -EINVAL); - if (sd_id128_is_null(saved_boot_id)) { - r = id128_read("/proc/sys/kernel/random/boot_id", ID128_UUID, &saved_boot_id); + r = id128_read("/proc/sys/kernel/random/boot_id", ID128_FORMAT_UUID, &saved_boot_id); + if (r == -ENOENT && proc_mounted() == 0) + return -ENOSYS; if (r < 0) return r; + + if (sd_id128_is_null(saved_boot_id)) + return -ENOMEDIUM; } - *ret = saved_boot_id; + if (ret) + *ret = saved_boot_id; return 0; } @@ -198,22 +204,22 @@ static int get_invocation_from_keyring(sd_id128_t *ret) { /* Chop off the final description string */ d = strrchr(description, ';'); if (!d) - return -EIO; + return -EUCLEAN; *d = 0; /* Look for the permissions */ p = strrchr(description, ';'); if (!p) - return -EIO; + return -EUCLEAN; errno = 0; perms = strtoul(p + 1, &e, 16); if (errno > 0) return -errno; if (e == p + 1) /* Read at least one character */ - return -EIO; + return -EUCLEAN; if (e != d) /* Must reached the end */ - return -EIO; + return -EUCLEAN; if ((perms & ~MAX_PERMS) != 0) return -EPERM; @@ -223,7 +229,7 @@ static int get_invocation_from_keyring(sd_id128_t *ret) { /* Look for the group ID */ g = strrchr(description, ';'); if (!g) - return -EIO; + return -EUCLEAN; r = parse_gid(g + 1, &gid); if (r < 0) return r; @@ -234,7 +240,7 @@ static int get_invocation_from_keyring(sd_id128_t *ret) { /* Look for the user ID */ u = strrchr(description, ';'); if (!u) - return -EIO; + return -EUCLEAN; r = parse_uid(u + 1, &uid); if (r < 0) return r; @@ -245,13 +251,14 @@ static int get_invocation_from_keyring(sd_id128_t *ret) { if (c < 0) return -errno; if (c != sizeof(sd_id128_t)) - return -EIO; + return -EUCLEAN; return 0; } static int get_invocation_from_environment(sd_id128_t *ret) { const char *e; + int r; assert(ret); @@ -259,33 +266,31 @@ static int get_invocation_from_environment(sd_id128_t *ret) { if (!e) return -ENXIO; - return sd_id128_from_string(e, ret); + r = sd_id128_from_string(e, ret); + return r == -EINVAL ? -EUCLEAN : r; } _public_ int sd_id128_get_invocation(sd_id128_t *ret) { static thread_local sd_id128_t saved_invocation_id = {}; int r; - assert_return(ret, -EINVAL); - if (sd_id128_is_null(saved_invocation_id)) { /* We first check the environment. The environment variable is primarily relevant for user * services, and sufficiently safe as long as no privilege boundary is involved. */ r = get_invocation_from_environment(&saved_invocation_id); - if (r >= 0) { - *ret = saved_invocation_id; - return 0; - } else if (r != -ENXIO) - return r; - - /* The kernel keyring is relevant for system services (as for user services we don't store - * the invocation ID in the keyring, as there'd be no trust benefit in that). */ - r = get_invocation_from_keyring(&saved_invocation_id); + if (r == -ENXIO) + /* The kernel keyring is relevant for system services (as for user services we don't + * store the invocation ID in the keyring, as there'd be no trust benefit in that). */ + r = get_invocation_from_keyring(&saved_invocation_id); if (r < 0) return r; + + if (sd_id128_is_null(saved_invocation_id)) + return -ENOMEDIUM; } - *ret = saved_invocation_id; + if (ret) + *ret = saved_invocation_id; return 0; } |