Skip to content

Commit

Permalink
update enum class & fix error of compile flag
Browse files Browse the repository at this point in the history
  • Loading branch information
Sy0307 committed Dec 22, 2024
1 parent fb09804 commit 8d6197d
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 43 deletions.
9 changes: 9 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,15 @@ endif()

message(STATUS "Started CMake for ${PROJECT_NAME} v${PROJECT_VERSION}...\n")

# option to use probe read/write checks
if(DEFINED ENABLE_PROBE_READ_CHECK)
add_compile_definitions(ENABLE_PROBE_READ_CHECK=1)
endif()

if(DEFINED ENABLE_PROBE_WRITE_CHECK)
add_compile_definitions(ENABLE_PROBE_WRITE_CHECK=1)
endif()

# if option to build without libbpf is set
if(${BPFTIME_BUILD_WITH_LIBBPF})
add_definitions(-DBPFTIME_BUILD_WITH_LIBBPF=1)
Expand Down
94 changes: 51 additions & 43 deletions runtime/src/bpf_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,52 +67,53 @@ long bpftime_strncmp(const char *s1, uint64_t s1_sz, const char *s2)
return strncmp(s1, s2, s1_sz);
}

extern void jump_point_read();
extern void jump_point_write();
extern "C" void jump_point_read();
extern "C" void jump_point_write();

/*
status instruction for probe_read and probe_write
*/
enum PROBE_STATUS {
PROBE_NOT_RUNNING = -1,
PROBE_RUNNING_NO_ERROR = 0,
PROBE_RUNNING_ERROR = 1
enum class PROBE_STATUS {
NOT_RUNNING = -1,
RUNNING_NO_ERROR = 0,
RUNNING_ERROR = 1
};

thread_local static PROBE_STATUS status_probe_write = PROBE_NOT_RUNNING;
thread_local static PROBE_STATUS status_probe_read = PROBE_NOT_RUNNING;
thread_local static PROBE_STATUS status_probe_write = PROBE_STATUS::NOT_RUNNING;
thread_local static PROBE_STATUS status_probe_read = PROBE_STATUS::NOT_RUNNING;
/*
origin handler exist flag for probe_read and probe_write
*/
enum ORIGIN_HANDLER_EXIST_FLAG {
ORIGIN_HANDLER_NOT_CHECKED = -1,
ORIGIN_HANDLER_NOT_EXIST = 0,
ORIGIN_HANDLER_EXIST = 1
enum class ORIGIN_HANDLER_EXIST_FLAG {
NOT_CHECKED = -1,
NOT_EXIST = 0,
EXIST = 1
};
thread_local static ORIGIN_HANDLER_EXIST_FLAG origin_handler_exist_read =
ORIGIN_HANDLER_NOT_CHECKED;
thread_local static ORIGIN_HANDLER_EXIST_FLAG origin_handler_exist_write =
ORIGIN_HANDLER_NOT_CHECKED;
thread_local static ORIGIN_HANDLER_EXIST_FLAG exist_read =
ORIGIN_HANDLER_EXIST_FLAG::NOT_CHECKED;
thread_local static ORIGIN_HANDLER_EXIST_FLAG exist_write =
ORIGIN_HANDLER_EXIST_FLAG::NOT_CHECKED;

thread_local static void (*origin_segv_read_handler)(int, siginfo_t *,
void *) = nullptr;
void *) = nullptr;
thread_local static void (*origin_segv_write_handler)(int, siginfo_t *,
void *) = nullptr;
void *) = nullptr;


static void segv_read_handler(int sig, siginfo_t *siginfo, void *ctx)
{
SPDLOG_TRACE("segv_handler for probe_read called");
if (status_probe_read == PROBE_NOT_RUNNING) {
if (status_probe_read == PROBE_STATUS::NOT_RUNNING) {
if (origin_segv_read_handler) {
origin_segv_read_handler(sig, siginfo, ctx);
} else {
abort();
}
} else if (status_probe_read == PROBE_RUNNING_NO_ERROR) {
} else if (status_probe_read == PROBE_STATUS::RUNNING_NO_ERROR) {
// set status to error
auto uctx = (ucontext_t *)ctx;
auto *rip = (uintptr_t *)(&uctx->uc_mcontext.gregs[REG_RIP]);
status_probe_read = PROBE_RUNNING_ERROR;
status_probe_read = PROBE_STATUS::RUNNING_ERROR;
*rip = (uintptr_t)&jump_point_read;
}
}
Expand All @@ -121,20 +122,22 @@ int64_t bpftime_probe_read(uint64_t dst, uint64_t size, uint64_t ptr, uint64_t,
uint64_t)
{
int64_t ret = 0;
status_probe_read = PROBE_RUNNING_NO_ERROR;

#ifdef ENABLE_PROBE_READ_CHECK
status_probe_read = PROBE_STATUS::RUNNING_NO_ERROR;

struct sigaction sa, original_sa;
// set up the signal handler
if (origin_handler_exist_read == ORIGIN_HANDLER_NOT_CHECKED) {
if (exist_read == ORIGIN_HANDLER_EXIST_FLAG::NOT_CHECKED) {
int err = sigaction(SIGSEGV, nullptr, &original_sa);
if (err) {
SPDLOG_ERROR("Failed to get signal handler: {}", errno);
return -EFAULT;
}
if (original_sa.sa_sigaction == nullptr) {
origin_handler_exist_read = ORIGIN_HANDLER_NOT_EXIST;
exist_read = ORIGIN_HANDLER_EXIST_FLAG::NOT_EXIST;
} else {
origin_handler_exist_read = ORIGIN_HANDLER_EXIST;
exist_read = ORIGIN_HANDLER_EXIST_FLAG::EXIST;
origin_segv_read_handler = original_sa.sa_sigaction;
}
}
Expand All @@ -143,7 +146,7 @@ int64_t bpftime_probe_read(uint64_t dst, uint64_t size, uint64_t ptr, uint64_t,
sa.sa_flags = SA_SIGINFO;
int err = 0;
err = sigemptyset(&sa.sa_mask);
if(err){
if (err) {
SPDLOG_ERROR("Failed to set signal handler: {}", errno);
return -EFAULT;
}
Expand All @@ -154,38 +157,40 @@ int64_t bpftime_probe_read(uint64_t dst, uint64_t size, uint64_t ptr, uint64_t,
return -EFAULT;
}
}
#endif
unsigned char *dst_p = (unsigned char *)dst;
unsigned char *src_p = (unsigned char *)ptr;
while (size--) {
*((unsigned char *)dst_p) = *((unsigned char *)src_p);
dst_p++;
src_p++;
}

__asm__("jump_point_read:");
if (status_probe_read) {

#ifdef ENABLE_PROBE_READ_CHECK
if (status_probe_read == PROBE_STATUS::RUNNING_ERROR) {
ret = -EFAULT;
}

status_probe_read = PROBE_NOT_RUNNING;

status_probe_read = PROBE_STATUS::NOT_RUNNING;
#endif
return ret;
}

static void segv_write_handler(int sig, siginfo_t *siginfo, void *ctx)
{
SPDLOG_TRACE("segv_handler for probe_write called");
if (status_probe_write == PROBE_NOT_RUNNING) {
if (status_probe_write == PROBE_STATUS::NOT_RUNNING) {
if (origin_segv_write_handler) {
origin_segv_write_handler(sig, siginfo, ctx);
} else {
abort();
}
} else if (status_probe_write == PROBE_RUNNING_NO_ERROR) {
} else if (status_probe_write == PROBE_STATUS::RUNNING_NO_ERROR) {
// set status to error
auto uctx = (ucontext_t *)ctx;
auto *rip = (uintptr_t *)(&uctx->uc_mcontext.gregs[REG_RIP]);
status_probe_write = PROBE_RUNNING_ERROR;
status_probe_write = PROBE_STATUS::RUNNING_ERROR;
*rip = (uintptr_t)&jump_point_write;
}
}
Expand All @@ -195,42 +200,43 @@ int64_t bpftime_probe_write_user(uint64_t dst, uint64_t src, uint64_t len,
{
int64_t ret = 0;

status_probe_write = PROBE_RUNNING_NO_ERROR;
#ifdef ENABLE_PROBE_WRITE_CHECK
status_probe_write = PROBE_STATUS::RUNNING_NO_ERROR;

struct sigaction sa, original_sa;
// set up the signal handler
if (origin_handler_exist_write == ORIGIN_HANDLER_NOT_CHECKED) {
if (exist_write == ORIGIN_HANDLER_EXIST_FLAG::NOT_CHECKED) {
int err = sigaction(SIGSEGV, nullptr, &original_sa);
if (err) {
SPDLOG_ERROR("Failed to get signal handler: {}", errno);
return -EFAULT;
}

if (original_sa.sa_sigaction == nullptr) {
origin_handler_exist_write = ORIGIN_HANDLER_NOT_EXIST;
exist_write = ORIGIN_HANDLER_EXIST_FLAG::NOT_EXIST;
} else {
origin_handler_exist_write = ORIGIN_HANDLER_EXIST;
exist_write = ORIGIN_HANDLER_EXIST_FLAG::EXIST;
origin_segv_write_handler = original_sa.sa_sigaction;
}
}

if (original_sa.sa_sigaction != segv_write_handler) {
sa.sa_flags = SA_SIGINFO;
int err = 0 ;
int err = 0;
err = sigemptyset(&sa.sa_mask);
if(err){
if (err) {
SPDLOG_ERROR("Failed to set signal handler: {}", errno);
return -EFAULT;
}

sa.sa_sigaction = segv_write_handler;
err = sigaction(SIGSEGV, &sa, nullptr);
if (err) {
SPDLOG_ERROR("Failed to set signal handler: {}", errno);
return -EFAULT;
}
}

#endif
unsigned char *dst_p = (unsigned char *)dst;
unsigned char *src_p = (unsigned char *)src;
while (len--) {
Expand All @@ -240,12 +246,14 @@ int64_t bpftime_probe_write_user(uint64_t dst, uint64_t src, uint64_t len,
}

__asm__("jump_point_write:");
if (status_probe_write) {
#ifdef ENABLE_PROBE_WRITE_CHECK
if (status_probe_write == PROBE_STATUS::RUNNING_ERROR) {
ret = -EFAULT;
}

status_probe_write = PROBE_NOT_RUNNING;
status_probe_write = PROBE_STATUS::NOT_RUNNING;

#endif
return ret;
}

Expand Down

0 comments on commit 8d6197d

Please sign in to comment.