Skip to content

Commit 12b928a

Browse files
committed
fix(daemon): add native FreeBSD process-image identity support
Extends runtime_process_image_reference_* (self/peer process image acquisition and comparison) to FreeBSD, previously guarded only for _WIN32/__APPLE__/__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 33bb058 commit 12b928a

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
@@ -42,10 +42,14 @@ void cbm_daemon_runtime_force_peer_image_unverified_for_testing(bool force) {
4242
#include <sys/proc_info.h>
4343
#include <sys/stat.h>
4444
#include <unistd.h>
45-
#elif defined(__linux__)
45+
#elif defined(__linux__) || defined(__FreeBSD__)
4646
#include <fcntl.h>
4747
#include <sys/stat.h>
4848
#include <unistd.h>
49+
#if defined(__FreeBSD__)
50+
#include <sys/types.h>
51+
#include <sys/sysctl.h>
52+
#endif
4953
#endif
5054

5155
enum {
@@ -147,7 +151,7 @@ typedef struct {
147151
HANDLE file;
148152
BY_HANDLE_FILE_INFORMATION information;
149153
LARGE_INTEGER size;
150-
#elif defined(__APPLE__) || defined(__linux__)
154+
#elif defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__)
151155
int fd;
152156
struct stat status;
153157
#endif
@@ -502,7 +506,7 @@ static bool runtime_activation_response_decode(
502506
static uint64_t runtime_current_process_id(void) {
503507
#ifdef _WIN32
504508
return (uint64_t)GetCurrentProcessId();
505-
#elif defined(__APPLE__) || defined(__linux__)
509+
#elif defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__)
506510
return (uint64_t)getpid();
507511
#else
508512
return 0;
@@ -516,7 +520,7 @@ static void runtime_process_image_reference_init(runtime_process_image_reference
516520
memset(reference, 0, sizeof(*reference));
517521
#ifdef _WIN32
518522
reference->file = INVALID_HANDLE_VALUE;
519-
#elif defined(__APPLE__) || defined(__linux__)
523+
#elif defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__)
520524
reference->fd = -1;
521525
#endif
522526
}
@@ -530,7 +534,7 @@ static bool runtime_process_image_reference_release(runtime_process_image_refere
530534
if (reference->file != INVALID_HANDLE_VALUE && !CloseHandle(reference->file)) {
531535
ok = false;
532536
}
533-
#elif defined(__APPLE__) || defined(__linux__)
537+
#elif defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__)
534538
if (reference->fd >= 0 && close(reference->fd) != 0) {
535539
ok = false;
536540
}
@@ -670,9 +674,9 @@ static bool runtime_mac_process_maps_file_executable(int process_id, const struc
670674
return false;
671675
}
672676

673-
#elif defined(__linux__)
677+
#elif defined(__linux__) || defined(__FreeBSD__)
674678

675-
static bool runtime_linux_stat_same_image(const struct stat *first, const struct stat *second) {
679+
static bool runtime_posix_stat_same_image(const struct stat *first, const struct stat *second) {
676680
return first && second && S_ISREG(first->st_mode) && S_ISREG(second->st_mode) &&
677681
first->st_dev == second->st_dev && first->st_ino == second->st_ino &&
678682
first->st_size == second->st_size && first->st_mtim.tv_sec == second->st_mtim.tv_sec &&
@@ -788,11 +792,11 @@ static bool runtime_process_image_reference_acquire(
788792
(!fingerprint ||
789793
cbm_daemon_build_fingerprint_native_file((uintptr_t)image_fd, fingerprint)) &&
790794
fstat(image_fd, &image_after) == 0 &&
791-
runtime_linux_stat_same_image(&image_before, &image_after);
795+
runtime_posix_stat_same_image(&image_before, &image_after);
792796
int verify_fd = ok ? openat(process_fd, "exe", O_RDONLY | O_CLOEXEC) : -1;
793797
struct stat verify_status;
794798
ok = ok && verify_fd >= 0 && fstat(verify_fd, &verify_status) == 0 &&
795-
runtime_linux_stat_same_image(&image_after, &verify_status);
799+
runtime_posix_stat_same_image(&image_after, &verify_status);
796800
if (verify_fd >= 0 && close(verify_fd) != 0) {
797801
ok = false;
798802
}
@@ -806,6 +810,33 @@ static bool runtime_process_image_reference_acquire(
806810
} else if (image_fd >= 0) {
807811
(void)close(image_fd);
808812
}
813+
#elif defined(__FreeBSD__)
814+
if (process_id > INT_MAX) {
815+
return false;
816+
}
817+
int pid = (int)process_id;
818+
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, pid};
819+
char path[PATH_MAX];
820+
size_t path_length = sizeof(path);
821+
bool ok = sysctl(mib, 4, path, &path_length, NULL, 0) == 0 && path_length > 0;
822+
if (ok) {
823+
path[path_length < sizeof(path) ? path_length : sizeof(path) - 1] = '\0';
824+
}
825+
int image_fd = ok ? open(path, O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK) : -1;
826+
struct stat image_before;
827+
struct stat image_after;
828+
ok = image_fd >= 0 && fstat(image_fd, &image_before) == 0 && S_ISREG(image_before.st_mode) &&
829+
(!fingerprint ||
830+
cbm_daemon_build_fingerprint_native_file((uintptr_t)image_fd, fingerprint)) &&
831+
fstat(image_fd, &image_after) == 0 &&
832+
runtime_posix_stat_same_image(&image_before, &image_after);
833+
if (ok) {
834+
reference->held = true;
835+
reference->fd = image_fd;
836+
reference->status = image_after;
837+
} else if (image_fd >= 0) {
838+
(void)close(image_fd);
839+
}
809840
#else
810841
(void)process_id;
811842
bool ok = false;
@@ -846,14 +877,14 @@ static bool runtime_process_image_reference_matches_process(
846877
runtime_mac_stat_same(&active->status, &peer.status);
847878
bool released = runtime_process_image_reference_release(&peer);
848879
return same && released;
849-
#elif defined(__linux__)
880+
#elif defined(__linux__) || defined(__FreeBSD__)
850881
runtime_process_image_reference_t peer;
851882
runtime_process_image_reference_init(&peer);
852883
bool same = runtime_process_image_reference_acquire(process_id, &peer, NULL);
853884
struct stat active_now;
854885
same = same && fstat(active->fd, &active_now) == 0 &&
855-
runtime_linux_stat_same_image(&active->status, &active_now) &&
856-
runtime_linux_stat_same_image(&active->status, &peer.status);
886+
runtime_posix_stat_same_image(&active->status, &active_now) &&
887+
runtime_posix_stat_same_image(&active->status, &peer.status);
857888
bool released = runtime_process_image_reference_release(&peer);
858889
return same && released;
859890
#else

0 commit comments

Comments
 (0)