mirror of
https://github.com/valitydev/osquery-1.git
synced 2024-11-08 10:23:54 +00:00
Merge pull request #1327 from mofarrell/kernel-publishers
Publisher system for kernel events in the kernel extension.
This commit is contained in:
commit
9a67c18974
@ -26,6 +26,7 @@ if(APPLE)
|
|||||||
|
|
||||||
# Set OS X platform-specific include paths.
|
# Set OS X platform-specific include paths.
|
||||||
include_directories("${CMAKE_SOURCE_DIR}/kernel/include")
|
include_directories("${CMAKE_SOURCE_DIR}/kernel/include")
|
||||||
|
include_directories("${CMAKE_SOURCE_DIR}/kernel/src")
|
||||||
include_directories("/System/Library/Frameworks/Kernel.framework/Headers")
|
include_directories("/System/Library/Frameworks/Kernel.framework/Headers")
|
||||||
include_directories("/Applications/Xcode.app/Contents/Developer/Platforms/\
|
include_directories("/Applications/Xcode.app/Contents/Developer/Platforms/\
|
||||||
MacOSX.platform/Developer/SDKs/MacOSX${APPLE_MIN_ABI}.sdk\
|
MacOSX.platform/Developer/SDKs/MacOSX${APPLE_MIN_ABI}.sdk\
|
||||||
@ -59,16 +60,20 @@ endif()
|
|||||||
|
|
||||||
# The set of platform-agnostic implementations.
|
# The set of platform-agnostic implementations.
|
||||||
set(BASE_KERNEL_SOURCES
|
set(BASE_KERNEL_SOURCES
|
||||||
src/osquery.cpp
|
|
||||||
src/circular_queue_kern.c
|
src/circular_queue_kern.c
|
||||||
)
|
)
|
||||||
|
|
||||||
# TODO: Add a set of platform-specific files.
|
file(GLOB APPLE_KERNEL_PUBLISHER_SOURCES "src/publishers/darwin/*.c")
|
||||||
|
# Add a set of platform-specific files.
|
||||||
|
set(APPLE_KERNEL_SOURCES
|
||||||
|
src/osquery.cpp
|
||||||
|
${APPLE_KERNEL_PUBLISHER_SOURCES}
|
||||||
|
)
|
||||||
|
|
||||||
# Define kernel targets, each should be an extension/module.
|
# Define kernel targets, each should be an extension/module.
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
# TODO: Remove the OS X requirement.
|
# TODO: Remove the OS X requirement.
|
||||||
add_executable(base_kernel ${BASE_KERNEL_SOURCES})
|
add_executable(base_kernel ${APPLE_KERNEL_SOURCES} ${BASE_KERNEL_SOURCES})
|
||||||
set_target_properties(base_kernel PROPERTIES COMPILE_FLAGS ${KERNEL_C_FLAGS} ${KERNEL_CXX_FLAGS})
|
set_target_properties(base_kernel PROPERTIES COMPILE_FLAGS ${KERNEL_C_FLAGS} ${KERNEL_CXX_FLAGS})
|
||||||
set_target_properties(base_kernel PROPERTIES LINK_FLAGS ${KERNEL_LINKER_FLAGS})
|
set_target_properties(base_kernel PROPERTIES LINK_FLAGS ${KERNEL_LINKER_FLAGS})
|
||||||
set_target_properties(base_kernel PROPERTIES EXCLUDE_FROM_ALL true)
|
set_target_properties(base_kernel PROPERTIES EXCLUDE_FROM_ALL true)
|
||||||
|
@ -23,6 +23,19 @@
|
|||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** @brief Communication version between kernel and daemon.
|
||||||
|
*
|
||||||
|
* A daemon may only connect to a kernel with the same communication version.
|
||||||
|
* Bump this number when changing or adding any event structs.
|
||||||
|
*/
|
||||||
|
#define OSQUERY_KERNEL_COMMUNICATION_VERSION 1UL
|
||||||
|
#ifdef KERNEL_TEST
|
||||||
|
#define OSQUERY_KERNEL_COMM_VERSION \
|
||||||
|
(OSQUERY_KERNEL_COMMUNICATION_VERSION | (1UL << 63))
|
||||||
|
#else
|
||||||
|
#define OSQUERY_KERNEL_COMM_VERSION OSQUERY_KERNEL_COMMUNICATION_VERSION
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@ -36,7 +49,6 @@ extern "C" {
|
|||||||
* a reentrant testing IOCTL call that adds test events to the cqueue structure.
|
* a reentrant testing IOCTL call that adds test events to the cqueue structure.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Event feed types
|
// Event feed types
|
||||||
//
|
//
|
||||||
@ -51,7 +63,7 @@ typedef enum {
|
|||||||
OSQUERY_TEST_EVENT_1,
|
OSQUERY_TEST_EVENT_1,
|
||||||
#endif // KERNEL_TEST
|
#endif // KERNEL_TEST
|
||||||
|
|
||||||
OSQUERY_EVENT_NUM_EVENTS // Number of different event types.
|
OSQUERY_NUM_EVENTS // Number of different event types.
|
||||||
} osquery_event_t;
|
} osquery_event_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -122,6 +134,7 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
osquery_event_t event;
|
osquery_event_t event;
|
||||||
int subscribe;
|
int subscribe;
|
||||||
|
void *udata;
|
||||||
} osquery_subscription_args_t;
|
} osquery_subscription_args_t;
|
||||||
|
|
||||||
// Flags for buffer sync options.
|
// Flags for buffer sync options.
|
||||||
@ -138,6 +151,7 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
size_t size; // Size of shared user kernel buffer.
|
size_t size; // Size of shared user kernel buffer.
|
||||||
void *buffer; // (Output) Pointer to buffer location.
|
void *buffer; // (Output) Pointer to buffer location.
|
||||||
|
uint64_t version; // osquery kernel communication version.
|
||||||
} osquery_buf_allocate_args_t;
|
} osquery_buf_allocate_args_t;
|
||||||
|
|
||||||
// TODO: Choose a proper IOCTL num.
|
// TODO: Choose a proper IOCTL num.
|
||||||
|
@ -12,12 +12,8 @@
|
|||||||
#include <mach/mach_types.h>
|
#include <mach/mach_types.h>
|
||||||
|
|
||||||
#include <kern/debug.h>
|
#include <kern/debug.h>
|
||||||
#include <sys/vnode.h>
|
|
||||||
#include <sys/errno.h>
|
#include <sys/errno.h>
|
||||||
#include <sys/conf.h>
|
#include <sys/conf.h>
|
||||||
#include <sys/proc.h>
|
|
||||||
#include <sys/systm.h>
|
|
||||||
#include <sys/kauth.h>
|
|
||||||
#include <miscfs/devfs/devfs.h>
|
#include <miscfs/devfs/devfs.h>
|
||||||
#include <sys/vnode.h>
|
#include <sys/vnode.h>
|
||||||
|
|
||||||
@ -25,7 +21,7 @@
|
|||||||
#include <IOKit/IOMemoryDescriptor.h>
|
#include <IOKit/IOMemoryDescriptor.h>
|
||||||
#include <IOKit/IOLib.h>
|
#include <IOKit/IOLib.h>
|
||||||
|
|
||||||
#include <feeds.h>
|
#include "publishers.h"
|
||||||
|
|
||||||
#include "circular_queue_kern.h"
|
#include "circular_queue_kern.h"
|
||||||
|
|
||||||
@ -49,7 +45,6 @@ static struct {
|
|||||||
void *devfs;
|
void *devfs;
|
||||||
int major_number;
|
int major_number;
|
||||||
int open_count;
|
int open_count;
|
||||||
kauth_listener_t fileop_listener;
|
|
||||||
|
|
||||||
lck_grp_attr_t *lck_grp_attr;
|
lck_grp_attr_t *lck_grp_attr;
|
||||||
lck_grp_t *lck_grp;
|
lck_grp_t *lck_grp;
|
||||||
@ -65,68 +60,6 @@ static struct {
|
|||||||
.major_number = OSQUERY_MAJOR
|
.major_number = OSQUERY_MAJOR
|
||||||
};
|
};
|
||||||
|
|
||||||
static int fileop_scope_callback(kauth_cred_t credential,
|
|
||||||
void *idata,
|
|
||||||
kauth_action_t action,
|
|
||||||
uintptr_t arg0,
|
|
||||||
uintptr_t arg1,
|
|
||||||
uintptr_t arg2,
|
|
||||||
uintptr_t arg3) {
|
|
||||||
vnode_t vp = (vnode_t)arg0;
|
|
||||||
if (action == KAUTH_FILEOP_EXEC && vp != NULL) {
|
|
||||||
// Someone is executing a file.
|
|
||||||
int path_len = MAXPATHLEN;
|
|
||||||
|
|
||||||
osquery_process_event_t *e =
|
|
||||||
(osquery_process_event_t *)osquery_cqueue_reserve(&osquery.cqueue,
|
|
||||||
OSQUERY_PROCESS_EVENT);
|
|
||||||
if (e == NULL) {
|
|
||||||
// Failed to reserve space for the event.
|
|
||||||
return KAUTH_RESULT_DEFER;
|
|
||||||
}
|
|
||||||
e->pid = proc_selfpid();
|
|
||||||
e->ppid = proc_selfppid();
|
|
||||||
e->owner_uid = 0;
|
|
||||||
e->owner_gid = 0;
|
|
||||||
e->mode = -1;
|
|
||||||
vfs_context_t context = vfs_context_create(NULL);
|
|
||||||
if (context) {
|
|
||||||
struct vnode_attr vattr = {0};
|
|
||||||
VATTR_INIT(&vattr);
|
|
||||||
VATTR_WANTED(&vattr, va_uid);
|
|
||||||
VATTR_WANTED(&vattr, va_gid);
|
|
||||||
VATTR_WANTED(&vattr, va_mode);
|
|
||||||
VATTR_WANTED(&vattr, va_create_time);
|
|
||||||
VATTR_WANTED(&vattr, va_access_time);
|
|
||||||
VATTR_WANTED(&vattr, va_modify_time);
|
|
||||||
VATTR_WANTED(&vattr, va_change_time);
|
|
||||||
|
|
||||||
if (vnode_getattr(vp, &vattr, context) == 0) {
|
|
||||||
e->owner_uid = vattr.va_uid;
|
|
||||||
e->owner_gid = vattr.va_gid;
|
|
||||||
e->mode = vattr.va_mode;
|
|
||||||
e->create_time = vattr.va_create_time.tv_sec;
|
|
||||||
e->access_time = vattr.va_access_time.tv_sec;
|
|
||||||
e->modify_time = vattr.va_modify_time.tv_sec;
|
|
||||||
e->change_time = vattr.va_change_time.tv_sec;
|
|
||||||
}
|
|
||||||
|
|
||||||
vfs_context_rele(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
e->uid = kauth_cred_getruid(credential);
|
|
||||||
e->euid = kauth_cred_getuid(credential);
|
|
||||||
|
|
||||||
e->gid = kauth_cred_getrgid(credential);
|
|
||||||
e->egid = kauth_cred_getgid(credential);
|
|
||||||
|
|
||||||
vn_getpath(vp, e->path, &path_len);
|
|
||||||
|
|
||||||
osquery_cqueue_commit(&osquery.cqueue, e);
|
|
||||||
}
|
|
||||||
return KAUTH_RESULT_DEFER;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void setup_locks() {
|
static inline void setup_locks() {
|
||||||
/* Create locks. Cannot be done on the stack. */
|
/* Create locks. Cannot be done on the stack. */
|
||||||
osquery.lck_grp_attr = lck_grp_attr_alloc_init();
|
osquery.lck_grp_attr = lck_grp_attr_alloc_init();
|
||||||
@ -150,30 +83,33 @@ static inline void teardown_locks() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void unsubscribe_all_events() {
|
static void unsubscribe_all_events() {
|
||||||
if (osquery.fileop_listener) {
|
for (int i = 0; i < OSQUERY_NUM_EVENTS; i++) {
|
||||||
kauth_unlisten_scope(osquery.fileop_listener);
|
if (osquery_publishers[i]) {
|
||||||
osquery.fileop_listener = NULL;
|
osquery_publishers[i]->unsubscribe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int subscribe_to_event(osquery_event_t event, int subscribe) {
|
static int subscribe_to_event(osquery_event_t event,
|
||||||
|
int subscribe,
|
||||||
|
void *udata) {
|
||||||
if (osquery.buffer == NULL) {
|
if (osquery.buffer == NULL) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
if (!(OSQUERY_NULL_EVENT < event && event < OSQUERY_NUM_EVENTS)) {
|
||||||
switch (event) {
|
|
||||||
case OSQUERY_PROCESS_EVENT:
|
|
||||||
if (subscribe && osquery.fileop_listener == NULL) {
|
|
||||||
osquery.fileop_listener =
|
|
||||||
kauth_listen_scope(KAUTH_SCOPE_FILEOP, fileop_scope_callback, NULL);
|
|
||||||
} else if (!subscribe && osquery.fileop_listener) {
|
|
||||||
kauth_unlisten_scope(osquery.fileop_listener);
|
|
||||||
osquery.fileop_listener = NULL;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
if (!osquery_publishers[event]) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subscribe) {
|
||||||
|
if (osquery_publishers[event]->subscribe(&osquery.cqueue, udata)) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
osquery_publishers[event]->unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -342,7 +278,7 @@ static int osquery_ioctl(dev_t dev, u_long cmd, caddr_t data,
|
|||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case OSQUERY_IOCTL_SUBSCRIPTION:
|
case OSQUERY_IOCTL_SUBSCRIPTION:
|
||||||
sub = (osquery_subscription_args_t *)data;
|
sub = (osquery_subscription_args_t *)data;
|
||||||
if ((err = subscribe_to_event(sub->event, sub->subscribe))) {
|
if ((err = subscribe_to_event(sub->event, sub->subscribe, sub->udata))) {
|
||||||
goto error_exit;
|
goto error_exit;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -365,6 +301,12 @@ static int osquery_ioctl(dev_t dev, u_long cmd, caddr_t data,
|
|||||||
case OSQUERY_IOCTL_BUF_ALLOCATE:
|
case OSQUERY_IOCTL_BUF_ALLOCATE:
|
||||||
alloc = (osquery_buf_allocate_args_t *)data;
|
alloc = (osquery_buf_allocate_args_t *)data;
|
||||||
|
|
||||||
|
if (alloc->version != OSQUERY_KERNEL_COMM_VERSION) {
|
||||||
|
// Daemon tried connecting with incorrect version number.
|
||||||
|
err = -EINVAL;
|
||||||
|
goto error_exit;
|
||||||
|
}
|
||||||
|
|
||||||
if (osquery.buffer != NULL) {
|
if (osquery.buffer != NULL) {
|
||||||
// We don't want to allocate a second buffer.
|
// We don't want to allocate a second buffer.
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
|
54
kernel/src/publishers.h
Normal file
54
kernel/src/publishers.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <feeds.h>
|
||||||
|
#include "circular_queue_kern.h"
|
||||||
|
|
||||||
|
/** @brief Subscribe function type.
|
||||||
|
*
|
||||||
|
* This function type is called when someone subscribes to a publisher. It
|
||||||
|
* should initialize all event callbacks and start publishing events to the
|
||||||
|
* queue.
|
||||||
|
*
|
||||||
|
* @param queue The queue to publish to. A subscriber will only publish to the
|
||||||
|
* last queue (not an issue as there should only be one queue).
|
||||||
|
* @param udata Pointer to user data. This is in user space and must be
|
||||||
|
* copied down to kernel space before use. A publisher may use this for
|
||||||
|
* any additional data it wants from user space.
|
||||||
|
* @return 0 on success, negative on failure.
|
||||||
|
*/
|
||||||
|
typedef int (*osquery_subscriber_t)(osquery_cqueue_t *queue, void *udata);
|
||||||
|
/** @brief Unsubscribe function type.
|
||||||
|
*
|
||||||
|
* Functions of this type stop a publisher from publishing events to the queue
|
||||||
|
* as soon as possible.
|
||||||
|
*
|
||||||
|
* @return Void.
|
||||||
|
*/
|
||||||
|
typedef void (*osquery_unsubscriber_t)();
|
||||||
|
|
||||||
|
/** @brief A kernel publisher must provide the following function pointers.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
osquery_subscriber_t subscribe;
|
||||||
|
osquery_unsubscriber_t unsubscribe;
|
||||||
|
} osquery_kernel_event_publisher_t;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Event publisher structs defined in implementations.
|
||||||
|
//
|
||||||
|
extern osquery_kernel_event_publisher_t process_events_publisher;
|
||||||
|
|
||||||
|
/** @brief List of the kernel event publishers.
|
||||||
|
*/
|
||||||
|
static osquery_kernel_event_publisher_t
|
||||||
|
*osquery_publishers[OSQUERY_NUM_EVENTS] = {
|
||||||
|
[OSQUERY_PROCESS_EVENT] = &process_events_publisher
|
||||||
|
};
|
105
kernel/src/publishers/darwin/process_events.c
Normal file
105
kernel/src/publishers/darwin/process_events.c
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/proc.h>
|
||||||
|
#include <sys/systm.h>
|
||||||
|
#include <sys/kauth.h>
|
||||||
|
#include <sys/vnode.h>
|
||||||
|
|
||||||
|
#include "publishers.h"
|
||||||
|
|
||||||
|
static osquery_cqueue_t *cqueue = NULL;
|
||||||
|
static kauth_listener_t fileop_listener = NULL;
|
||||||
|
|
||||||
|
static int fileop_scope_callback(kauth_cred_t credential,
|
||||||
|
void *idata,
|
||||||
|
kauth_action_t action,
|
||||||
|
uintptr_t arg0,
|
||||||
|
uintptr_t arg1,
|
||||||
|
uintptr_t arg2,
|
||||||
|
uintptr_t arg3) {
|
||||||
|
vnode_t vp = (vnode_t)arg0;
|
||||||
|
if (action == KAUTH_FILEOP_EXEC && vp != NULL) {
|
||||||
|
// Someone is executing a file.
|
||||||
|
int path_len = MAXPATHLEN;
|
||||||
|
|
||||||
|
osquery_process_event_t *e =
|
||||||
|
(osquery_process_event_t *)osquery_cqueue_reserve(
|
||||||
|
cqueue, OSQUERY_PROCESS_EVENT);
|
||||||
|
if (e == NULL) {
|
||||||
|
// Failed to reserve space for the event.
|
||||||
|
return KAUTH_RESULT_DEFER;
|
||||||
|
}
|
||||||
|
e->pid = proc_selfpid();
|
||||||
|
e->ppid = proc_selfppid();
|
||||||
|
e->owner_uid = 0;
|
||||||
|
e->owner_gid = 0;
|
||||||
|
e->mode = -1;
|
||||||
|
vfs_context_t context = vfs_context_create(NULL);
|
||||||
|
if (context) {
|
||||||
|
struct vnode_attr vattr = {0};
|
||||||
|
VATTR_INIT(&vattr);
|
||||||
|
VATTR_WANTED(&vattr, va_uid);
|
||||||
|
VATTR_WANTED(&vattr, va_gid);
|
||||||
|
VATTR_WANTED(&vattr, va_mode);
|
||||||
|
VATTR_WANTED(&vattr, va_create_time);
|
||||||
|
VATTR_WANTED(&vattr, va_access_time);
|
||||||
|
VATTR_WANTED(&vattr, va_modify_time);
|
||||||
|
VATTR_WANTED(&vattr, va_change_time);
|
||||||
|
|
||||||
|
if (vnode_getattr(vp, &vattr, context) == 0) {
|
||||||
|
e->owner_uid = vattr.va_uid;
|
||||||
|
e->owner_gid = vattr.va_gid;
|
||||||
|
e->mode = vattr.va_mode;
|
||||||
|
e->create_time = vattr.va_create_time.tv_sec;
|
||||||
|
e->access_time = vattr.va_access_time.tv_sec;
|
||||||
|
e->modify_time = vattr.va_modify_time.tv_sec;
|
||||||
|
e->change_time = vattr.va_change_time.tv_sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
vfs_context_rele(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
e->uid = kauth_cred_getruid(credential);
|
||||||
|
e->euid = kauth_cred_getuid(credential);
|
||||||
|
|
||||||
|
e->gid = kauth_cred_getrgid(credential);
|
||||||
|
e->egid = kauth_cred_getgid(credential);
|
||||||
|
|
||||||
|
vn_getpath(vp, e->path, &path_len);
|
||||||
|
|
||||||
|
osquery_cqueue_commit(cqueue, e);
|
||||||
|
}
|
||||||
|
return KAUTH_RESULT_DEFER;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int subscribe(osquery_cqueue_t *queue, void *udata) {
|
||||||
|
cqueue = queue;
|
||||||
|
if (fileop_listener != NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileop_listener =
|
||||||
|
kauth_listen_scope(KAUTH_SCOPE_FILEOP, fileop_scope_callback, NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void unsubscribe() {
|
||||||
|
if (fileop_listener) {
|
||||||
|
kauth_unlisten_scope(fileop_listener);
|
||||||
|
fileop_listener = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
osquery_kernel_event_publisher_t process_events_publisher = {
|
||||||
|
.subscribe = &subscribe,
|
||||||
|
.unsubscribe = &unsubscribe
|
||||||
|
};
|
@ -40,7 +40,7 @@ void KernelEventPublisher::configure() {
|
|||||||
for (const auto &sub : subscriptions_) {
|
for (const auto &sub : subscriptions_) {
|
||||||
if (queue_ != nullptr) {
|
if (queue_ != nullptr) {
|
||||||
auto sc = getSubscriptionContext(sub->context);
|
auto sc = getSubscriptionContext(sub->context);
|
||||||
queue_->subscribe(sc->event_type);
|
queue_->subscribe(sc->event_type, sc->udata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,9 @@ namespace osquery {
|
|||||||
struct KernelSubscriptionContext : public SubscriptionContext {
|
struct KernelSubscriptionContext : public SubscriptionContext {
|
||||||
/// The kernel event subscription type.
|
/// The kernel event subscription type.
|
||||||
osquery_event_t event_type;
|
osquery_event_t event_type;
|
||||||
|
|
||||||
|
/// Data to pass to the kernel.
|
||||||
|
void *udata;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,6 +27,7 @@ CQueue::CQueue(size_t size) {
|
|||||||
osquery_buf_allocate_args_t alloc;
|
osquery_buf_allocate_args_t alloc;
|
||||||
alloc.size = size;
|
alloc.size = size;
|
||||||
alloc.buffer = NULL;
|
alloc.buffer = NULL;
|
||||||
|
alloc.version = OSQUERY_KERNEL_COMM_VERSION;
|
||||||
|
|
||||||
fd_ = open(filename, O_RDWR);
|
fd_ = open(filename, O_RDWR);
|
||||||
if (fd_ < 0) {
|
if (fd_ < 0) {
|
||||||
@ -50,10 +51,11 @@ CQueue::~CQueue() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CQueue::subscribe(osquery_event_t event) {
|
void CQueue::subscribe(osquery_event_t event, void *udata) {
|
||||||
osquery_subscription_args_t sub;
|
osquery_subscription_args_t sub;
|
||||||
sub.event = event;
|
sub.event = event;
|
||||||
sub.subscribe = 1;
|
sub.subscribe = 1;
|
||||||
|
sub.udata = udata;
|
||||||
|
|
||||||
if (ioctl(fd_, OSQUERY_IOCTL_SUBSCRIPTION, &sub)) {
|
if (ioctl(fd_, OSQUERY_IOCTL_SUBSCRIPTION, &sub)) {
|
||||||
throw CQueueException("Could not subscribe to event.");
|
throw CQueueException("Could not subscribe to event.");
|
||||||
|
@ -55,8 +55,9 @@ class CQueue {
|
|||||||
* This sets up the event callbacks so we start hearing about the given event.
|
* This sets up the event callbacks so we start hearing about the given event.
|
||||||
*
|
*
|
||||||
* @param event The event we are interested in.
|
* @param event The event we are interested in.
|
||||||
|
* @param udata Pointer to udata for the event. This is for additional info.
|
||||||
*/
|
*/
|
||||||
void subscribe(osquery_event_t event);
|
void subscribe(osquery_event_t event, void *udata);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Dequeue's an event from the shared buffer.
|
* @brief Dequeue's an event from the shared buffer.
|
||||||
|
@ -28,6 +28,7 @@ REGISTER(ProcessEventSubscriber, "event_subscriber", "process_events");
|
|||||||
Status ProcessEventSubscriber::init() {
|
Status ProcessEventSubscriber::init() {
|
||||||
auto sc = createSubscriptionContext();
|
auto sc = createSubscriptionContext();
|
||||||
sc->event_type = OSQUERY_PROCESS_EVENT;
|
sc->event_type = OSQUERY_PROCESS_EVENT;
|
||||||
|
sc->udata = NULL;
|
||||||
subscribe(&ProcessEventSubscriber::Callback, sc, NULL);
|
subscribe(&ProcessEventSubscriber::Callback, sc, NULL);
|
||||||
|
|
||||||
return Status(0, "OK");
|
return Status(0, "OK");
|
||||||
|
Loading…
Reference in New Issue
Block a user