Skip to content

Commit 9c519b6

Browse files
committed
fix(daemon): add native FreeBSD process-image identity support
Extends runtime_process_image_reference_* to support FreeBSD process image discovery and comparison. Previously this functionality was guarded only for _WIN32, __APPLE__, and __linux__. Uses sysctl(KERN_PROC_PATHNAME) to resolve a process's executable path without depending on procfs. Renames runtime_linux_stat_same_image to runtime_posix_stat_same_image now that the same comparison logic serves Linux, macOS, and FreeBSD. Signed-off-by: Pedro Ramos <131530838+pr9000@users.noreply.github.com>
1 parent 92b8298 commit 9c519b6

1 file changed

Lines changed: 43 additions & 12 deletions

File tree

‎src/daemon/runtime.c‎

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,14 @@
3030
#include <sys/proc_info.h>
3131
#include <sys/stat.h>
3232
#include <unistd.h>
33-
#elif defined(__linux__)
33+
#elif defined(__linux__) || defined(__FreeBSD__)
3434
#include <fcntl.h>
3535
#include <sys/stat.h>
3636
#include <unistd.h>
37+
#if defined(__FreeBSD__)
38+
#include <sys/types.h>
39+
#include <sys/sysctl.h>
40+
#endif
3741
#endif
3842

3943
enum {
@@ -135,7 +139,7 @@ typedef struct {
135139
HANDLE file;
136140
BY_HANDLE_FILE_INFORMATION information;
137141
LARGE_INTEGER size;
138-
#elif defined(__APPLE__) || defined(__linux__)
142+
#elif defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__)
139143
int fd;
140144
struct stat status;
141145
#endif
@@ -490,7 +494,7 @@ static bool runtime_activation_response_decode(
490494
static uint64_t runtime_current_process_id(void) {
491495
#ifdef _WIN32
492496
return (uint64_t)GetCurrentProcessId();
493-
#elif defined(__APPLE__) || defined(__linux__)
497+
#elif defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__)
494498
return (uint64_t)getpid();
495499
#else
496500
return 0;
@@ -504,7 +508,7 @@ static void runtime_process_image_reference_init(runtime_process_image_reference
504508
memset(reference, 0, sizeof(*reference));
505509
#ifdef _WIN32
506510
reference->file = INVALID_HANDLE_VALUE;
507-
#elif defined(__APPLE__) || defined(__linux__)
511+
#elif defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__)
508512
reference->fd = -1;
509513
#endif
510514
}
@@ -518,7 +522,7 @@ static bool runtime_process_image_reference_release(runtime_process_image_refere
518522
if (reference->file != INVALID_HANDLE_VALUE && !CloseHandle(reference->file)) {
519523
ok = false;
520524
}
521-
#elif defined(__APPLE__) || defined(__linux__)
525+
#elif defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__)
522526
if (reference->fd >= 0 && close(reference->fd) != 0) {
523527
ok = false;
524528
}
@@ -658,9 +662,9 @@ static bool runtime_mac_process_maps_file_executable(int process_id, const struc
658662
return false;
659663
}
660664

661-
#elif defined(__linux__)
665+
#elif defined(__linux__) || defined(__FreeBSD__)
662666

663-
static bool runtime_linux_stat_same_image(const struct stat *first, const struct stat *second) {
667+
static bool runtime_posix_stat_same_image(const struct stat *first, const struct stat *second) {
664668
return first && second && S_ISREG(first->st_mode) && S_ISREG(second->st_mode) &&
665669
first->st_dev == second->st_dev && first->st_ino == second->st_ino &&
666670
first->st_size == second->st_size && first->st_mtim.tv_sec == second->st_mtim.tv_sec &&
@@ -769,11 +773,11 @@ static bool runtime_process_image_reference_acquire(
769773
(!fingerprint ||
770774
cbm_daemon_build_fingerprint_native_file((uintptr_t)image_fd, fingerprint)) &&
771775
fstat(image_fd, &image_after) == 0 &&
772-
runtime_linux_stat_same_image(&image_before, &image_after);
776+
runtime_posix_stat_same_image(&image_before, &image_after);
773777
int verify_fd = ok ? openat(process_fd, "exe", O_RDONLY | O_CLOEXEC) : -1;
774778
struct stat verify_status;
775779
ok = ok && verify_fd >= 0 && fstat(verify_fd, &verify_status) == 0 &&
776-
runtime_linux_stat_same_image(&image_after, &verify_status);
780+
runtime_posix_stat_same_image(&image_after, &verify_status);
777781
if (verify_fd >= 0 && close(verify_fd) != 0) {
778782
ok = false;
779783
}
@@ -787,6 +791,33 @@ static bool runtime_process_image_reference_acquire(
787791
} else if (image_fd >= 0) {
788792
(void)close(image_fd);
789793
}
794+
#elif defined(__FreeBSD__)
795+
if (process_id > INT_MAX) {
796+
return false;
797+
}
798+
int pid = (int)process_id;
799+
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, pid};
800+
char path[PATH_MAX];
801+
size_t path_length = sizeof(path);
802+
bool ok = sysctl(mib, 4, path, &path_length, NULL, 0) == 0 && path_length > 0;
803+
if (ok) {
804+
path[path_length < sizeof(path) ? path_length : sizeof(path) - 1] = '\0';
805+
}
806+
int image_fd = ok ? open(path, O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK) : -1;
807+
struct stat image_before;
808+
struct stat image_after;
809+
ok = image_fd >= 0 && fstat(image_fd, &image_before) == 0 && S_ISREG(image_before.st_mode) &&
810+
(!fingerprint ||
811+
cbm_daemon_build_fingerprint_native_file((uintptr_t)image_fd, fingerprint)) &&
812+
fstat(image_fd, &image_after) == 0 &&
813+
runtime_posix_stat_same_image(&image_before, &image_after);
814+
if (ok) {
815+
reference->held = true;
816+
reference->fd = image_fd;
817+
reference->status = image_after;
818+
} else if (image_fd >= 0) {
819+
(void)close(image_fd);
820+
}
790821
#else
791822
(void)process_id;
792823
bool ok = false;
@@ -827,14 +858,14 @@ static bool runtime_process_image_reference_matches_process(
827858
runtime_mac_stat_same(&active->status, &peer.status);
828859
bool released = runtime_process_image_reference_release(&peer);
829860
return same && released;
830-
#elif defined(__linux__)
861+
#elif defined(__linux__) || defined(__FreeBSD__)
831862
runtime_process_image_reference_t peer;
832863
runtime_process_image_reference_init(&peer);
833864
bool same = runtime_process_image_reference_acquire(process_id, &peer, NULL);
834865
struct stat active_now;
835866
same = same && fstat(active->fd, &active_now) == 0 &&
836-
runtime_linux_stat_same_image(&active->status, &active_now) &&
837-
runtime_linux_stat_same_image(&active->status, &peer.status);
867+
runtime_posix_stat_same_image(&active->status, &active_now) &&
868+
runtime_posix_stat_same_image(&active->status, &peer.status);
838869
bool released = runtime_process_image_reference_release(&peer);
839870
return same && released;
840871
#else

0 commit comments

Comments
 (0)