summaryrefslogtreecommitdiffstats
path: root/src/libsystemd/sd-id128
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystemd/sd-id128')
-rw-r--r--src/libsystemd/sd-id128/id128-util.c82
-rw-r--r--src/libsystemd/sd-id128/id128-util.h3
-rw-r--r--src/libsystemd/sd-id128/sd-id128.c52
3 files changed, 108 insertions, 29 deletions
diff --git a/src/libsystemd/sd-id128/id128-util.c b/src/libsystemd/sd-id128/id128-util.c
index b9714ee..298d21e 100644
--- a/src/libsystemd/sd-id128/id128-util.c
+++ b/src/libsystemd/sd-id128/id128-util.c
@@ -9,9 +9,12 @@
#include "hexdecoct.h"
#include "id128-util.h"
#include "io-util.h"
+#include "namespace-util.h"
+#include "process-util.h"
#include "sha256.h"
#include "stdio-util.h"
#include "string-util.h"
+#include "strv.h"
#include "sync-util.h"
#include "virt.h"
@@ -192,11 +195,11 @@ int id128_write_at(int dir_fd, const char *path, Id128Flag f, sd_id128_t id) {
}
void id128_hash_func(const sd_id128_t *p, struct siphash *state) {
- siphash24_compress(p, sizeof(sd_id128_t), state);
+ siphash24_compress_typesafe(*p, state);
}
int id128_compare_func(const sd_id128_t *a, const sd_id128_t *b) {
- return memcmp(a, b, 16);
+ return memcmp(a, b, sizeof(sd_id128_t));
}
sd_id128_t id128_make_v4_uuid(sd_id128_t id) {
@@ -231,11 +234,15 @@ int id128_get_product(sd_id128_t *ret) {
* of the host */
return -ENOENT;
- r = id128_read("/sys/class/dmi/id/product_uuid", ID128_FORMAT_UUID, &uuid);
- if (r == -ENOENT)
- r = id128_read("/proc/device-tree/vm,uuid", ID128_FORMAT_UUID, &uuid);
- if (r == -ENOENT)
- r = id128_read("/sys/hypervisor/uuid", ID128_FORMAT_UUID, &uuid);
+ FOREACH_STRING(i,
+ "/sys/class/dmi/id/product_uuid", /* KVM */
+ "/proc/device-tree/vm,uuid", /* Device tree */
+ "/sys/hypervisor/uuid") { /* Xen */
+
+ r = id128_read(i, ID128_FORMAT_UUID, &uuid);
+ if (r != -ENOENT)
+ break;
+ }
if (r < 0)
return r;
@@ -263,3 +270,64 @@ sd_id128_t id128_digest(const void *data, size_t size) {
return id128_make_v4_uuid(id);
}
+
+int id128_get_boot_for_machine(const char *machine, sd_id128_t *ret) {
+ _cleanup_close_ int pidnsfd = -EBADF, mntnsfd = -EBADF, rootfd = -EBADF;
+ _cleanup_close_pair_ int pair[2] = EBADF_PAIR;
+ pid_t pid, child;
+ sd_id128_t id;
+ ssize_t k;
+ int r;
+
+ assert(ret);
+
+ if (isempty(machine))
+ return sd_id128_get_boot(ret);
+
+ r = container_get_leader(machine, &pid);
+ if (r < 0)
+ return r;
+
+ r = namespace_open(pid, &pidnsfd, &mntnsfd, /* ret_netns_fd = */ NULL, /* ret_userns_fd = */ NULL, &rootfd);
+ if (r < 0)
+ return r;
+
+ if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
+ return -errno;
+
+ r = namespace_fork("(sd-bootidns)", "(sd-bootid)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL,
+ pidnsfd, mntnsfd, -1, -1, rootfd, &child);
+ if (r < 0)
+ return r;
+ if (r == 0) {
+ pair[0] = safe_close(pair[0]);
+
+ r = id128_get_boot(&id);
+ if (r < 0)
+ _exit(EXIT_FAILURE);
+
+ k = send(pair[1], &id, sizeof(id), MSG_NOSIGNAL);
+ if (k != sizeof(id))
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ pair[1] = safe_close(pair[1]);
+
+ r = wait_for_terminate_and_check("(sd-bootidns)", child, 0);
+ if (r < 0)
+ return r;
+ if (r != EXIT_SUCCESS)
+ return -EIO;
+
+ k = recv(pair[0], &id, sizeof(id), 0);
+ if (k != sizeof(id))
+ return -EIO;
+
+ if (sd_id128_is_null(id))
+ return -EIO;
+
+ *ret = id;
+ return 0;
+}
diff --git a/src/libsystemd/sd-id128/id128-util.h b/src/libsystemd/sd-id128/id128-util.h
index 53ba50a..458d430 100644
--- a/src/libsystemd/sd-id128/id128-util.h
+++ b/src/libsystemd/sd-id128/id128-util.h
@@ -49,6 +49,9 @@ int id128_get_product(sd_id128_t *ret);
sd_id128_t id128_digest(const void *data, size_t size);
+int id128_get_boot(sd_id128_t *ret);
+int id128_get_boot_for_machine(const char *machine, sd_id128_t *ret);
+
/* A helper to check for the three relevant cases of "machine ID not initialized" */
#define ERRNO_IS_NEG_MACHINE_ID_UNSET(r) \
IN_SET(r, \
diff --git a/src/libsystemd/sd-id128/sd-id128.c b/src/libsystemd/sd-id128/sd-id128.c
index 9fda79a..fc1107b 100644
--- a/src/libsystemd/sd-id128/sd-id128.c
+++ b/src/libsystemd/sd-id128/sd-id128.c
@@ -13,6 +13,7 @@
#include "hmac.h"
#include "id128-util.h"
#include "io-util.h"
+#include "keyring-util.h"
#include "macro.h"
#include "missing_syscall.h"
#include "missing_threads.h"
@@ -170,14 +171,24 @@ int id128_get_machine(const char *root, sd_id128_t *ret) {
return id128_read_fd(fd, ID128_FORMAT_PLAIN | ID128_REFUSE_NULL, ret);
}
+int id128_get_boot(sd_id128_t *ret) {
+ int r;
+
+ assert(ret);
+
+ r = id128_read("/proc/sys/kernel/random/boot_id", ID128_FORMAT_UUID | ID128_REFUSE_NULL, ret);
+ if (r == -ENOENT && proc_mounted() == 0)
+ return -ENOSYS;
+
+ return r;
+}
+
_public_ int sd_id128_get_boot(sd_id128_t *ret) {
static thread_local sd_id128_t saved_boot_id = {};
int r;
if (sd_id128_is_null(saved_boot_id)) {
- r = id128_read("/proc/sys/kernel/random/boot_id", ID128_FORMAT_UUID | ID128_REFUSE_NULL, &saved_boot_id);
- if (r == -ENOENT && proc_mounted() == 0)
- return -ENOSYS;
+ r = id128_get_boot(&saved_boot_id);
if (r < 0)
return r;
}
@@ -192,7 +203,6 @@ static int get_invocation_from_keyring(sd_id128_t *ret) {
char *d, *p, *g, *u, *e;
unsigned long perms;
key_serial_t key;
- size_t sz = 256;
uid_t uid;
gid_t gid;
int r, c;
@@ -211,24 +221,9 @@ static int get_invocation_from_keyring(sd_id128_t *ret) {
return -errno;
}
- for (;;) {
- description = new(char, sz);
- if (!description)
- return -ENOMEM;
-
- c = keyctl(KEYCTL_DESCRIBE, key, (unsigned long) description, sz, 0);
- if (c < 0)
- return -errno;
-
- if ((size_t) c <= sz)
- break;
-
- sz = c;
- free(description);
- }
-
- /* The kernel returns a final NUL in the string, verify that. */
- assert(description[c-1] == 0);
+ r = keyring_describe(key, &description);
+ if (r < 0)
+ return r;
/* Chop off the final description string */
d = strrchr(description, ';');
@@ -380,3 +375,16 @@ _public_ int sd_id128_get_boot_app_specific(sd_id128_t app_id, sd_id128_t *ret)
return sd_id128_get_app_specific(id, app_id, ret);
}
+
+_public_ int sd_id128_get_invocation_app_specific(sd_id128_t app_id, sd_id128_t *ret) {
+ sd_id128_t id;
+ int r;
+
+ assert_return(ret, -EINVAL);
+
+ r = sd_id128_get_invocation(&id);
+ if (r < 0)
+ return r;
+
+ return sd_id128_get_app_specific(id, app_id, ret);
+}