summaryrefslogtreecommitdiff
path: root/src/libnm-systemd-core/src/libsystemd/sd-id128/sd-id128.c
diff options
context:
space:
mode:
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.c81
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;
}