Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
7fb0410
test fix
saxena-anurag Jun 10, 2026
729444f
Merge branch 'main' into user/anusa/issue_5238
saxena-anurag Jun 10, 2026
51a2f64
fix: use mutex serialization instead of skipping worker thread cleanup
saxena-anurag Jun 10, 2026
e2b0ca3
Revert "fix: use mutex serialization instead of skipping worker threa…
saxena-anurag Jun 10, 2026
a3f315b
Merge branch 'main' into user/anusa/issue_5238
saxena-anurag Jun 10, 2026
aceff0f
update test code
saxena-anurag Jun 10, 2026
18617bc
Merge branch 'user/anusa/issue_5238' of https://github.com/microsoft/…
saxena-anurag Jun 10, 2026
6949dc0
backup code
saxena-anurag Jun 11, 2026
0063188
Merge branch 'main' into user/anusa/issue_5238
saxena-anurag Jun 18, 2026
d346b02
Merge branch 'main' into user/anusa/issue_5238
saxena-anurag Jul 10, 2026
01e914b
Merge branch 'main' into user/anusa/issue_5238
saxena-anurag Jul 14, 2026
8a562be
fix link object leaks in socket_tests
saxena-anurag Jul 14, 2026
2b674bf
Merge branch 'main' into user/anusa/issue_5238
saxena-anurag Jul 14, 2026
a537594
fix tests
saxena-anurag Jul 14, 2026
a0e32a3
use RAII
saxena-anurag Jul 14, 2026
db63bc3
Merge branch 'main' into user/anusa/issue_5238_3
saxena-anurag Jul 23, 2026
81337a6
Merge branch 'main' into user/anusa/issue_5238_3
saxena-anurag Jul 27, 2026
7281b37
Merge branch 'main' into user/anusa/issue_5238_3
saxena-anurag Jul 27, 2026
251e1d9
Merge branch 'main' into user/anusa/issue_5238_3
saxena-anurag Aug 14, 2026
927a1a7
Merge branch 'main' into user/anusa/issue_5238_3
saxena-anurag Aug 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions libs/execution_context/ebpf_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1544,12 +1544,15 @@ _ebpf_core_protocol_unlink_program(_In_ const ebpf_operation_unlink_program_requ
EBPF_LOG_ENTRY();
ebpf_result_t retval = EBPF_SUCCESS;
ebpf_link_t* link = NULL;
bool detach_single_link = false;
bool detached_any_link = false;

if (request->link_handle != ebpf_handle_invalid) {
retval = EBPF_OBJECT_REFERENCE_BY_HANDLE(request->link_handle, EBPF_OBJECT_LINK, (ebpf_core_object_t**)&link);
if (retval != EBPF_SUCCESS) {
goto Done;
}
detach_single_link = true;
} else if (request->attach_data_present) {
// This path will be taken for bpf_prog_detach and bpf_prog_detach2 APIs.
// Find the link object matching the unlink request parameters.
Expand All @@ -1570,17 +1573,18 @@ _ebpf_core_protocol_unlink_program(_In_ const ebpf_operation_unlink_program_requ
// Detach the link. Since _ebpf_core_find_matching_link takes a reference on the link object,
// the detach function will not free the link object.
ebpf_link_detach_program(link);
detached_any_link = true;
// Pass the link object as the previous object parameter to the _ebpf_core_find_matching_link function,
// which will release the reference from it.
previous_link = link;
}
if (retval == EBPF_NO_MORE_KEYS) {
// No more matching links to detach.
retval = EBPF_SUCCESS;
retval = detached_any_link ? EBPF_SUCCESS : EBPF_OBJECT_NOT_FOUND;
}
}

if (link != NULL) {
if (detach_single_link && link != NULL) {
ebpf_link_detach_program(link);
}

Expand Down
2 changes: 1 addition & 1 deletion tests/connect_redirect/connect_redirect_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ _initialize_test_globals()

// Load and attach the programs.
native_module_helper_t helper;
helper.initialize("cgroup_sock_addr2");
helper.initialize("cgroup_sock_addr2", EBPF_EXECUTION_ANY, true);
_globals.bpf_object.reset(bpf_object__open(helper.get_file_name().c_str()));
SAFE_REQUIRE(_globals.bpf_object.get() != nullptr);
SAFE_REQUIRE(bpf_object__load(_globals.bpf_object.get()) == 0);
Expand Down
89 changes: 89 additions & 0 deletions tests/libs/common/common_tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,95 @@ typedef struct _close_bpf_object
} close_bpf_object_t;
typedef std::unique_ptr<bpf_object, close_bpf_object_t> bpf_object_ptr;

/**
* @brief RAII guard for legacy links created by bpf_prog_attach.
*
* bpf_prog_attach does not return a bpf_link handle, so the only way to
* clean up is to call bpf_prog_detach2 with the same parameters. This
* guard captures those parameters at attach time and calls detach in its
* destructor, ensuring cleanup even when tests exit via exceptions or
* SAFE_REQUIRE failures.
*/
class bpf_prog_attach_guard_t
{
public:
bpf_prog_attach_guard_t() = default;

/**
* @brief Attach a program and take ownership of detaching it.
* @param prog_fd File descriptor of the program to attach.
* @param attach_target Target (compartment ID) to attach to.
* @param attach_type The BPF attach type.
* @param flags Attach flags.
*/
bpf_prog_attach_guard_t(int prog_fd, uint32_t attach_target, bpf_attach_type attach_type, uint32_t flags = 0)
: _prog_fd(prog_fd), _attach_target(attach_target), _attach_type(attach_type)
{
_last_result = bpf_prog_attach(prog_fd, attach_target, attach_type, flags);
_attached = (_last_result == 0);
}

~bpf_prog_attach_guard_t() { detach(); }

bpf_prog_attach_guard_t(const bpf_prog_attach_guard_t&) = delete;
bpf_prog_attach_guard_t&
operator=(const bpf_prog_attach_guard_t&) = delete;

bpf_prog_attach_guard_t(bpf_prog_attach_guard_t&& other) noexcept
: _prog_fd(other._prog_fd), _attach_target(other._attach_target), _attach_type(other._attach_type),
_attached(other._attached), _last_result(other._last_result)
{
other._attached = false;
}

bpf_prog_attach_guard_t&
operator=(bpf_prog_attach_guard_t&& other) noexcept
{
if (this != &other) {
detach();
_prog_fd = other._prog_fd;
_attach_target = other._attach_target;
_attach_type = other._attach_type;
_attached = other._attached;
_last_result = other._last_result;
other._attached = false;
}
return *this;
}

/** @brief Manually detach. Safe to call multiple times. */
int
detach()
{
if (_attached) {
_attached = false;
return bpf_prog_detach2(_prog_fd, _attach_target, _attach_type);
}
return 0;
}

/** @brief Result of the bpf_prog_attach call (0 on success). */
int
result() const
{
return _last_result;
}

/** @brief Whether the program is currently attached. */
bool
attached() const
{
return _attached;
}

private:
int _prog_fd{-1};
uint32_t _attach_target{0};
bpf_attach_type _attach_type{};
bool _attached{false};
int _last_result{-1};
};

void
ebpf_test_pinned_map_enum(bool verify_pin_path);
void
Expand Down
14 changes: 0 additions & 14 deletions tests/libs/util/native_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,6 @@ _native_module_helper::initialize(
#else
ebpf_execution_type_t system_default = ebpf_execution_type_t::EBPF_EXECUTION_ANY;
#endif
// Clean up any previous state.
// Detach all bpf links.
uint32_t link_id;
while (bpf_link_get_next_id(0, &link_id) == 0) {
fd_t link_fd = bpf_link_get_fd_by_id(link_id);
if (link_fd < 0) {
break;
}
bpf_link_detach(link_fd);
if (link_fd >= 0) {
(void)ebpf_close_fd(link_fd);
}
}

// Set _is_main_thread before any REQUIRE is invoked.
_is_main_thread = is_main_thread;

Expand Down
Loading
Loading