Skip to content

Commit 91f6539

Browse files
authored
Merge branch 'master' into fix-issue-268
2 parents 0d019be + 8beba35 commit 91f6539

File tree

11 files changed

+175
-10
lines changed

11 files changed

+175
-10
lines changed

attach/frida_uprobe_attach_impl/src/frida_internal_attach_entry.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ frida_internal_attach_entry::~frida_internal_attach_entry()
7979
SPDLOG_DEBUG("Reverted function replace");
8080
}
8181
gum_object_unref(interceptor);
82+
SPDLOG_DEBUG("Destructor of frida_internal_attach_entry exiting..");
8283
}
8384

8485
bool frida_internal_attach_entry::has_override() const

attach/text_segment_transformer/agent-transformer.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ using shm_destroy_func_t = void (*)(void);
1313

1414
static main_func_t orig_main_func = nullptr;
1515
static shm_destroy_func_t shm_destroy_func = nullptr;
16+
17+
// Whether syscall server was injected using frida. Defaults to true. If
18+
// __libc_start_main was called, it will be set to false
19+
static bool injected_with_frida = true;
1620
extern "C" void bpftime_agent_main(const gchar *data, gboolean *stay_resident);
1721

1822
extern "C" int bpftime_hooked_main(int argc, char **argv, char **envp)
@@ -29,6 +33,7 @@ extern "C" int __libc_start_main(int (*main)(int, char **, char **), int argc,
2933
void (*fini)(void), void (*rtld_fini)(void),
3034
void *stack_end)
3135
{
36+
injected_with_frida = false;
3237
SPDLOG_INFO("Entering bpftime syscal transformer agent");
3338
orig_main_func = main;
3439
using this_func_t = decltype(&__libc_start_main);
@@ -70,6 +75,14 @@ extern "C" void bpftime_agent_main(const gchar *data, gboolean *stay_resident)
7075
SPDLOG_ERROR("Failed to open agent: {}", dlerror());
7176
exit(1);
7277
}
78+
// Set the flag `injected_with_frida` for agent
79+
bool *injected_with_frida__agent =
80+
(bool *)dlsym(next_handle, "injected_with_frida");
81+
if (!injected_with_frida__agent) {
82+
SPDLOG_WARN(
83+
"Agent does not expose a symbol named injected_with_frida, so we can't let agent know whether it was loaded using frida");
84+
}
85+
*injected_with_frida__agent = injected_with_frida;
7386
auto entry_func = (void (*)(syscall_hooker_func_t *))dlsym(
7487
next_handle, "_bpftime__setup_syscall_trace_callback");
7588

runtime/agent/agent.cpp

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
#include "attach_private_data.hpp"
22
#include "bpf_attach_ctx.hpp"
3+
#include "bpftime_shm_internal.hpp"
34
#include "frida_attach_private_data.hpp"
45
#include "frida_uprobe_attach_impl.hpp"
56
#include "spdlog/common.h"
67
#include "syscall_trace_attach_impl.hpp"
78
#include "syscall_trace_attach_private_data.hpp"
9+
#include <chrono>
10+
#include <csignal>
811
#include <exception>
912
#include <fcntl.h>
1013
#include <memory>
14+
#include <pthread.h>
1115
#include <string_view>
16+
#include <thread>
1217
#include <unistd.h>
1318
#include <frida-gum.h>
1419
#include <cstdint>
@@ -22,6 +27,12 @@ using main_func_t = int (*)(int, char **, char **);
2227

2328
static main_func_t orig_main_func = nullptr;
2429

30+
// Whether this injected process was operated through frida?
31+
// Defaults to true. If __libc_start_main was called, it should be set to false;
32+
// Besides, if agent was loaded by text-transformer, this variable will be set
33+
// by text-transformer
34+
bool injected_with_frida = true;
35+
2536
union bpf_attach_ctx_holder {
2637
bpf_attach_ctx ctx;
2738
bpf_attach_ctx_holder()
@@ -48,7 +59,7 @@ extern "C" void bpftime_agent_main(const gchar *data, gboolean *stay_resident);
4859
extern "C" int bpftime_hooked_main(int argc, char **argv, char **envp)
4960
{
5061
int stay_resident = 0;
51-
62+
injected_with_frida = false;
5263
bpftime_agent_main("", &stay_resident);
5364
int ret = orig_main_func(argc, argv, envp);
5465
ctx_holder.destroy();
@@ -70,8 +81,22 @@ extern "C" int __libc_start_main(int (*main)(int, char **, char **), int argc,
7081
stack_end);
7182
}
7283

84+
static void sig_handler_sigusr1(int sig)
85+
{
86+
SPDLOG_INFO("Detaching..");
87+
if (int err = ctx_holder.ctx.destroy_all_attach_links(); err < 0) {
88+
SPDLOG_ERROR("Unable to detach: {}", err);
89+
return;
90+
}
91+
shm_holder.global_shared_memory.remove_pid_from_alive_agent_set(getpid());
92+
SPDLOG_DEBUG("Detaching done");
93+
}
94+
7395
extern "C" void bpftime_agent_main(const gchar *data, gboolean *stay_resident)
7496
{
97+
SPDLOG_DEBUG("Registering signal handler");
98+
// We use SIGUSR1 to indicate the detaching
99+
signal(SIGUSR1, sig_handler_sigusr1);
75100
spdlog::cfg::load_env_levels();
76101
try {
77102
// If we are unable to initialize shared memory..
@@ -81,6 +106,12 @@ extern "C" void bpftime_agent_main(const gchar *data, gboolean *stay_resident)
81106
ex.what());
82107
return;
83108
}
109+
// Only agents injected through frida could be detached
110+
if (injected_with_frida) {
111+
// Record the pid
112+
shm_holder.global_shared_memory.add_pid_into_alive_agent_set(
113+
getpid());
114+
}
84115
ctx_holder.init();
85116
// Register syscall trace impl
86117
auto syscall_trace_impl = std::make_unique<syscall_trace_attach_impl>();

runtime/include/bpf_attach_ctx.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ class bpf_attach_ctx {
5252
private_data_creator);
5353
// Destroy a specific attach link
5454
int destroy_instantiated_attach_link(int link_id);
55+
// Destroy all instantiated attach links
56+
int destroy_all_attach_links();
5557

5658
private:
5759
constexpr static int CURRENT_ID_OFFSET = 65536;
@@ -64,7 +66,7 @@ class bpf_attach_ctx {
6466
std::map<int, std::unique_ptr<bpftime_prog> > instantiated_progs;
6567
// handler_id -> (instantiated attaches id, attach_impl*)
6668
std::map<int, std::pair<int, attach::base_attach_impl *> >
67-
instantiated_attach_ids;
69+
instantiated_attach_links;
6870
// handler_id -> instantiated attach private data & attach type
6971
std::map<int,
7072
std::pair<std::unique_ptr<attach::attach_private_data>, int> >

runtime/src/attach/bpf_attach_ctx.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ int bpf_attach_ctx::instantiate_bpf_link_handler_at(
236236
id, attach_id);
237237
return attach_id;
238238
}
239-
instantiated_attach_ids[id] = std::make_pair(attach_id, attach_impl);
239+
instantiated_attach_links[id] = std::make_pair(attach_id, attach_impl);
240240
return 0;
241241
}
242242
int bpf_attach_ctx::instantiate_perf_event_handler_at(
@@ -315,21 +315,37 @@ int bpf_attach_ctx::instantiate_perf_event_handler_at(
315315
int bpf_attach_ctx::destroy_instantiated_attach_link(int link_id)
316316
{
317317
SPDLOG_DEBUG("Destroy attach link {}", link_id);
318-
if (auto itr = instantiated_attach_ids.find(link_id);
319-
itr != instantiated_attach_ids.end()) {
318+
if (auto itr = instantiated_attach_links.find(link_id);
319+
itr != instantiated_attach_links.end()) {
320320
auto [attach_id, impl] = itr->second;
321321
if (int err = impl->detach_by_id(attach_id); err < 0) {
322322
SPDLOG_ERROR(
323323
"Failed to detach attach link id {}, attach-specified id {}: {}",
324324
link_id, attach_id, err);
325325
return err;
326326
}
327-
instantiated_attach_ids.erase(itr);
327+
instantiated_attach_links.erase(itr);
328328
return 0;
329329
} else {
330330
SPDLOG_ERROR("Unable to find instantiated attach link id {}",
331331
link_id);
332332
return -ENOENT;
333333
}
334334
}
335+
int bpf_attach_ctx::destroy_all_attach_links()
336+
{
337+
// Avoid modifying along with iterating..
338+
std::vector<int> to_detach;
339+
for (const auto &[k, _] : instantiated_attach_links)
340+
to_detach.push_back(k);
341+
for (auto k : to_detach) {
342+
SPDLOG_DEBUG("Destrying attach link {}", k);
343+
if (int err = destroy_instantiated_attach_link(k); err < 0) {
344+
SPDLOG_ERROR("Unable to destroy attach link {}: {}", k,
345+
err);
346+
return err;
347+
}
348+
}
349+
return 0;
350+
}
335351
} // namespace bpftime

runtime/src/bpftime_shm_internal.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
#include "bpftime_shm.hpp"
77
#include "handler/epoll_handler.hpp"
8+
#include "handler/handler_manager.hpp"
89
#include "handler/link_handler.hpp"
910
#include "handler/perf_event_handler.hpp"
1011
#include "spdlog/spdlog.h"
@@ -51,6 +52,17 @@ extern "C" void bpftime_remove_global_shm()
5152

5253
static __attribute__((destructor(65535))) void __destruct_shm()
5354
{
55+
// This usually indicates that the living shared memory object is used
56+
// by an agent instance
57+
if (bpftime::shm_holder.global_shared_memory.get_open_type() ==
58+
bpftime::shm_open_type::SHM_OPEN_ONLY) {
59+
// Try our best to remove the current pid from alive agent's set
60+
int self_pid = getpid();
61+
// It doesn't matter if the current pid is not in the set
62+
bpftime::shm_holder.global_shared_memory
63+
.remove_pid_from_alive_agent_set(self_pid);
64+
}
65+
5466
bpftime_destroy_global_shm();
5567
}
5668

@@ -527,6 +539,7 @@ bool bpftime_shm::is_exist_fake_fd(int fd) const
527539
}
528540

529541
bpftime_shm::bpftime_shm(const char *shm_name, shm_open_type type)
542+
: open_type(type)
530543
{
531544
if (type == shm_open_type::SHM_OPEN_ONLY) {
532545
SPDLOG_DEBUG("start: bpftime_shm for client setup");
@@ -544,6 +557,11 @@ bpftime_shm::bpftime_shm(const char *shm_name, shm_open_type type)
544557
segment.find<struct agent_config>(
545558
bpftime::DEFAULT_AGENT_CONFIG_NAME)
546559
.first;
560+
561+
injected_pids =
562+
segment.find<alive_agent_pids>(
563+
bpftime::DEFAULT_ALIVE_AGENT_PIDS_NAME)
564+
.first;
547565
SPDLOG_DEBUG("done: bpftime_shm for client setup");
548566
} else if (type == shm_open_type::SHM_CREATE_OR_OPEN) {
549567
SPDLOG_DEBUG("start: bpftime_shm for create or open setup");
@@ -567,6 +585,12 @@ bpftime_shm::bpftime_shm(const char *shm_name, shm_open_type type)
567585

568586
agent_config = segment.find_or_construct<struct agent_config>(
569587
bpftime::DEFAULT_AGENT_CONFIG_NAME)();
588+
589+
injected_pids = segment.find_or_construct<alive_agent_pids>(
590+
bpftime::DEFAULT_ALIVE_AGENT_PIDS_NAME)(
591+
std::less<int>(),
592+
alive_agent_pid_set_allocator(
593+
segment.get_segment_manager()));
570594
SPDLOG_DEBUG("done: bpftime_shm for open_or_create setup");
571595
} else if (type == shm_open_type::SHM_REMOVE_AND_CREATE) {
572596
SPDLOG_DEBUG("start: bpftime_shm for server setup");
@@ -596,6 +620,12 @@ bpftime_shm::bpftime_shm(const char *shm_name, shm_open_type type)
596620
bpftime::DEFAULT_AGENT_CONFIG_NAME)();
597621
SPDLOG_DEBUG(
598622
"done: bpftime_shm for server setup: agent_config");
623+
624+
injected_pids = segment.construct<alive_agent_pids>(
625+
bpftime::DEFAULT_ALIVE_AGENT_PIDS_NAME)(
626+
std::less<int>(),
627+
alive_agent_pid_set_allocator(
628+
segment.get_segment_manager()));
599629
SPDLOG_DEBUG("done: bpftime_shm for server setup.");
600630
} else if (type == shm_open_type::SHM_NO_CREATE) {
601631
// not create any shm
@@ -735,4 +765,20 @@ int bpftime_shm::add_custom_perf_event(int type, const char *attach_argument)
735765
segment);
736766
return fd;
737767
}
768+
769+
void bpftime_shm::add_pid_into_alive_agent_set(int pid)
770+
{
771+
injected_pids->insert(pid);
772+
}
773+
void bpftime_shm::remove_pid_from_alive_agent_set(int pid)
774+
{
775+
injected_pids->erase(pid);
776+
}
777+
void bpftime_shm::iterate_all_pids_in_alive_agent_set(
778+
std::function<void(int)> &&cb)
779+
{
780+
for (auto x : *injected_pids) {
781+
cb(x);
782+
}
783+
}
738784
} // namespace bpftime

runtime/src/bpftime_shm_internal.hpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,16 @@ using syscall_pid_set_allocator = boost::interprocess::allocator<
2323
using syscall_pid_set =
2424
boost::interprocess::set<int, std::less<int>, syscall_pid_set_allocator>;
2525

26+
using alive_agent_pid_set_allocator = boost::interprocess::allocator<
27+
int, boost::interprocess::managed_shared_memory::segment_manager>;
28+
29+
using alive_agent_pids =
30+
boost::interprocess::set<int, std::less<int>,
31+
alive_agent_pid_set_allocator>;
32+
2633
// global bpftime share memory
2734
class bpftime_shm {
35+
bpftime::shm_open_type open_type;
2836
// shared memory segment
2937
boost::interprocess::managed_shared_memory segment;
3038

@@ -37,6 +45,9 @@ class bpftime_shm {
3745
// Configuration for the agent. e.g, which helpers are enabled
3846
struct bpftime::agent_config *agent_config = nullptr;
3947

48+
// Record which pids are injected by agent
49+
alive_agent_pids *injected_pids;
50+
4051
#if BPFTIME_ENABLE_MPK
4152
// mpk key for protect shm
4253
bool is_mpk_init = false;
@@ -55,6 +66,13 @@ class bpftime_shm {
5566
// Using a set stored in the shared memory
5667
void set_syscall_trace_setup(int pid, bool whether);
5768

69+
// Add a pid into alive agent set
70+
void add_pid_into_alive_agent_set(int pid);
71+
// Remove a pid from alive agent set
72+
void remove_pid_from_alive_agent_set(int pid);
73+
// Iterate over all pids from the alive agent set
74+
void iterate_all_pids_in_alive_agent_set(std::function<void(int)> &&cb);
75+
5876
const handler_variant &get_handler(int fd) const;
5977
bool is_epoll_fd(int fd) const;
6078

@@ -163,6 +181,10 @@ class bpftime_shm {
163181
get_software_perf_event_raw_buffer(int fd, size_t buffer_sz) const;
164182

165183
int add_custom_perf_event(int type, const char *attach_argument);
184+
bpftime::shm_open_type get_open_type() const
185+
{
186+
return open_type;
187+
}
166188
};
167189

168190
// memory region for maps and prog info

runtime/src/handler/handler_manager.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ constexpr const char *DEFAULT_GLOBAL_SHM_NAME = "bpftime_maps_shm";
5353
constexpr const char *DEFAULT_GLOBAL_HANDLER_NAME = "bpftime_handler";
5454
constexpr const char *DEFAULT_SYSCALL_PID_SET_NAME = "bpftime_syscall_pid_set";
5555
constexpr const char *DEFAULT_AGENT_CONFIG_NAME = "bpftime_agent_config";
56+
constexpr const char* DEFAULT_ALIVE_AGENT_PIDS_NAME = "bpftime_alive_agent_pids";
5657
inline const char *get_global_shm_name()
5758
{
5859
const char *name = getenv("BPFTIME_GLOBAL_SHM_NAME");

tools/cli/CMakeLists.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ add_executable(
55

66
set_target_properties(bpftime-cli-cpp PROPERTIES OUTPUT_NAME "bpftime")
77

8-
target_include_directories(bpftime-cli-cpp PRIVATE ${FRIDA_CORE_INSTALL_DIR} ${SPDLOG_INCLUDE} ${argparse_INCLUDE})
9-
target_link_libraries(bpftime-cli-cpp PRIVATE spdlog::spdlog ${FRIDA_CORE_INSTALL_DIR}/libfrida-core.a argparse)
8+
target_include_directories(bpftime-cli-cpp PRIVATE ${FRIDA_CORE_INSTALL_DIR} ${SPDLOG_INCLUDE} ${argparse_INCLUDE} ../../runtime/include)
9+
target_link_libraries(bpftime-cli-cpp PRIVATE spdlog::spdlog ${FRIDA_CORE_INSTALL_DIR}/libfrida-core.a argparse runtime)
1010
set_property(TARGET bpftime-cli-cpp PROPERTY CXX_STANDARD 20)
1111

1212
target_compile_definitions(bpftime-cli-cpp PRIVATE _GNU_SOURCE)
1313

14-
add_dependencies(bpftime-cli-cpp spdlog::spdlog FridaCore argparse)
14+
add_dependencies(bpftime-cli-cpp spdlog::spdlog FridaCore argparse runtime)
1515

1616
install(TARGETS bpftime-cli-cpp CONFIGURATIONS Release Debug RelWithDebInfo DESTINATION ~/.bpftime)

0 commit comments

Comments
 (0)