Skip to content
55 changes: 53 additions & 2 deletions src/flb_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -2043,13 +2043,39 @@ static int machine_id_read_and_sanitize(char *path,
return 0;
}

int write_uuid_to_file(char* filename, char* uuid) {
int fd;
size_t uuid_len;

if (filename == NULL || uuid == NULL) {
return FLB_FALSE;
}

/* write uuid to file */
fd = flb_open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666);
if (fd == -1) {
return FLB_FALSE;
}

uuid_len = strlen(uuid);

if (flb_write(fd, uuid, uuid_len) != uuid_len) {
flb_close(fd);
return FLB_FALSE;
}

flb_close(fd);
return FLB_TRUE;
}

int flb_utils_get_machine_id(char **out_id, size_t *out_size)
{
int ret;
char *id;
size_t bytes;
char *uuid;
int fallback = FLB_FALSE;
char *fallback_id_file = "machine-id"; //should reside in current working directory
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fallback file path is unreliable — use an absolute or well-known directory.

Using "machine-id" without a directory path means the file will be created in the current working directory, which is unpredictable and environment-dependent. This can lead to:

  • Permission denied errors in restricted directories
  • Files scattered across unexpected locations
  • Inability to persist the machine-id reliably across restarts

Consider using a well-defined location such as /var/lib/fluent-bit/machine-id, /tmp/fluent-bit-machine-id, or a configurable path.

Example fix:

-    char *fallback_id_file = "machine-id";           //should reside in current working directory
+    char *fallback_id_file = "/var/lib/fluent-bit/machine-id";

Note: You may need to ensure the directory exists or handle directory creation.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
char *fallback_id_file = "machine-id"; //should reside in current working directory
char *fallback_id_file = "/var/lib/fluent-bit/machine-id";
🤖 Prompt for AI Agents
In src/flb_utils.c around line 2078, the hardcoded fallback filename
"machine-id" is unreliable because it creates files in the current working
directory; change it to use a well-defined absolute path or a configurable
location (e.g. /var/lib/fluent-bit/machine-id or /tmp/fluent-bit-machine-id),
ensure the directory exists (create it if necessary with safe permissions), fall
back to a safe temp location if creation fails, and expose the path as a
configurable option so callers can override it.


#ifdef __linux__
char *dbus_var = "/var/lib/dbus/machine-id";
Expand Down Expand Up @@ -2084,6 +2110,24 @@ int flb_utils_get_machine_id(char **out_id, size_t *out_size)
return 0;
}
}

if (access(fallback_id_file, F_OK) == 0)
{
ret = machine_id_read_and_sanitize(fallback_id_file, &id, &bytes);
if(ret == 0)
{
if (bytes == 0) {
/* guid is somewhat corrupted */
fallback = FLB_TRUE;
goto fallback;
}
}

*out_id = id;
*out_size = bytes;
return 0;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Guard against failed read of fallback machine-id file

When the fallback machine-id file exists but machine_id_read_and_sanitize() returns an error (for example due to permissions or a short read), the code still writes *out_id = id; and *out_size = bytes; even though id/bytes were never assigned. This returns an uninitialized pointer to callers and can lead to crashes or undefined behaviour. The outputs should only be filled after a successful read or the flow should jump to the fallback generation path.

Useful? React with 👍 / 👎.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see this argument, but it should apply for other locations (dbus_var and dbus_etc) as well?
Also testing for bytes==0 does not include any ids with shorter length (what if the file was not written fully?)

I need to check if machine-id files are always in the same format and length.

Comment on lines +2123 to +2127

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Return uninitialized fallback ID on read failure

If a fallback machine-id file exists but machine_id_read_and_sanitize fails (e.g., unreadable or malformed), ret remains non‑zero yet the code still assigns id/bytes to the outputs and returns success because the return block sits outside the ret == 0 guard. In that scenario id and bytes are uninitialized, so callers can receive a garbage pointer/size or crash instead of regenerating an ID. The return should stay within the successful read path or jump to the fallback path when the read fails.

Useful? React with 👍 / 👎.

}

#elif defined(__FreeBSD__) || defined(__NetBSD__) || \
defined(__OpenBSD__) || defined(__DragonFly__)

Expand Down Expand Up @@ -2175,7 +2219,7 @@ int flb_utils_get_machine_id(char **out_id, size_t *out_size)
#endif

fallback:

flb_warn("falling back on random machine UUID");

/* generate a random uuid */
Expand All @@ -2185,15 +2229,22 @@ int flb_utils_get_machine_id(char **out_id, size_t *out_size)
return -1;
}
ret = flb_utils_uuid_v4_gen(uuid);

if (ret == 0) {

ret = write_uuid_to_file(fallback_id_file, uuid);
if (ret != 0){
//writing failed, next uuid generation will be random again
//write a message and return
flb_warn("failed to write machine-id to file %s", fallback_id_file);
}
*out_id = uuid;
*out_size = strlen(uuid);
if (fallback == FLB_TRUE) {
return 2;
}
return 0;
}

return -1;
}

Expand Down