From 3043f16d66bf5a1d754bc34323d84d9a048c6cf4 Mon Sep 17 00:00:00 2001 From: Jan Beich Date: Mon, 28 Sep 2020 05:14:52 +0000 Subject: [PATCH] util: mimic KCMP_FILE via KERN_FILE on DragonFly and FreeBSD Iterate over all file descriptors and compare their kernel addresses. Reviewed-by: Emmanuel Vadot Reviewed-by: Val Packett --- src/util/os_file.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/util/os_file.c b/src/util/os_file.c index 5fb30f2d9084f..f3e1a1ff6f36f 100644 --- a/src/util/os_file.c +++ b/src/util/os_file.c @@ -214,6 +214,58 @@ os_same_file_description(int fd1, int fd2) return syscall(SYS_kcmp, pid, pid, KCMP_FILE, fd1, fd2); } +#elif DETECT_OS_DRAGONFLY || DETECT_OS_FREEBSD + +#include "macros.h" /* ARRAY_SIZE */ + +#include +#if DETECT_OS_DRAGONFLY +#include +typedef void *kvaddr_t; +#elif DETECT_OS_FREEBSD +#include +#define kinfo_file xfile +#define f_pid xf_pid +#define f_fd xf_fd +#define f_file xf_file +#endif + +int +os_same_file_description(int fd1, int fd2) +{ + /* Same file descriptor trivially implies same file description */ + if (fd1 == fd2) + return 0; + + int mib[] = { CTL_KERN, KERN_FILE }; + size_t len; + if (sysctl(mib, ARRAY_SIZE(mib), NULL, &len, NULL, 0)) + return -1; + struct kinfo_file *kf = malloc(len); + if (sysctl(mib, ARRAY_SIZE(mib), kf, &len, NULL, 0)) + return -1; + + int count = len / sizeof(*kf); + pid_t pid = getpid(); + kvaddr_t fd1_kfile = 0, fd2_kfile = 0; + for (int i = 0; i < count; i++) { + if (pid == kf[i].f_pid) { + if (fd1 == kf[i].f_fd) { + fd1_kfile = kf[i].f_file; + } + if (fd2 == kf[i].f_fd) { + fd2_kfile = kf[i].f_file; + } + } + } + free(kf); + + if (fd1_kfile == 0 || fd2_kfile == 0) + return -1; + + return (fd1_kfile < fd2_kfile) | ((fd1_kfile > fd2_kfile) << 1); +} + #else int -- GitLab