Skip to content

Commit 46d5717

Browse files
committed
Implement entity_id. Issue #155
This implements the 12 byte entity id as defined in https://www.elastic.co/docs/reference/ecs/ecs-process#field-process-entity-id We can't depend on dynamic linking of md or openssl, so include a standlone MIT licensed sha256 implementation from https://github.com/ilvn/SHA256, they claim to be formally verified, so that's something. We now also have to link against resolv so we can get the base64 functions, that's ok, beats already links against it. This is a WIP as I want to make sure we compute the very same entity_id as gosysinfo and friends.
1 parent c08b0eb commit 46d5717

File tree

5 files changed

+478
-1
lines changed

5 files changed

+478
-1
lines changed

Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ LIBQUARK_SRCS:= \
9393
compat.c \
9494
kprobe_queue.c \
9595
quark.c \
96-
qutil.c
96+
qutil.c \
97+
sha256.c
9798
LIBQUARK_OBJS:= $(patsubst %.c,%.o,$(LIBQUARK_SRCS))
9899
LIBQUARK_STATIC:= libquark.a
99100
LIBQUARK_STATIC_BIG:= libquark_big.a
@@ -106,6 +107,9 @@ LIBQUARK_TARGET=$(LIBQUARK_STATIC)
106107
EXTRA_LDFLAGS+= -lbpf
107108
endif
108109

110+
# for b64_ntop()
111+
EXTRA_LDFLAGS+= -lresolv
112+
109113
# ZLIB
110114
ZLIB_SRC:= zlib
111115
ZLIB_FILES:= $(shell find $(ZLIB_SRC) \(\

quark.c

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <fcntl.h>
1717
#include <fts.h>
1818
#include <limits.h>
19+
#include <resolv.h> /* for b64_ntop */
1920
#include <stdarg.h>
2021
#include <stdio.h>
2122
#include <stdlib.h>
@@ -62,6 +63,7 @@ RB_GENERATE(raw_event_by_pidtime, raw_event,
6263
struct quark {
6364
unsigned int hz;
6465
u64 boottime;
66+
char machine_id[1024];
6567
} quark;
6668

6769
struct raw_event *
@@ -444,6 +446,43 @@ process_by_pid_cmp(struct quark_process *a, struct quark_process *b)
444446
return (0);
445447
}
446448

449+
static void
450+
process_entity_id(struct quark_queue *qq, struct quark_process *qp)
451+
{
452+
sha256_context ctx;
453+
u64 pid64_le, start_le;
454+
u8 digest[SHA256_SIZE_BYTES];
455+
char digest_p[45];
456+
size_t machine_len;
457+
458+
/* No proc_time_boot, bail */
459+
if ((qp->flags & QUARK_F_PROC) == 0)
460+
return;
461+
/* Already known, bail */
462+
if (qp->flags & QUARK_F_ENTITYID)
463+
return;
464+
/* No machine_id, bail */
465+
if ((machine_len = strlen(quark.machine_id)) == 0)
466+
return;
467+
468+
/* Historically little endian */
469+
pid64_le = htole64(qp->pid);
470+
start_le = htole64(qp->proc_time_boot);
471+
472+
sha256_init(&ctx);
473+
sha256_hash(&ctx, quark.machine_id, machine_len);
474+
sha256_hash(&ctx, &pid64_le, sizeof(pid64_le));
475+
sha256_hash(&ctx, &start_le, sizeof(start_le));
476+
sha256_done(&ctx, digest);
477+
478+
b64_ntop(digest, sizeof(digest), digest_p, sizeof(digest_p));
479+
digest_p[sizeof(digest_p) - 1] = 0;
480+
481+
/* Let it truncate, entity_id is only 12 bytes */
482+
(void)strlcpy(qp->entity_id, digest_p, sizeof(qp->entity_id));
483+
qp->flags |= QUARK_F_ENTITYID;
484+
}
485+
447486
/*
448487
* Socket stuff
449488
*/
@@ -580,6 +619,8 @@ event_flag_str(u64 flag)
580619
return "CMDLINE";
581620
case QUARK_F_CWD:
582621
return "CWD";
622+
case QUARK_F_ENTITYID:
623+
return "EID";
583624
default:
584625
return "?";
585626
}
@@ -1012,6 +1053,10 @@ quark_event_dump(const struct quark_event *qev, FILE *f)
10121053
entry_leader_type_str(qp->proc_entry_leader_type),
10131054
qp->proc_entry_leader);
10141055
}
1056+
if (qp->flags & QUARK_F_ENTITYID) {
1057+
flagname = event_flag_str(QUARK_F_ENTITYID);
1058+
P(" %.4s\tentity_id=%s\n", flagname, qp->entity_id);
1059+
}
10151060
if (qp->flags & QUARK_F_CWD) {
10161061
flagname = event_flag_str(QUARK_F_CWD);
10171062
P(" %.4s\tcwd=%s\n", flagname, qp->cwd);
@@ -1258,6 +1303,9 @@ raw_event_process(struct quark_queue *qq, struct raw_event *src)
12581303

12591304
/* Don't set cwd as it's not valid on exit */
12601305
comm = raw_task->comm;
1306+
1307+
/* Depends on QUARK_F_PROC, idempotent */
1308+
process_entity_id(qq, qp);
12611309
}
12621310
if (raw_comm != NULL)
12631311
comm = raw_comm->comm; /* raw_comm always overrides */
@@ -1968,6 +2016,39 @@ fetch_boottime(void)
19682016
return (btime * NS_PER_S);
19692017
}
19702018

2019+
static int
2020+
fetch_machine_id(char *buf, size_t len)
2021+
{
2022+
int fd;
2023+
char *id;
2024+
const char **path, *all_paths[] = {
2025+
"/etc/machine-id",
2026+
"/var/lib/dbus/machine-id",
2027+
"/var/db/dbus/machine-id",
2028+
NULL
2029+
};
2030+
2031+
for (fd = -1, path = all_paths; *path != NULL; path++) {
2032+
fd = open("/etc/machine-id", O_RDONLY);
2033+
if (fd != -1)
2034+
break;
2035+
}
2036+
if (fd == -1)
2037+
return (-1);
2038+
/* Historically the final newline is included, so keep it. */
2039+
if ((id = load_file_nostat(fd, NULL)) == NULL) {
2040+
close(fd);
2041+
warnx("can't load machine_id");
2042+
return (-1);
2043+
}
2044+
close(fd);
2045+
2046+
if (strlcpy(buf, id, len) >= len)
2047+
warnx("machine_id truncated, ignoring");
2048+
2049+
return (0);
2050+
}
2051+
19712052
/*
19722053
* Aggregation is a relationship between a parent event and a child event. In a
19732054
* fork+exec cenario, fork is the parent, exec is the child.
@@ -2028,6 +2109,12 @@ quark_init(void)
20282109
qwarn("can't fetch btime");
20292110
return (-1);
20302111
}
2112+
if (fetch_machine_id(quark.machine_id,
2113+
sizeof(quark.machine_id)) == -1) {
2114+
qwarn("can't fetch machine id, ignoring");
2115+
quark.machine_id[0] = 0;
2116+
}
2117+
20312118
quark.hz = hz;
20322119
quark.boottime = boottime;
20332120

quark.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
/* Compat, tree.h, queue.h */
1818
#include "compat.h"
1919

20+
/* sha256 since we can't link against openssl */
21+
#include "sha256.h"
22+
2023
/* Misc */
2124
#ifndef ALIGN_UP
2225
#define ALIGN_UP(_p, _b) (((u64)(_p) + ((_b) - 1)) & ~((_b) - 1))
@@ -381,6 +384,7 @@ struct quark_process {
381384
#define QUARK_F_FILENAME (1 << 3)
382385
#define QUARK_F_CMDLINE (1 << 4)
383386
#define QUARK_F_CWD (1 << 5)
387+
#define QUARK_F_ENTITYID (1 << 6)
384388
u64 flags;
385389

386390
/* QUARK_F_PROC */
@@ -419,6 +423,8 @@ struct quark_process {
419423
char *cmdline;
420424
/* QUARK_F_CWD */
421425
char *cwd;
426+
/* QUARK_F_ENTITY_ID */
427+
char entity_id[13];
422428
};
423429

424430
struct quark_process_iter {

0 commit comments

Comments
 (0)