Skip to content

Commit f481289

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 f481289

File tree

5 files changed

+479
-1
lines changed

5 files changed

+479
-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: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#include <fcntl.h>
1717
#include <fts.h>
1818
#include <limits.h>
19+
#include <resolv.h> /* for b64_ntop */
20+
#include <sha2.h>
1921
#include <stdarg.h>
2022
#include <stdio.h>
2123
#include <stdlib.h>
@@ -62,6 +64,7 @@ RB_GENERATE(raw_event_by_pidtime, raw_event,
6264
struct quark {
6365
unsigned int hz;
6466
u64 boottime;
67+
char machine_id[1024];
6568
} quark;
6669

6770
struct raw_event *
@@ -444,6 +447,43 @@ process_by_pid_cmp(struct quark_process *a, struct quark_process *b)
444447
return (0);
445448
}
446449

450+
static void
451+
process_entity_id(struct quark_queue *qq, struct quark_process *qp)
452+
{
453+
sha256_context ctx;
454+
u64 pid64_le, start_le;
455+
u8 digest[SHA256_SIZE_BYTES];
456+
char digest_p[45];
457+
size_t machine_len;
458+
459+
/* No proc_time_boot, bail */
460+
if ((qp->flags & QUARK_F_PROC) == 0)
461+
return;
462+
/* Already known, bail */
463+
if (qp->flags & QUARK_F_ENTITYID)
464+
return;
465+
/* No machine_id, bail */
466+
if ((machine_len = strlen(quark.machine_id)) == 0)
467+
return;
468+
469+
/* Historically little endian */
470+
pid64_le = htole64(qp->pid);
471+
start_le = htole64(qp->proc_time_boot);
472+
473+
sha256_init(&ctx);
474+
sha256_hash(&ctx, quark.machine_id, machine_len);
475+
sha256_hash(&ctx, &pid64_le, sizeof(pid64_le));
476+
sha256_hash(&ctx, &start_le, sizeof(start_le));
477+
sha256_done(&ctx, digest);
478+
479+
b64_ntop(digest, sizeof(digest), digest_p, sizeof(digest_p));
480+
digest_p[sizeof(digest_p) - 1] = 0;
481+
482+
/* Let it truncate, entity_id is only 12 bytes */
483+
(void)strlcpy(qp->entity_id, digest_p, sizeof(qp->entity_id));
484+
qp->flags |= QUARK_F_ENTITYID;
485+
}
486+
447487
/*
448488
* Socket stuff
449489
*/
@@ -580,6 +620,8 @@ event_flag_str(u64 flag)
580620
return "CMDLINE";
581621
case QUARK_F_CWD:
582622
return "CWD";
623+
case QUARK_F_ENTITYID:
624+
return "EID";
583625
default:
584626
return "?";
585627
}
@@ -1012,6 +1054,10 @@ quark_event_dump(const struct quark_event *qev, FILE *f)
10121054
entry_leader_type_str(qp->proc_entry_leader_type),
10131055
qp->proc_entry_leader);
10141056
}
1057+
if (qp->flags & QUARK_F_ENTITYID) {
1058+
flagname = event_flag_str(QUARK_F_ENTITYID);
1059+
P(" %.4s\tentity_id=%s\n", flagname, qp->entity_id);
1060+
}
10151061
if (qp->flags & QUARK_F_CWD) {
10161062
flagname = event_flag_str(QUARK_F_CWD);
10171063
P(" %.4s\tcwd=%s\n", flagname, qp->cwd);
@@ -1258,6 +1304,9 @@ raw_event_process(struct quark_queue *qq, struct raw_event *src)
12581304

12591305
/* Don't set cwd as it's not valid on exit */
12601306
comm = raw_task->comm;
1307+
1308+
/* Depends on QUARK_F_PROC, idempotent */
1309+
process_entity_id(qq, qp);
12611310
}
12621311
if (raw_comm != NULL)
12631312
comm = raw_comm->comm; /* raw_comm always overrides */
@@ -1968,6 +2017,39 @@ fetch_boottime(void)
19682017
return (btime * NS_PER_S);
19692018
}
19702019

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

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)