Add object history tracking instrumentation (#2449)
* Add object history tracking instrumentation Signed-off-by: Alan Jowett <alanjo@microsoft.com> * Fix file_id type in history Signed-off-by: Alan Jowett <alanjo@microsoft.com> * Code analysis failure Signed-off-by: Alan Jowett <alanjo@microsoft.com> * PR feedback Signed-off-by: Alan Jowett <alanjo@microsoft.com> * Fix incorrect instrumentation Signed-off-by: Alan Jowett <alanjo@microsoft.com> --------- Signed-off-by: Alan Jowett <alanjo@microsoft.com>
This commit is contained in:
Родитель
6df36ed81e
Коммит
f92c9995b0
|
@ -1,6 +1,8 @@
|
|||
// Copyright (c) Microsoft Corporation
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#define EBPF_FILE_ID EBPF_FILE_ID_CORE
|
||||
|
||||
#include "ebpf_async.h"
|
||||
#include "ebpf_core.h"
|
||||
#include "ebpf_epoch.h"
|
||||
|
@ -278,7 +280,7 @@ ebpf_core_load_code(
|
|||
EBPF_LOG_ENTRY();
|
||||
ebpf_result_t retval;
|
||||
ebpf_program_t* program = NULL;
|
||||
retval = ebpf_object_reference_by_handle(program_handle, EBPF_OBJECT_PROGRAM, (ebpf_core_object_t**)&program);
|
||||
retval = EBPF_OBJECT_REFERENCE_BY_HANDLE(program_handle, EBPF_OBJECT_PROGRAM, (ebpf_core_object_t**)&program);
|
||||
if (retval != EBPF_SUCCESS) {
|
||||
goto Done;
|
||||
}
|
||||
|
@ -289,7 +291,7 @@ ebpf_core_load_code(
|
|||
}
|
||||
|
||||
Done:
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)program);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)program);
|
||||
EBPF_RETURN_RESULT(retval);
|
||||
}
|
||||
|
||||
|
@ -345,7 +347,7 @@ ebpf_core_resolve_helper(
|
|||
EBPF_LOG_ENTRY();
|
||||
ebpf_program_t* program = NULL;
|
||||
ebpf_result_t return_value =
|
||||
ebpf_object_reference_by_handle(program_handle, EBPF_OBJECT_PROGRAM, (ebpf_core_object_t**)&program);
|
||||
EBPF_OBJECT_REFERENCE_BY_HANDLE(program_handle, EBPF_OBJECT_PROGRAM, (ebpf_core_object_t**)&program);
|
||||
if (return_value != EBPF_SUCCESS) {
|
||||
goto Done;
|
||||
}
|
||||
|
@ -361,7 +363,7 @@ ebpf_core_resolve_helper(
|
|||
}
|
||||
|
||||
Done:
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)program);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)program);
|
||||
EBPF_RETURN_RESULT(return_value);
|
||||
}
|
||||
|
||||
|
@ -427,7 +429,7 @@ ebpf_core_resolve_maps(
|
|||
uint32_t map_index = 0;
|
||||
|
||||
ebpf_result_t return_value =
|
||||
ebpf_object_reference_by_handle(program_handle, EBPF_OBJECT_PROGRAM, (ebpf_core_object_t**)&program);
|
||||
EBPF_OBJECT_REFERENCE_BY_HANDLE(program_handle, EBPF_OBJECT_PROGRAM, (ebpf_core_object_t**)&program);
|
||||
if (return_value != EBPF_SUCCESS) {
|
||||
goto Done;
|
||||
}
|
||||
|
@ -435,7 +437,7 @@ ebpf_core_resolve_maps(
|
|||
for (map_index = 0; map_index < count_of_maps; map_index++) {
|
||||
ebpf_map_t* map;
|
||||
return_value =
|
||||
ebpf_object_reference_by_handle(map_handles[map_index], EBPF_OBJECT_MAP, (ebpf_core_object_t**)&map);
|
||||
EBPF_OBJECT_REFERENCE_BY_HANDLE(map_handles[map_index], EBPF_OBJECT_MAP, (ebpf_core_object_t**)&map);
|
||||
|
||||
if (return_value != EBPF_SUCCESS) {
|
||||
goto Done;
|
||||
|
@ -449,10 +451,10 @@ ebpf_core_resolve_maps(
|
|||
Done:
|
||||
// Release our reference only after the map has been associated with the program.
|
||||
for (uint32_t map_index2 = 0; map_index2 < map_index; map_index2++) {
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)map_addresses[map_index2]);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)map_addresses[map_index2]);
|
||||
}
|
||||
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)program);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)program);
|
||||
EBPF_RETURN_RESULT(return_value);
|
||||
}
|
||||
|
||||
|
@ -518,7 +520,7 @@ ebpf_core_create_map(
|
|||
retval = EBPF_SUCCESS;
|
||||
|
||||
Done:
|
||||
ebpf_object_release_reference(map_object);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE(map_object);
|
||||
EBPF_RETURN_RESULT(retval);
|
||||
}
|
||||
|
||||
|
@ -727,7 +729,7 @@ _ebpf_core_protocol_map_find_element(
|
|||
size_t value_length;
|
||||
size_t key_length;
|
||||
|
||||
retval = ebpf_object_reference_by_handle(request->handle, EBPF_OBJECT_MAP, (ebpf_core_object_t**)&map);
|
||||
retval = EBPF_OBJECT_REFERENCE_BY_HANDLE(request->handle, EBPF_OBJECT_MAP, (ebpf_core_object_t**)&map);
|
||||
if (retval != EBPF_SUCCESS) {
|
||||
goto Done;
|
||||
}
|
||||
|
@ -759,7 +761,7 @@ _ebpf_core_protocol_map_find_element(
|
|||
reply->header.length = reply_length;
|
||||
|
||||
Done:
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)map);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)map);
|
||||
EBPF_RETURN_RESULT(retval);
|
||||
}
|
||||
|
||||
|
@ -772,7 +774,7 @@ _ebpf_core_protocol_map_update_element(_In_ const ebpf_operation_map_update_elem
|
|||
size_t value_length;
|
||||
size_t key_length;
|
||||
|
||||
retval = ebpf_object_reference_by_handle(request->handle, EBPF_OBJECT_MAP, (ebpf_core_object_t**)&map);
|
||||
retval = EBPF_OBJECT_REFERENCE_BY_HANDLE(request->handle, EBPF_OBJECT_MAP, (ebpf_core_object_t**)&map);
|
||||
if (retval != EBPF_SUCCESS) {
|
||||
goto Done;
|
||||
}
|
||||
|
@ -796,7 +798,7 @@ _ebpf_core_protocol_map_update_element(_In_ const ebpf_operation_map_update_elem
|
|||
map, key_length, request->data, value_length, request->data + key_length, request->option, 0);
|
||||
|
||||
Done:
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)map);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)map);
|
||||
EBPF_RETURN_RESULT(retval);
|
||||
}
|
||||
|
||||
|
@ -809,7 +811,7 @@ _ebpf_core_protocol_map_update_element_with_handle(
|
|||
ebpf_map_t* map = NULL;
|
||||
size_t key_length;
|
||||
|
||||
retval = ebpf_object_reference_by_handle(request->map_handle, EBPF_OBJECT_MAP, (ebpf_core_object_t**)&map);
|
||||
retval = EBPF_OBJECT_REFERENCE_BY_HANDLE(request->map_handle, EBPF_OBJECT_MAP, (ebpf_core_object_t**)&map);
|
||||
if (retval != EBPF_SUCCESS) {
|
||||
goto Done;
|
||||
}
|
||||
|
@ -825,7 +827,7 @@ _ebpf_core_protocol_map_update_element_with_handle(
|
|||
retval = ebpf_map_update_entry_with_handle(map, key_length, request->key, request->value_handle, request->option);
|
||||
|
||||
Done:
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)map);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)map);
|
||||
EBPF_RETURN_RESULT(retval);
|
||||
}
|
||||
|
||||
|
@ -837,7 +839,7 @@ _ebpf_core_protocol_map_delete_element(_In_ const ebpf_operation_map_delete_elem
|
|||
ebpf_map_t* map = NULL;
|
||||
size_t key_length;
|
||||
|
||||
retval = ebpf_object_reference_by_handle(request->handle, EBPF_OBJECT_MAP, (ebpf_core_object_t**)&map);
|
||||
retval = EBPF_OBJECT_REFERENCE_BY_HANDLE(request->handle, EBPF_OBJECT_MAP, (ebpf_core_object_t**)&map);
|
||||
if (retval != EBPF_SUCCESS) {
|
||||
goto Done;
|
||||
}
|
||||
|
@ -851,7 +853,7 @@ _ebpf_core_protocol_map_delete_element(_In_ const ebpf_operation_map_delete_elem
|
|||
retval = ebpf_map_delete_entry(map, key_length, request->key, 0);
|
||||
|
||||
Done:
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)map);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)map);
|
||||
EBPF_RETURN_RESULT(retval);
|
||||
}
|
||||
|
||||
|
@ -867,7 +869,7 @@ _ebpf_core_protocol_map_get_next_key(
|
|||
size_t previous_key_length;
|
||||
size_t next_key_length;
|
||||
|
||||
retval = ebpf_object_reference_by_handle(request->handle, EBPF_OBJECT_MAP, (ebpf_core_object_t**)&map);
|
||||
retval = EBPF_OBJECT_REFERENCE_BY_HANDLE(request->handle, EBPF_OBJECT_MAP, (ebpf_core_object_t**)&map);
|
||||
if (retval != EBPF_SUCCESS) {
|
||||
goto Done;
|
||||
}
|
||||
|
@ -904,7 +906,7 @@ _ebpf_core_protocol_map_get_next_key(
|
|||
reply->header.length = reply_length;
|
||||
|
||||
Done:
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)map);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)map);
|
||||
|
||||
EBPF_RETURN_RESULT(retval);
|
||||
}
|
||||
|
@ -938,7 +940,7 @@ _ebpf_core_protocol_program_test_run_complete(
|
|||
}
|
||||
|
||||
ebpf_async_complete(async_context, reply->header.length, result);
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)program);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)program);
|
||||
ebpf_free((void*)options);
|
||||
}
|
||||
|
||||
|
@ -971,7 +973,7 @@ _ebpf_core_protocol_program_test_run(
|
|||
}
|
||||
|
||||
retval =
|
||||
ebpf_object_reference_by_handle(request->program_handle, EBPF_OBJECT_PROGRAM, (ebpf_core_object_t**)&program);
|
||||
EBPF_OBJECT_REFERENCE_BY_HANDLE(request->program_handle, EBPF_OBJECT_PROGRAM, (ebpf_core_object_t**)&program);
|
||||
if (retval != EBPF_SUCCESS) {
|
||||
goto Done;
|
||||
}
|
||||
|
@ -1002,7 +1004,7 @@ _ebpf_core_protocol_program_test_run(
|
|||
Done:
|
||||
if (retval != EBPF_PENDING) {
|
||||
ebpf_free(options);
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)program);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)program);
|
||||
}
|
||||
EBPF_RETURN_RESULT(retval);
|
||||
}
|
||||
|
@ -1021,7 +1023,7 @@ _ebpf_core_protocol_query_program_info(
|
|||
ebpf_utf8_string_t section_name = {0};
|
||||
ebpf_code_type_t code_type;
|
||||
|
||||
retval = ebpf_object_reference_by_handle(request->handle, EBPF_OBJECT_PROGRAM, (ebpf_core_object_t**)&program);
|
||||
retval = EBPF_OBJECT_REFERENCE_BY_HANDLE(request->handle, EBPF_OBJECT_PROGRAM, (ebpf_core_object_t**)&program);
|
||||
if (retval != EBPF_SUCCESS) {
|
||||
goto Done;
|
||||
}
|
||||
|
@ -1068,7 +1070,7 @@ Done:
|
|||
ebpf_utf8_string_free(&file_name);
|
||||
ebpf_utf8_string_free(§ion_name);
|
||||
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)program);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)program);
|
||||
|
||||
EBPF_RETURN_RESULT(retval);
|
||||
}
|
||||
|
@ -1084,7 +1086,7 @@ ebpf_core_update_pinning(const ebpf_handle_t handle, _In_ const ebpf_utf8_string
|
|||
retval = ebpf_pinning_table_delete(_ebpf_core_map_pinning_table, path);
|
||||
goto Done;
|
||||
} else {
|
||||
retval = ebpf_object_reference_by_handle(handle, EBPF_OBJECT_UNKNOWN, (ebpf_core_object_t**)&object);
|
||||
retval = EBPF_OBJECT_REFERENCE_BY_HANDLE(handle, EBPF_OBJECT_UNKNOWN, (ebpf_core_object_t**)&object);
|
||||
if (retval != EBPF_SUCCESS) {
|
||||
goto Done;
|
||||
}
|
||||
|
@ -1092,7 +1094,7 @@ ebpf_core_update_pinning(const ebpf_handle_t handle, _In_ const ebpf_utf8_string
|
|||
retval = ebpf_pinning_table_insert(_ebpf_core_map_pinning_table, path, (ebpf_core_object_t*)object);
|
||||
}
|
||||
Done:
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)object);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)object);
|
||||
|
||||
EBPF_RETURN_RESULT(retval);
|
||||
}
|
||||
|
@ -1135,7 +1137,7 @@ ebpf_core_get_pinned_object(_In_ const ebpf_utf8_string_t* path, _Out_ ebpf_hand
|
|||
retval = ebpf_handle_create(handle, (ebpf_base_object_t*)object);
|
||||
|
||||
Done:
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)object);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)object);
|
||||
EBPF_RETURN_RESULT(retval);
|
||||
}
|
||||
|
||||
|
@ -1162,7 +1164,7 @@ _ebpf_core_protocol_get_pinned_object(
|
|||
retval = ebpf_core_get_pinned_object(&path, &reply->handle);
|
||||
|
||||
Done:
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)object);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)object);
|
||||
EBPF_RETURN_RESULT(retval);
|
||||
}
|
||||
|
||||
|
@ -1177,7 +1179,7 @@ _ebpf_core_protocol_link_program(
|
|||
ebpf_code_type_t code_type;
|
||||
|
||||
retval =
|
||||
ebpf_object_reference_by_handle(request->program_handle, EBPF_OBJECT_PROGRAM, (ebpf_core_object_t**)&program);
|
||||
EBPF_OBJECT_REFERENCE_BY_HANDLE(request->program_handle, EBPF_OBJECT_PROGRAM, (ebpf_core_object_t**)&program);
|
||||
if (retval != EBPF_SUCCESS) {
|
||||
goto Done;
|
||||
}
|
||||
|
@ -1214,8 +1216,8 @@ Done:
|
|||
if (retval != EBPF_SUCCESS && link) {
|
||||
ebpf_link_detach_program(link);
|
||||
}
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)program);
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)link);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)program);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)link);
|
||||
EBPF_RETURN_RESULT(retval);
|
||||
}
|
||||
|
||||
|
@ -1246,9 +1248,9 @@ _ebpf_core_find_matching_link(
|
|||
// Enumerate all link objects starting with previous_object.
|
||||
while (TRUE) {
|
||||
struct bpf_link_info info = {0};
|
||||
ebpf_object_reference_next_object(previous_object, EBPF_OBJECT_LINK, (ebpf_core_object_t**)&local_link);
|
||||
EBPF_OBJECT_REFERENCE_NEXT_OBJECT(previous_object, EBPF_OBJECT_LINK, (ebpf_core_object_t**)&local_link);
|
||||
if (previous_object != NULL) {
|
||||
ebpf_object_release_reference(previous_object);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE(previous_object);
|
||||
}
|
||||
if (local_link == NULL) {
|
||||
// No more links.
|
||||
|
@ -1275,15 +1277,15 @@ _ebpf_core_find_matching_link(
|
|||
// Compare program id.
|
||||
if (program_handle != ebpf_handle_invalid) {
|
||||
ebpf_core_object_t* program = NULL;
|
||||
result = ebpf_object_reference_by_handle(program_handle, EBPF_OBJECT_PROGRAM, &program);
|
||||
result = EBPF_OBJECT_REFERENCE_BY_HANDLE(program_handle, EBPF_OBJECT_PROGRAM, &program);
|
||||
if (result != EBPF_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
if (info.prog_id != program->id) {
|
||||
ebpf_object_release_reference(program);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE(program);
|
||||
continue;
|
||||
}
|
||||
ebpf_object_release_reference(program);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE(program);
|
||||
}
|
||||
|
||||
match_found = TRUE;
|
||||
|
@ -1306,7 +1308,7 @@ _ebpf_core_protocol_unlink_program(_In_ const ebpf_operation_unlink_program_requ
|
|||
ebpf_link_t* link = NULL;
|
||||
|
||||
if (request->link_handle != ebpf_handle_invalid) {
|
||||
retval = ebpf_object_reference_by_handle(request->link_handle, EBPF_OBJECT_LINK, (ebpf_core_object_t**)&link);
|
||||
retval = EBPF_OBJECT_REFERENCE_BY_HANDLE(request->link_handle, EBPF_OBJECT_LINK, (ebpf_core_object_t**)&link);
|
||||
if (retval != EBPF_SUCCESS) {
|
||||
goto Done;
|
||||
}
|
||||
|
@ -1345,7 +1347,7 @@ _ebpf_core_protocol_unlink_program(_In_ const ebpf_operation_unlink_program_requ
|
|||
}
|
||||
|
||||
Done:
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)link);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)link);
|
||||
EBPF_RETURN_RESULT(retval);
|
||||
}
|
||||
|
||||
|
@ -1394,7 +1396,7 @@ _ebpf_core_protocol_get_program_info(
|
|||
goto Done;
|
||||
}
|
||||
} else {
|
||||
retval = ebpf_object_reference_by_handle(
|
||||
retval = EBPF_OBJECT_REFERENCE_BY_HANDLE(
|
||||
request->program_handle, EBPF_OBJECT_PROGRAM, (ebpf_core_object_t**)&program);
|
||||
if (retval != EBPF_SUCCESS) {
|
||||
goto Done;
|
||||
|
@ -1422,7 +1424,7 @@ _ebpf_core_protocol_get_program_info(
|
|||
|
||||
Done:
|
||||
ebpf_program_free_program_info(program_info);
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)program);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)program);
|
||||
EBPF_RETURN_RESULT(retval);
|
||||
}
|
||||
|
||||
|
@ -1555,13 +1557,13 @@ ebpf_core_get_handle_by_id(ebpf_object_type_t type, ebpf_id_t id, _Out_ ebpf_han
|
|||
{
|
||||
EBPF_LOG_ENTRY();
|
||||
ebpf_core_object_t* object;
|
||||
ebpf_result_t result = ebpf_object_reference_by_id(id, type, &object);
|
||||
ebpf_result_t result = EBPF_OBJECT_REFERENCE_BY_ID(id, type, &object);
|
||||
if (result != EBPF_SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = ebpf_handle_create(handle, (ebpf_base_object_t*)object);
|
||||
ebpf_object_release_reference(object);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE(object);
|
||||
|
||||
EBPF_RETURN_RESULT(result);
|
||||
}
|
||||
|
@ -1676,12 +1678,12 @@ _ebpf_core_protocol_bind_map(_In_ const ebpf_operation_bind_map_request_t* reque
|
|||
ebpf_map_t* map = NULL;
|
||||
|
||||
result =
|
||||
ebpf_object_reference_by_handle(request->program_handle, EBPF_OBJECT_PROGRAM, (ebpf_core_object_t**)&program);
|
||||
EBPF_OBJECT_REFERENCE_BY_HANDLE(request->program_handle, EBPF_OBJECT_PROGRAM, (ebpf_core_object_t**)&program);
|
||||
if (result != EBPF_SUCCESS) {
|
||||
goto Done;
|
||||
}
|
||||
|
||||
result = ebpf_object_reference_by_handle(request->map_handle, EBPF_OBJECT_MAP, (ebpf_core_object_t**)&map);
|
||||
result = EBPF_OBJECT_REFERENCE_BY_HANDLE(request->map_handle, EBPF_OBJECT_MAP, (ebpf_core_object_t**)&map);
|
||||
if (result != EBPF_SUCCESS) {
|
||||
goto Done;
|
||||
}
|
||||
|
@ -1690,10 +1692,10 @@ _ebpf_core_protocol_bind_map(_In_ const ebpf_operation_bind_map_request_t* reque
|
|||
|
||||
Done:
|
||||
if (program) {
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)program);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)program);
|
||||
}
|
||||
if (map) {
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)map);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)map);
|
||||
}
|
||||
EBPF_RETURN_RESULT(result);
|
||||
}
|
||||
|
@ -1708,7 +1710,7 @@ _ebpf_core_protocol_get_object_info(
|
|||
uint16_t info_size = reply_length - FIELD_OFFSET(ebpf_operation_get_object_info_reply_t, info);
|
||||
|
||||
ebpf_core_object_t* object;
|
||||
ebpf_result_t result = ebpf_object_reference_by_handle(request->handle, EBPF_OBJECT_UNKNOWN, &object);
|
||||
ebpf_result_t result = EBPF_OBJECT_REFERENCE_BY_HANDLE(request->handle, EBPF_OBJECT_UNKNOWN, &object);
|
||||
if (result != EBPF_SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
|
@ -1729,7 +1731,7 @@ _ebpf_core_protocol_get_object_info(
|
|||
if (result == EBPF_SUCCESS) {
|
||||
reply->header.length = FIELD_OFFSET(ebpf_operation_get_object_info_reply_t, info) + info_size;
|
||||
}
|
||||
ebpf_object_release_reference(object);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE(object);
|
||||
EBPF_RETURN_RESULT(result);
|
||||
}
|
||||
|
||||
|
@ -1742,7 +1744,7 @@ _ebpf_core_protocol_ring_buffer_map_query_buffer(
|
|||
|
||||
ebpf_map_t* map = NULL;
|
||||
ebpf_result_t result =
|
||||
ebpf_object_reference_by_handle(request->map_handle, EBPF_OBJECT_MAP, (ebpf_core_object_t**)&map);
|
||||
EBPF_OBJECT_REFERENCE_BY_HANDLE(request->map_handle, EBPF_OBJECT_MAP, (ebpf_core_object_t**)&map);
|
||||
if (result != EBPF_SUCCESS) {
|
||||
goto Exit;
|
||||
}
|
||||
|
@ -1755,7 +1757,7 @@ _ebpf_core_protocol_ring_buffer_map_query_buffer(
|
|||
result = ebpf_ring_buffer_map_query_buffer(map, (uint8_t**)(uintptr_t*)&reply->buffer_address);
|
||||
|
||||
Exit:
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)map);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)map);
|
||||
EBPF_RETURN_RESULT(result);
|
||||
}
|
||||
|
||||
|
@ -1772,7 +1774,7 @@ _ebpf_core_protocol_ring_buffer_map_async_query(
|
|||
bool reference_taken = FALSE;
|
||||
|
||||
ebpf_result_t result =
|
||||
ebpf_object_reference_by_handle(request->map_handle, EBPF_OBJECT_MAP, (ebpf_core_object_t**)&map);
|
||||
EBPF_OBJECT_REFERENCE_BY_HANDLE(request->map_handle, EBPF_OBJECT_MAP, (ebpf_core_object_t**)&map);
|
||||
if (result != EBPF_SUCCESS) {
|
||||
goto Exit;
|
||||
}
|
||||
|
@ -1795,7 +1797,7 @@ _ebpf_core_protocol_ring_buffer_map_async_query(
|
|||
|
||||
Exit:
|
||||
if (reference_taken) {
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)map);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)map);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -2494,7 +2496,7 @@ ebpf_core_close_context(_In_opt_ void* context)
|
|||
ebpf_epoch_state_t* epoch_state = ebpf_epoch_enter();
|
||||
|
||||
ebpf_core_object_t* object = (ebpf_core_object_t*)context;
|
||||
object->base.release_reference(object);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE_INDIRECT((&object->base));
|
||||
|
||||
ebpf_epoch_exit(epoch_state);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// Copyright (c) Microsoft Corporation
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#define EBPF_FILE_ID EBPF_FILE_ID_LINK
|
||||
|
||||
#include "ebpf_core.h"
|
||||
#include "ebpf_epoch.h"
|
||||
#include "ebpf_handle.h"
|
||||
|
@ -136,7 +138,7 @@ ebpf_link_create(
|
|||
|
||||
// Note: This must be the last thing done in this function as it inserts the object into the global list.
|
||||
// After this point, the object can be accessed by other threads.
|
||||
ebpf_result_t result = ebpf_object_initialize(&local_link->object, EBPF_OBJECT_LINK, _ebpf_link_free, NULL);
|
||||
ebpf_result_t result = EBPF_OBJECT_INITIALIZE(&local_link->object, EBPF_OBJECT_LINK, _ebpf_link_free, NULL);
|
||||
if (result != EBPF_SUCCESS) {
|
||||
retval = EBPF_NO_MEMORY;
|
||||
goto Exit;
|
||||
|
@ -310,7 +312,7 @@ ebpf_link_detach_program(_Inout_ ebpf_link_t* link)
|
|||
ebpf_program_t* program = NULL;
|
||||
bool link_is_detaching = false;
|
||||
|
||||
ebpf_object_acquire_reference((ebpf_core_object_t*)link);
|
||||
EBPF_OBJECT_ACQUIRE_REFERENCE((ebpf_core_object_t*)link);
|
||||
|
||||
state = ebpf_lock_lock(&link->attach_lock);
|
||||
|
||||
|
@ -351,7 +353,7 @@ ebpf_link_detach_program(_Inout_ ebpf_link_t* link)
|
|||
ebpf_lock_unlock(&link->attach_lock, state);
|
||||
|
||||
Done:
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)link);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)link);
|
||||
|
||||
EBPF_RETURN_VOID();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// Copyright (c) Microsoft Corporation
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#define EBPF_FILE_ID EBPF_FILE_ID_MAPS
|
||||
|
||||
#include "ebpf_async.h"
|
||||
#include "ebpf_bitmap.h"
|
||||
#include "ebpf_epoch.h"
|
||||
|
@ -454,7 +456,7 @@ _associate_inner_map(_Inout_ ebpf_core_object_map_t* object_map, ebpf_handle_t i
|
|||
}
|
||||
|
||||
// Convert value handle to an object pointer.
|
||||
result = ebpf_object_reference_by_handle(inner_map_handle, EBPF_OBJECT_MAP, &inner_map_template_object);
|
||||
result = EBPF_OBJECT_REFERENCE_BY_HANDLE(inner_map_handle, EBPF_OBJECT_MAP, &inner_map_template_object);
|
||||
if (result != EBPF_SUCCESS) {
|
||||
EBPF_LOG_MESSAGE_NTSTATUS(
|
||||
EBPF_TRACELOG_LEVEL_ERROR, EBPF_TRACELOG_KEYWORD_MAP, "Get object ref by handle failed.", result);
|
||||
|
@ -469,7 +471,7 @@ _associate_inner_map(_Inout_ ebpf_core_object_map_t* object_map, ebpf_handle_t i
|
|||
|
||||
Exit:
|
||||
if (inner_map_template_object) {
|
||||
ebpf_object_release_reference(inner_map_template_object);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE(inner_map_template_object);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -482,7 +484,7 @@ _delete_object_array_map(_Inout_ _Post_invalid_ ebpf_core_map_t* map, ebpf_objec
|
|||
for (uint32_t i = 0; i < map->ebpf_map_definition.max_entries; i++) {
|
||||
ebpf_id_t id = *(ebpf_id_t*)&map->data[i * map->ebpf_map_definition.value_size];
|
||||
if (id) {
|
||||
ebpf_assert_success(ebpf_object_release_id_reference(id, value_type));
|
||||
ebpf_assert_success(EBPF_OBJECT_RELEASE_ID_REFERENCE(id, value_type));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -659,7 +661,7 @@ _update_array_map_entry_with_handle(
|
|||
|
||||
ebpf_core_object_t* value_object = NULL;
|
||||
if (value_handle != (uintptr_t)ebpf_handle_invalid) {
|
||||
result = ebpf_object_reference_by_handle(value_handle, value_type, &value_object);
|
||||
result = EBPF_OBJECT_REFERENCE_BY_HANDLE(value_handle, value_type, &value_object);
|
||||
if (result != EBPF_SUCCESS) {
|
||||
EBPF_LOG_MESSAGE_UINT64_UINT64(
|
||||
EBPF_TRACELOG_LEVEL_ERROR,
|
||||
|
@ -696,7 +698,7 @@ _update_array_map_entry_with_handle(
|
|||
|
||||
// Release the reference on the old ID's id table entry. The object may have been already deleted, so an
|
||||
// error return value of 'stale id' is ok.
|
||||
result = ebpf_object_release_id_reference(old_id, value_type);
|
||||
result = EBPF_OBJECT_RELEASE_ID_REFERENCE(old_id, value_type);
|
||||
ebpf_assert(result == EBPF_SUCCESS || result == EBPF_STALE_ID);
|
||||
if (result == EBPF_STALE_ID) {
|
||||
result = EBPF_SUCCESS;
|
||||
|
@ -707,7 +709,7 @@ _update_array_map_entry_with_handle(
|
|||
|
||||
// Acquire a reference to the id table entry for the new incoming id. This operation _cannot_ fail as we
|
||||
// already have a valid pointer to the object. A failure here is indicative of a fatal internal error.
|
||||
ebpf_assert_success(ebpf_object_acquire_id_reference(value_object->id, value_type));
|
||||
ebpf_assert_success(EBPF_OBJECT_ACQUIRE_ID_REFERENCE(value_object->id, value_type));
|
||||
}
|
||||
|
||||
// Note that this could be an 'update to erase' operation where we don't have a valid (incoming) object. In this
|
||||
|
@ -724,7 +726,7 @@ Done:
|
|||
// use the id to get to the object, as and when required. Note that this is with the explicit understanding
|
||||
// that the object may well have been since destroyed by the time we actually need to use this id. This is
|
||||
// perfectly valid and something we need to be prepared for.
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)value_object);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)value_object);
|
||||
}
|
||||
|
||||
if (locked) {
|
||||
|
@ -764,7 +766,7 @@ _delete_array_map_entry_with_reference(
|
|||
if (id) {
|
||||
|
||||
// The object may have been already deleted, so an error return value of 'stale id' is ok.
|
||||
result = ebpf_object_release_id_reference(id, value_type);
|
||||
result = EBPF_OBJECT_RELEASE_ID_REFERENCE(id, value_type);
|
||||
ebpf_assert(result == EBPF_SUCCESS || result == EBPF_STALE_ID);
|
||||
if (result == EBPF_STALE_ID) {
|
||||
result = EBPF_SUCCESS;
|
||||
|
@ -819,7 +821,7 @@ _get_object_from_array_map_entry(_Inout_ ebpf_core_map_t* map, _In_ const uint8_
|
|||
|
||||
// Note that this call might fail and that's fine. The id might be valid, but the object might have been
|
||||
// since deleted.
|
||||
(void)ebpf_object_reference_by_id(id, value_type, &object);
|
||||
(void)EBPF_OBJECT_REFERENCE_BY_ID(id, value_type, &object);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -921,7 +923,7 @@ _delete_object_hash_map(_In_ _Post_invalid_ ebpf_core_map_t* map)
|
|||
if (id) {
|
||||
|
||||
// The object may have been already deleted, so an error return value of 'stale id' is ok.
|
||||
result = ebpf_object_release_id_reference(id, EBPF_OBJECT_MAP);
|
||||
result = EBPF_OBJECT_RELEASE_ID_REFERENCE(id, EBPF_OBJECT_MAP);
|
||||
ebpf_assert(result == EBPF_SUCCESS || result == EBPF_STALE_ID);
|
||||
if (result == EBPF_STALE_ID) {
|
||||
result = EBPF_SUCCESS;
|
||||
|
@ -1300,7 +1302,7 @@ _get_object_from_hash_map_entry(_In_ ebpf_core_map_t* map, _In_ const uint8_t* k
|
|||
uint8_t* value = NULL;
|
||||
if (_find_hash_map_entry(map, key, false, &value) == EBPF_SUCCESS) {
|
||||
ebpf_id_t id = *(ebpf_id_t*)value;
|
||||
(void)ebpf_object_reference_by_id(id, EBPF_OBJECT_MAP, &object);
|
||||
(void)EBPF_OBJECT_REFERENCE_BY_ID(id, EBPF_OBJECT_MAP, &object);
|
||||
}
|
||||
|
||||
ebpf_lock_unlock(&object_map->lock, lock_state);
|
||||
|
@ -1390,7 +1392,7 @@ _update_hash_map_entry_with_handle(
|
|||
|
||||
ebpf_core_object_map_t* object_map = EBPF_FROM_FIELD(ebpf_core_object_map_t, core_map, map);
|
||||
ebpf_core_object_t* value_object = NULL;
|
||||
result = ebpf_object_reference_by_handle(value_handle, value_type, &value_object);
|
||||
result = EBPF_OBJECT_REFERENCE_BY_HANDLE(value_handle, value_type, &value_object);
|
||||
if (result != EBPF_SUCCESS) {
|
||||
EBPF_LOG_MESSAGE_UINT64_UINT64(
|
||||
EBPF_TRACELOG_LEVEL_ERROR,
|
||||
|
@ -1428,7 +1430,7 @@ _update_hash_map_entry_with_handle(
|
|||
|
||||
// Release the reference on the old ID's id table entry. The object may already have been deleted, so an
|
||||
// error return value of 'stale id' is ok.
|
||||
result = ebpf_object_release_id_reference(old_id, value_type);
|
||||
result = EBPF_OBJECT_RELEASE_ID_REFERENCE(old_id, value_type);
|
||||
ebpf_assert(result == EBPF_SUCCESS || result == EBPF_STALE_ID);
|
||||
if (result == EBPF_STALE_ID) {
|
||||
result = EBPF_SUCCESS;
|
||||
|
@ -1446,11 +1448,11 @@ _update_hash_map_entry_with_handle(
|
|||
|
||||
// Acquire a reference to the id table entry for the new incoming id. This operation _cannot_ fail as we already
|
||||
// have a valid pointer to the object. A failure here is indicative of a fatal internal error.
|
||||
ebpf_assert_success(ebpf_object_acquire_id_reference(value_object->id, value_type));
|
||||
ebpf_assert_success(EBPF_OBJECT_ACQUIRE_ID_REFERENCE(value_object->id, value_type));
|
||||
|
||||
Done:
|
||||
if (value_object != NULL) {
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)value_object);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)value_object);
|
||||
}
|
||||
ebpf_lock_unlock(&object_map->lock, lock_state);
|
||||
return result;
|
||||
|
@ -1480,7 +1482,7 @@ _delete_map_hash_map_entry(_Inout_ ebpf_core_map_t* map, _In_ const uint8_t* key
|
|||
if (id) {
|
||||
|
||||
// The object may have been already deleted, so an error return value of 'stale id' is ok.
|
||||
result = ebpf_object_release_id_reference(id, EBPF_OBJECT_MAP);
|
||||
result = EBPF_OBJECT_RELEASE_ID_REFERENCE(id, EBPF_OBJECT_MAP);
|
||||
ebpf_assert(result == EBPF_SUCCESS || result == EBPF_STALE_ID);
|
||||
if (result == EBPF_STALE_ID) {
|
||||
result = EBPF_SUCCESS;
|
||||
|
@ -2289,7 +2291,7 @@ ebpf_map_create(
|
|||
|
||||
const ebpf_map_metadata_table_t* table = &ebpf_map_metadata_tables[local_map->ebpf_map_definition.type];
|
||||
ebpf_object_get_program_type_t get_program_type = (table->get_object_from_entry) ? _get_map_program_type : NULL;
|
||||
result = ebpf_object_initialize(&local_map->object, EBPF_OBJECT_MAP, _ebpf_map_delete, get_program_type);
|
||||
result = EBPF_OBJECT_INITIALIZE(&local_map->object, EBPF_OBJECT_MAP, _ebpf_map_delete, get_program_type);
|
||||
if (result != EBPF_SUCCESS) {
|
||||
goto Exit;
|
||||
}
|
||||
|
@ -2360,7 +2362,7 @@ ebpf_map_find_entry(
|
|||
// Release the extra reference obtained.
|
||||
// REVIEW: is this safe?
|
||||
if (object) {
|
||||
ebpf_object_release_reference(object);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE(object);
|
||||
return_value = (uint8_t*)object;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// Copyright (c) Microsoft Corporation
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#define EBPF_FILE_ID EBPF_FILE_ID_NATIVE
|
||||
|
||||
#include "ebpf_core.h"
|
||||
#include "ebpf_handle.h"
|
||||
#include "ebpf_native.h"
|
||||
|
@ -202,10 +204,10 @@ _ebpf_native_clean_up_programs(
|
|||
for (uint32_t i = 0; i < count_of_programs; i++) {
|
||||
if (programs[i].handle != ebpf_handle_invalid) {
|
||||
ebpf_program_t* program_object = NULL;
|
||||
ebpf_assert_success(ebpf_object_reference_by_handle(
|
||||
ebpf_assert_success(EBPF_OBJECT_REFERENCE_BY_HANDLE(
|
||||
programs[i].handle, EBPF_OBJECT_PROGRAM, (ebpf_core_object_t**)&program_object));
|
||||
ebpf_assert_success(ebpf_program_register_for_helper_changes(program_object, NULL, NULL));
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)program_object);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)program_object);
|
||||
if (close_handles) {
|
||||
ebpf_assert_success(ebpf_handle_close(programs[i].handle));
|
||||
programs[i].handle = ebpf_handle_invalid;
|
||||
|
@ -377,6 +379,23 @@ ebpf_native_terminate()
|
|||
EBPF_RETURN_VOID();
|
||||
}
|
||||
|
||||
void
|
||||
ebpf_object_update_reference_history(void* object, bool acquire, uint32_t file_id, uint32_t line);
|
||||
|
||||
static void
|
||||
_ebpf_native_acquire_reference_internal(void* base_object, ebpf_file_id_t file_id, uint32_t line)
|
||||
{
|
||||
ebpf_object_update_reference_history(base_object, true, file_id, line);
|
||||
ebpf_native_acquire_reference(base_object);
|
||||
}
|
||||
|
||||
static void
|
||||
_ebpf_native_release_reference_internal(void* base_object, ebpf_file_id_t file_id, uint32_t line)
|
||||
{
|
||||
ebpf_object_update_reference_history(base_object, false, file_id, line);
|
||||
ebpf_native_release_reference(base_object);
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
_ebpf_native_provider_attach_client_callback(
|
||||
HANDLE nmr_binding_handle,
|
||||
|
@ -438,8 +457,8 @@ _ebpf_native_provider_attach_client_callback(
|
|||
|
||||
ebpf_lock_create(&client_context->lock);
|
||||
client_context->base.marker = _ebpf_native_marker;
|
||||
client_context->base.acquire_reference = ebpf_native_acquire_reference;
|
||||
client_context->base.release_reference = ebpf_native_release_reference;
|
||||
client_context->base.acquire_reference = _ebpf_native_acquire_reference_internal;
|
||||
client_context->base.release_reference = _ebpf_native_release_reference_internal;
|
||||
// Acquire "attach" reference. Released when detach is called for this module.
|
||||
client_context->base.reference_count = 1;
|
||||
client_context->client_module_id = *client_module_id;
|
||||
|
@ -702,7 +721,7 @@ _ebpf_native_validate_map(_In_ const ebpf_native_map_t* map, ebpf_handle_t origi
|
|||
ebpf_core_object_t* object;
|
||||
ebpf_handle_t inner_map_handle = ebpf_handle_invalid;
|
||||
uint16_t info_size = (uint16_t)sizeof(info);
|
||||
ebpf_result_t result = ebpf_object_reference_by_handle(original_map_handle, EBPF_OBJECT_MAP, &object);
|
||||
ebpf_result_t result = EBPF_OBJECT_REFERENCE_BY_HANDLE(original_map_handle, EBPF_OBJECT_MAP, &object);
|
||||
if (result != EBPF_SUCCESS) {
|
||||
goto Exit;
|
||||
}
|
||||
|
@ -743,7 +762,7 @@ _ebpf_native_validate_map(_In_ const ebpf_native_map_t* map, ebpf_handle_t origi
|
|||
}
|
||||
|
||||
Exit:
|
||||
ebpf_object_release_reference(object);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE(object);
|
||||
EBPF_RETURN_RESULT(result);
|
||||
}
|
||||
|
||||
|
@ -1163,7 +1182,7 @@ _ebpf_native_load_programs(_Inout_ ebpf_native_module_t* module)
|
|||
context->native_program = native_program;
|
||||
|
||||
ebpf_program_t* program_object = NULL;
|
||||
result = ebpf_object_reference_by_handle(
|
||||
result = EBPF_OBJECT_REFERENCE_BY_HANDLE(
|
||||
native_program->handle, EBPF_OBJECT_PROGRAM, (ebpf_core_object_t**)&program_object);
|
||||
if (result != EBPF_SUCCESS) {
|
||||
ebpf_free(context);
|
||||
|
@ -1172,7 +1191,7 @@ _ebpf_native_load_programs(_Inout_ ebpf_native_module_t* module)
|
|||
|
||||
result = ebpf_program_register_for_helper_changes(program_object, _ebpf_native_helper_address_changed, context);
|
||||
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)program_object);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)program_object);
|
||||
|
||||
if (result != EBPF_SUCCESS) {
|
||||
ebpf_free(context);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// Copyright (c) Microsoft Corporation
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#define EBPF_FILE_ID EBPF_FILE_ID_PROGRAM
|
||||
|
||||
#include "bpf_helpers.h"
|
||||
#include "ebpf_async.h"
|
||||
#include "ebpf_core.h"
|
||||
|
@ -252,7 +254,7 @@ _ebpf_program_free(_In_opt_ _Post_invalid_ ebpf_core_object_t* object)
|
|||
ebpf_assert(ebpf_list_is_empty(&program->links));
|
||||
|
||||
for (index = 0; index < program->count_of_maps; index++) {
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)program->maps[index]);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)program->maps[index]);
|
||||
}
|
||||
|
||||
ebpf_epoch_work_item_t* cleanup_work_item = program->cleanup_work_item;
|
||||
|
@ -530,7 +532,7 @@ ebpf_program_create(_In_ const ebpf_program_parameters_t* program_parameters, _O
|
|||
|
||||
// Note: This is performed after initializing the program as it inserts the program into the global list.
|
||||
// From this point on, the program can be found by other threads.
|
||||
retval = ebpf_object_initialize(
|
||||
retval = EBPF_OBJECT_INITIALIZE(
|
||||
&local_program->object, EBPF_OBJECT_PROGRAM, _ebpf_program_free, _ebpf_program_get_program_type);
|
||||
if (retval != EBPF_SUCCESS) {
|
||||
goto Done;
|
||||
|
@ -589,7 +591,7 @@ ebpf_program_associate_additional_map(ebpf_program_t* program, ebpf_map_t* map)
|
|||
goto Done;
|
||||
}
|
||||
|
||||
ebpf_object_acquire_reference((ebpf_core_object_t*)map);
|
||||
EBPF_OBJECT_ACQUIRE_REFERENCE((ebpf_core_object_t*)map);
|
||||
program_maps[map_count - 1] = map;
|
||||
program->maps = program_maps;
|
||||
program->count_of_maps = map_count;
|
||||
|
@ -631,7 +633,7 @@ ebpf_program_associate_maps(ebpf_program_t* program, ebpf_map_t** maps, uint32_t
|
|||
program_maps = NULL;
|
||||
program->count_of_maps = maps_count;
|
||||
for (index = 0; index < maps_count; index++) {
|
||||
ebpf_object_acquire_reference((ebpf_core_object_t*)program->maps[index]);
|
||||
EBPF_OBJECT_ACQUIRE_REFERENCE((ebpf_core_object_t*)program->maps[index]);
|
||||
}
|
||||
ebpf_lock_unlock(&program->lock, state);
|
||||
|
||||
|
@ -1147,7 +1149,7 @@ ebpf_program_invoke(
|
|||
}
|
||||
|
||||
if (state.count != 0) {
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)current_program);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)current_program);
|
||||
current_program = NULL;
|
||||
}
|
||||
|
||||
|
@ -1447,7 +1449,7 @@ ebpf_program_attach_link(_Inout_ ebpf_program_t* program, _Inout_ ebpf_link_t* l
|
|||
{
|
||||
EBPF_LOG_ENTRY();
|
||||
// Acquire "attach" reference on the link object.
|
||||
ebpf_object_acquire_reference((ebpf_core_object_t*)link);
|
||||
EBPF_OBJECT_ACQUIRE_REFERENCE((ebpf_core_object_t*)link);
|
||||
|
||||
// Insert the link in the attach list.
|
||||
ebpf_lock_state_t state;
|
||||
|
@ -1470,7 +1472,7 @@ ebpf_program_detach_link(_Inout_ ebpf_program_t* program, _Inout_ ebpf_link_t* l
|
|||
ebpf_lock_unlock(&program->lock, state);
|
||||
|
||||
// Release the "attach" reference.
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)link);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)link);
|
||||
EBPF_RETURN_VOID();
|
||||
}
|
||||
|
||||
|
@ -1549,7 +1551,7 @@ ebpf_program_create_and_initialize(
|
|||
}
|
||||
|
||||
Done:
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)program);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)program);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// Copyright (c) Microsoft Corporation
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#define EBPF_FILE_ID EBPF_FILE_ID_EXECUTION_CONTEXT_UNIT_TESTS
|
||||
|
||||
#include "catch_wrapper.hpp"
|
||||
#include "ebpf_async.h"
|
||||
#include "ebpf_core.h"
|
||||
|
@ -101,7 +103,7 @@ template <typename T> class ebpf_object_deleter
|
|||
void
|
||||
operator()(T* object)
|
||||
{
|
||||
ebpf_object_release_reference(reinterpret_cast<ebpf_core_object_t*>(object));
|
||||
EBPF_OBJECT_RELEASE_REFERENCE(reinterpret_cast<ebpf_core_object_t*>(object));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -57,6 +57,8 @@ extern "C"
|
|||
*
|
||||
* @param[in] handle Handle to find in table.
|
||||
* @param[out] object Pointer to memory that contains object success.
|
||||
* @param[in] file_id File ID of the caller.
|
||||
* @param[in] line Line number of the caller.
|
||||
* @retval EBPF_SUCCESS The operation was successful.
|
||||
* @retval EBPF_INVALID_OBJECT The provided handle is not valid.
|
||||
*/
|
||||
|
@ -64,7 +66,9 @@ extern "C"
|
|||
ebpf_handle_t handle,
|
||||
_In_opt_ ebpf_compare_object_t compare_function,
|
||||
_In_opt_ const void* context,
|
||||
_Outptr_ struct _ebpf_base_object** object);
|
||||
_Outptr_ struct _ebpf_base_object** object,
|
||||
uint32_t file_id,
|
||||
uint32_t line);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -74,6 +74,70 @@ typedef struct _ebpf_id_entry
|
|||
// case this becomes a hash table.
|
||||
static _Guarded_by_(_ebpf_object_tracking_list_lock) ebpf_id_entry_t _ebpf_id_table[1024];
|
||||
|
||||
/**
|
||||
* @brief An enum of operations that can be performed on an object reference.
|
||||
*/
|
||||
typedef enum _ebpf_object_reference_operationEBPF_OBJECT_INITIALIZE
|
||||
{
|
||||
EBPF_OBJECT_CREATE,
|
||||
EBPF_OBJECT_ACQUIRE,
|
||||
EBPF_OBJECT_RELEASE,
|
||||
EBPF_OBJECT_DESTROY,
|
||||
} ebpf_object_reference_operation_t;
|
||||
|
||||
/**
|
||||
* @brief A history of object references. This is used to track
|
||||
* down the source of a reference leak and use after free bugs.
|
||||
* This is a circular buffer of the last 1024 references with the
|
||||
* next index to write to stored in _ebpf_object_reference_history_index.
|
||||
*/
|
||||
static _Guarded_by_(_ebpf_object_reference_history_lock) struct _ebpf_object_reference_entry
|
||||
{
|
||||
uintptr_t object : 64;
|
||||
ebpf_file_id_t file_id : 16;
|
||||
unsigned int line : 32;
|
||||
ebpf_object_reference_operation_t operation : 16;
|
||||
} _ebpf_object_reference_history[1024];
|
||||
|
||||
/**
|
||||
* @brief The index of the next entry to write to in the reference history.
|
||||
* This is updated atomically using interlocked operations and should be used
|
||||
* modulo count of _ebpf_object_reference_history.
|
||||
*/
|
||||
static _Guarded_by_(_ebpf_object_reference_history_lock) size_t _ebpf_object_reference_history_index = 0;
|
||||
|
||||
static ebpf_lock_t _ebpf_object_reference_history_lock = {0};
|
||||
|
||||
static inline void
|
||||
_update_reference_history(void* object, ebpf_object_reference_operation_t operation, uint32_t file_id, uint32_t line)
|
||||
{
|
||||
ebpf_lock_state_t state = ebpf_lock_lock(&_ebpf_object_reference_history_lock);
|
||||
|
||||
size_t index = _ebpf_object_reference_history_index++;
|
||||
index %= EBPF_COUNT_OF(_ebpf_object_reference_history);
|
||||
|
||||
_ebpf_object_reference_history[index].object = (uintptr_t)object;
|
||||
_ebpf_object_reference_history[index].operation = operation;
|
||||
_ebpf_object_reference_history[index].file_id = file_id;
|
||||
_ebpf_object_reference_history[index].line = line;
|
||||
|
||||
ebpf_lock_unlock(&_ebpf_object_reference_history_lock, state);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add an entry to the reference history.
|
||||
*
|
||||
* @param[in] object Object being referenced.
|
||||
* @param[in] acquire True if this is an acquire reference, false if it is a release reference.
|
||||
* @param[in] file_id Id of the file where the reference was acquired or released.
|
||||
* @param[in] line Line number in the file where the reference was acquired or released.
|
||||
*/
|
||||
void
|
||||
ebpf_object_update_reference_history(void* object, bool acquire, uint32_t file_id, uint32_t line)
|
||||
{
|
||||
_update_reference_history(object, acquire ? EBPF_OBJECT_ACQUIRE : EBPF_OBJECT_RELEASE, file_id, line);
|
||||
}
|
||||
|
||||
// Get the ID last stored at a given index.
|
||||
static inline ebpf_id_t
|
||||
_get_id_from_index(uint32_t index)
|
||||
|
@ -102,7 +166,7 @@ _get_index_from_id(ebpf_id_t id, _Out_ uint32_t* index)
|
|||
}
|
||||
|
||||
static ebpf_result_t
|
||||
_ebpf_object_tracking_list_insert(_Inout_ ebpf_core_object_t* object)
|
||||
_ebpf_object_tracking_list_insert(_Inout_ ebpf_core_object_t* object, ebpf_file_id_t file_id, uint32_t line)
|
||||
{
|
||||
int new_index;
|
||||
ebpf_result_t return_value;
|
||||
|
@ -122,6 +186,7 @@ _ebpf_object_tracking_list_insert(_Inout_ ebpf_core_object_t* object)
|
|||
_ebpf_id_table[new_index].counter++;
|
||||
_ebpf_id_table[new_index].reference_count = 1;
|
||||
_ebpf_id_table[new_index].object = object;
|
||||
_update_reference_history(&_ebpf_id_table[new_index], EBPF_OBJECT_CREATE, file_id, line);
|
||||
object->id = _get_id_from_index(new_index);
|
||||
|
||||
return_value = EBPF_SUCCESS;
|
||||
|
@ -133,7 +198,7 @@ Done:
|
|||
}
|
||||
|
||||
_Requires_lock_held_(&_ebpf_object_tracking_list_lock) static void _ebpf_object_tracking_list_remove(
|
||||
_In_ const ebpf_core_object_t* object)
|
||||
_In_ const ebpf_core_object_t* object, ebpf_file_id_t file_id, uint32_t line)
|
||||
{
|
||||
uint32_t index;
|
||||
ebpf_result_t return_value = _get_index_from_id(object->id, &index);
|
||||
|
@ -144,6 +209,7 @@ _Requires_lock_held_(&_ebpf_object_tracking_list_lock) static void _ebpf_object_
|
|||
|
||||
// Under lock, so un-protected access is ok.
|
||||
_ebpf_id_table[index].reference_count--;
|
||||
_update_reference_history(&_ebpf_id_table[index], EBPF_OBJECT_RELEASE, file_id, line);
|
||||
ebpf_assert(_ebpf_id_table[index].reference_count >= 0);
|
||||
_ebpf_id_table[index].object = NULL;
|
||||
}
|
||||
|
@ -153,6 +219,8 @@ ebpf_object_tracking_initiate()
|
|||
{
|
||||
ebpf_lock_create(&_ebpf_object_tracking_list_lock);
|
||||
memset(_ebpf_id_table, 0, sizeof(_ebpf_id_table));
|
||||
memset(_ebpf_object_reference_history, 0, sizeof(_ebpf_object_reference_history));
|
||||
_ebpf_object_reference_history_index = 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -169,7 +237,9 @@ ebpf_object_initialize(
|
|||
_Inout_ ebpf_core_object_t* object,
|
||||
ebpf_object_type_t object_type,
|
||||
ebpf_free_object_t free_function,
|
||||
ebpf_object_get_program_type_t get_program_type_function)
|
||||
ebpf_object_get_program_type_t get_program_type_function,
|
||||
ebpf_file_id_t file_id,
|
||||
uint32_t line)
|
||||
{
|
||||
EBPF_LOG_MESSAGE_POINTER_ENUM(
|
||||
EBPF_TRACELOG_LEVEL_VERBOSE, EBPF_TRACELOG_KEYWORD_BASE, "eBPF object initialized", object, object_type);
|
||||
|
@ -181,13 +251,15 @@ ebpf_object_initialize(
|
|||
object->free_function = free_function;
|
||||
object->get_program_type = get_program_type_function;
|
||||
ebpf_list_initialize(&object->object_list_entry);
|
||||
_update_reference_history(object, EBPF_OBJECT_CREATE, file_id, line);
|
||||
|
||||
return _ebpf_object_tracking_list_insert(object);
|
||||
return _ebpf_object_tracking_list_insert(object, file_id, line);
|
||||
}
|
||||
|
||||
void
|
||||
ebpf_object_acquire_reference(_Inout_ ebpf_core_object_t* object)
|
||||
ebpf_object_acquire_reference(_Inout_ ebpf_core_object_t* object, uint32_t file_id, uint32_t line)
|
||||
{
|
||||
_update_reference_history(object, EBPF_OBJECT_ACQUIRE, file_id, line);
|
||||
if (object->base.marker != _ebpf_object_marker) {
|
||||
__fastfail(FAST_FAIL_INVALID_ARG);
|
||||
}
|
||||
|
@ -206,7 +278,7 @@ ebpf_object_acquire_reference(_Inout_ ebpf_core_object_t* object)
|
|||
* @retval false Reference was not acquired.
|
||||
*/
|
||||
static bool
|
||||
_ebpf_object_try_acquire_reference(_Inout_ ebpf_base_object_t* object)
|
||||
_ebpf_object_try_acquire_reference(_Inout_ ebpf_base_object_t* object, uint32_t file_id, uint32_t line)
|
||||
{
|
||||
if (object->marker != _ebpf_object_marker) {
|
||||
__fastfail(FAST_FAIL_INVALID_ARG);
|
||||
|
@ -224,15 +296,17 @@ _ebpf_object_try_acquire_reference(_Inout_ ebpf_base_object_t* object)
|
|||
|
||||
if (ebpf_interlocked_compare_exchange_int64(&object->reference_count, new_ref_count + 1, new_ref_count) ==
|
||||
new_ref_count) {
|
||||
_update_reference_history(object, EBPF_OBJECT_ACQUIRE, file_id, line);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ebpf_object_release_reference(_Inout_opt_ ebpf_core_object_t* object)
|
||||
ebpf_object_release_reference(_Inout_opt_ ebpf_core_object_t* object, uint32_t file_id, uint32_t line)
|
||||
{
|
||||
int64_t new_ref_count;
|
||||
_update_reference_history(object, EBPF_OBJECT_RELEASE, file_id, line);
|
||||
|
||||
if (!object) {
|
||||
return;
|
||||
|
@ -254,12 +328,13 @@ ebpf_object_release_reference(_Inout_opt_ ebpf_core_object_t* object)
|
|||
ebpf_lock_state_t state = ebpf_lock_lock(&_ebpf_object_tracking_list_lock);
|
||||
EBPF_LOG_MESSAGE_POINTER_ENUM(
|
||||
EBPF_TRACELOG_LEVEL_VERBOSE, EBPF_TRACELOG_KEYWORD_BASE, "eBPF object terminated", object, object->type);
|
||||
_ebpf_object_tracking_list_remove(object);
|
||||
_ebpf_object_tracking_list_remove(object, file_id, line);
|
||||
ebpf_lock_unlock(&_ebpf_object_tracking_list_lock, state);
|
||||
}
|
||||
|
||||
// Free the object outside the lock.
|
||||
if (new_ref_count == 0) {
|
||||
_update_reference_history(object, EBPF_OBJECT_DESTROY, file_id, line);
|
||||
object->base.marker = ~object->base.marker;
|
||||
object->free_function(object);
|
||||
}
|
||||
|
@ -340,7 +415,9 @@ void
|
|||
ebpf_object_reference_next_object(
|
||||
_In_opt_ const ebpf_core_object_t* previous_object,
|
||||
ebpf_object_type_t type,
|
||||
_Outptr_result_maybenull_ ebpf_core_object_t** next_object)
|
||||
_Outptr_result_maybenull_ ebpf_core_object_t** next_object,
|
||||
uint32_t file_id,
|
||||
uint32_t line)
|
||||
{
|
||||
ebpf_result_t return_value = EBPF_SUCCESS;
|
||||
ebpf_lock_state_t state;
|
||||
|
@ -362,7 +439,7 @@ ebpf_object_reference_next_object(
|
|||
if (_ebpf_id_table[index].object == NULL) {
|
||||
continue;
|
||||
}
|
||||
if (!_ebpf_object_try_acquire_reference(&_ebpf_id_table[index].object->base)) {
|
||||
if (!_ebpf_object_try_acquire_reference(&_ebpf_id_table[index].object->base, file_id, line)) {
|
||||
continue;
|
||||
}
|
||||
*next_object = _ebpf_id_table[index].object;
|
||||
|
@ -370,10 +447,14 @@ ebpf_object_reference_next_object(
|
|||
}
|
||||
|
||||
ebpf_lock_unlock(&_ebpf_object_tracking_list_lock, state);
|
||||
if (*next_object != NULL) {
|
||||
_update_reference_history(*next_object, EBPF_OBJECT_ACQUIRE, file_id, line);
|
||||
}
|
||||
}
|
||||
|
||||
_Must_inspect_result_ ebpf_result_t
|
||||
ebpf_object_reference_by_id(ebpf_id_t id, ebpf_object_type_t object_type, _Outptr_ ebpf_core_object_t** object)
|
||||
ebpf_object_reference_by_id(
|
||||
ebpf_id_t id, ebpf_object_type_t object_type, _Outptr_ ebpf_core_object_t** object, uint32_t file_id, uint32_t line)
|
||||
{
|
||||
ebpf_lock_state_t state = ebpf_lock_lock(&_ebpf_object_tracking_list_lock);
|
||||
|
||||
|
@ -385,7 +466,7 @@ ebpf_object_reference_by_id(ebpf_id_t id, ebpf_object_type_t object_type, _Outpt
|
|||
} else {
|
||||
ebpf_core_object_t* found = _ebpf_id_table[index].object;
|
||||
if ((found != NULL) && (found->type == object_type)) {
|
||||
if (_ebpf_object_try_acquire_reference(&found->base)) {
|
||||
if (_ebpf_object_try_acquire_reference(&found->base, file_id, line)) {
|
||||
*object = found;
|
||||
} else {
|
||||
return_value = EBPF_KEY_NOT_FOUND;
|
||||
|
@ -397,6 +478,9 @@ ebpf_object_reference_by_id(ebpf_id_t id, ebpf_object_type_t object_type, _Outpt
|
|||
}
|
||||
|
||||
ebpf_lock_unlock(&_ebpf_object_tracking_list_lock, state);
|
||||
if (return_value == EBPF_SUCCESS) {
|
||||
_update_reference_history(*object, EBPF_OBJECT_ACQUIRE, file_id, line);
|
||||
}
|
||||
return return_value;
|
||||
}
|
||||
|
||||
|
@ -421,10 +505,14 @@ _ebpf_object_compare(_In_ const ebpf_base_object_t* object, _In_ const void* con
|
|||
|
||||
ebpf_result_t
|
||||
ebpf_object_reference_by_handle(
|
||||
ebpf_handle_t handle, ebpf_object_type_t object_type, _Outptr_ ebpf_core_object_t** object)
|
||||
ebpf_handle_t handle,
|
||||
ebpf_object_type_t object_type,
|
||||
_Outptr_ ebpf_core_object_t** object,
|
||||
uint32_t file_id,
|
||||
uint32_t line)
|
||||
{
|
||||
return ebpf_reference_base_object_by_handle(
|
||||
handle, _ebpf_object_compare, &object_type, (ebpf_base_object_t**)object);
|
||||
handle, _ebpf_object_compare, &object_type, (ebpf_base_object_t**)object, file_id, line);
|
||||
}
|
||||
|
||||
_Must_inspect_result_ char*
|
||||
|
@ -440,7 +528,7 @@ ebpf_duplicate_string(_In_z_ const char* source)
|
|||
}
|
||||
|
||||
_Must_inspect_result_ ebpf_result_t
|
||||
ebpf_object_acquire_id_reference(ebpf_id_t id, ebpf_object_type_t object_type)
|
||||
ebpf_object_acquire_id_reference(ebpf_id_t id, ebpf_object_type_t object_type, uint32_t file_id, uint32_t line)
|
||||
{
|
||||
ebpf_lock_state_t state = ebpf_lock_lock(&_ebpf_object_tracking_list_lock);
|
||||
|
||||
|
@ -451,20 +539,8 @@ ebpf_object_acquire_id_reference(ebpf_id_t id, ebpf_object_type_t object_type)
|
|||
}
|
||||
|
||||
ebpf_id_entry_t* entry = &_ebpf_id_table[index];
|
||||
ebpf_assert(entry->reference_count);
|
||||
if (entry->reference_count == 0) {
|
||||
if (entry->object == NULL) {
|
||||
|
||||
// Do not allow access to entries that are not in use.
|
||||
result = EBPF_INVALID_ARGUMENT;
|
||||
} else {
|
||||
|
||||
// This can _never_ happen. If the object pointer is not null, the ref-count HAS TO BE _at_ _least_ 1.
|
||||
// This conditon is indicative of a severe internal error.
|
||||
ebpf_assert(0);
|
||||
result = EBPF_FAILED;
|
||||
}
|
||||
goto Done;
|
||||
if (entry->reference_count <= 0) {
|
||||
__fastfail(FAST_FAIL_INVALID_REFERENCE_COUNT);
|
||||
}
|
||||
|
||||
// ref count is non-zero
|
||||
|
@ -487,6 +563,7 @@ ebpf_object_acquire_id_reference(ebpf_id_t id, ebpf_object_type_t object_type)
|
|||
// We're under lock so un-protected access is ok.
|
||||
entry->reference_count++;
|
||||
result = EBPF_SUCCESS;
|
||||
_update_reference_history(entry, EBPF_OBJECT_ACQUIRE, file_id, line);
|
||||
|
||||
Done:
|
||||
ebpf_lock_unlock(&_ebpf_object_tracking_list_lock, state);
|
||||
|
@ -494,7 +571,7 @@ Done:
|
|||
}
|
||||
|
||||
_Must_inspect_result_ ebpf_result_t
|
||||
ebpf_object_release_id_reference(ebpf_id_t id, ebpf_object_type_t object_type)
|
||||
ebpf_object_release_id_reference(ebpf_id_t id, ebpf_object_type_t object_type, uint32_t file_id, uint32_t line)
|
||||
{
|
||||
ebpf_lock_state_t state = ebpf_lock_lock(&_ebpf_object_tracking_list_lock);
|
||||
|
||||
|
@ -505,19 +582,8 @@ ebpf_object_release_id_reference(ebpf_id_t id, ebpf_object_type_t object_type)
|
|||
}
|
||||
|
||||
ebpf_id_entry_t* entry = &_ebpf_id_table[index];
|
||||
ebpf_assert(entry->reference_count);
|
||||
if (entry->reference_count == 0) {
|
||||
if (entry->object == NULL) {
|
||||
|
||||
// Do not allow access to entries that are not in use.
|
||||
result = EBPF_INVALID_ARGUMENT;
|
||||
} else {
|
||||
|
||||
// This can _never_ happen. If the object pointer is not null, the ref-count HAS TO BE _at_ _least_ 1.
|
||||
// This condition is indicative of a severe internal error.
|
||||
result = EBPF_FAILED;
|
||||
}
|
||||
goto Done;
|
||||
if (entry->reference_count <= 0) {
|
||||
__fastfail(FAST_FAIL_INVALID_REFERENCE_COUNT);
|
||||
}
|
||||
|
||||
// ref count is non-zero
|
||||
|
@ -537,8 +603,10 @@ ebpf_object_release_id_reference(ebpf_id_t id, ebpf_object_type_t object_type)
|
|||
entry->reference_count--;
|
||||
ebpf_assert(entry->reference_count >= 0);
|
||||
result = EBPF_SUCCESS;
|
||||
_update_reference_history(entry, EBPF_OBJECT_RELEASE, file_id, line);
|
||||
|
||||
Done:
|
||||
ebpf_lock_unlock(&_ebpf_object_tracking_list_lock, state);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,100 @@ extern "C"
|
|||
{
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Identifier for the file that is referencing the object. Each file that references an object is assigned
|
||||
* a unique identifier. This identifier is used to track the reference count of the object. The file identifier is
|
||||
* recorded in the _ebpf_object_reference_history table along with the line number of the reference. This allows
|
||||
* for tracking down use-after-free bugs and leaks of objects.
|
||||
*/
|
||||
typedef enum _ebpf_file_id
|
||||
{
|
||||
EBPF_FILE_ID_UNKNOWN,
|
||||
EBPF_FILE_ID_CORE,
|
||||
EBPF_FILE_ID_MAPS,
|
||||
EBPF_FILE_ID_LINK,
|
||||
EBPF_FILE_ID_PROGRAM,
|
||||
EBPF_FILE_ID_NATIVE,
|
||||
EBPF_FILE_ID_PINNING_TABLE,
|
||||
EBPF_FILE_ID_HANDLE,
|
||||
EBPF_FILE_ID_EXECUTION_CONTEXT_UNIT_TESTS,
|
||||
EBPF_FILE_ID_PLATFORM_UNIT_TESTS,
|
||||
EBPF_FILE_ID_PERFORMANCE_TESTS,
|
||||
EBPF_FILE_ID_CORE_HELPER_FUZZER,
|
||||
} ebpf_file_id_t;
|
||||
|
||||
/**
|
||||
* @brief Macro to acquire a reference on an object and record the file and line number of the reference.
|
||||
*/
|
||||
#define EBPF_OBJECT_ACQUIRE_REFERENCE(object) ebpf_object_acquire_reference(object, EBPF_FILE_ID, __LINE__)
|
||||
|
||||
/**
|
||||
* @brief Macro to release a reference on an object and record the file and line number of the reference.
|
||||
*/
|
||||
#define EBPF_OBJECT_RELEASE_REFERENCE(object) ebpf_object_release_reference(object, EBPF_FILE_ID, __LINE__)
|
||||
|
||||
/**
|
||||
* @brief Macro to locate the next object in the object list and acquire a reference on it and record the file and
|
||||
* line number of the reference.
|
||||
*/
|
||||
#define EBPF_OBJECT_REFERENCE_NEXT_OBJECT(object, type, next_object) \
|
||||
ebpf_object_reference_next_object(object, type, next_object, EBPF_FILE_ID, __LINE__)
|
||||
|
||||
/**
|
||||
* @brief Macro to locate an object by its ID and acquire a reference on it and record the file and line number of
|
||||
* the reference.
|
||||
*/
|
||||
#define EBPF_OBJECT_REFERENCE_BY_ID(object_id, type, object) \
|
||||
ebpf_object_reference_by_id(object_id, type, object, EBPF_FILE_ID, __LINE__)
|
||||
|
||||
/**
|
||||
* @brief Macro to locate an object by its handle and acquire a reference on it and record the file and line number
|
||||
* of the reference.
|
||||
*/
|
||||
#define EBPF_OBJECT_REFERENCE_BY_HANDLE(object_handle, type, object) \
|
||||
ebpf_object_reference_by_handle(object_handle, type, object, EBPF_FILE_ID, __LINE__)
|
||||
|
||||
/**
|
||||
* @brief Macro to acquire a reference on an object ID and record the file and line number of the reference.
|
||||
*
|
||||
*/
|
||||
#define EBPF_OBJECT_ACQUIRE_ID_REFERENCE(object_id, type) \
|
||||
ebpf_object_acquire_id_reference(object_id, type, EBPF_FILE_ID, __LINE__)
|
||||
|
||||
/**
|
||||
* @brief Macro to release a reference on an object ID and record the file and line number of the reference.
|
||||
*
|
||||
*/
|
||||
#define EBPF_OBJECT_RELEASE_ID_REFERENCE(object_id, type) \
|
||||
ebpf_object_release_id_reference(object_id, type, EBPF_FILE_ID, __LINE__)
|
||||
|
||||
/**
|
||||
* @brief Macro to acquire a reference on an object via it's function pointers and record the file and line number
|
||||
* of the reference.
|
||||
*/
|
||||
#define EBPF_OBJECT_ACQUIRE_REFERENCE_INDIRECT(base_object) \
|
||||
base_object->acquire_reference(base_object, EBPF_FILE_ID, __LINE__)
|
||||
|
||||
/**
|
||||
* @brief Macro to release a reference on an object via it's function pointers and record the file and line number
|
||||
* of the reference.
|
||||
*/
|
||||
#define EBPF_OBJECT_RELEASE_REFERENCE_INDIRECT(base_object) \
|
||||
base_object->release_reference(base_object, EBPF_FILE_ID, __LINE__)
|
||||
|
||||
/**
|
||||
* @brief Macro to initialize an object and record the file and line number of the reference.
|
||||
*EBPF_OBJECT_INITIALIZE
|
||||
*/
|
||||
#define EBPF_OBJECT_INITIALIZE(object, object_type, free_function, get_program_type_function) \
|
||||
ebpf_object_initialize( \
|
||||
(ebpf_core_object_t*)(object), \
|
||||
(object_type), \
|
||||
(free_function), \
|
||||
(get_program_type_function), \
|
||||
EBPF_FILE_ID, \
|
||||
__LINE__)
|
||||
|
||||
typedef enum _ebpf_object_type
|
||||
{
|
||||
EBPF_OBJECT_UNKNOWN,
|
||||
|
@ -18,8 +112,8 @@ extern "C"
|
|||
} ebpf_object_type_t;
|
||||
|
||||
typedef struct _ebpf_base_object ebpf_base_object_t;
|
||||
typedef void (*ebpf_base_release_reference_t)(_Inout_ void* base_object);
|
||||
typedef void (*ebpf_base_acquire_reference_t)(_Inout_ void* base_object);
|
||||
typedef void (*ebpf_base_release_reference_t)(_Inout_ void* base_object, ebpf_file_id_t file_id, uint32_t line);
|
||||
typedef void (*ebpf_base_acquire_reference_t)(_Inout_ void* base_object, ebpf_file_id_t file_id, uint32_t line);
|
||||
|
||||
typedef struct _ebpf_core_object ebpf_core_object_t;
|
||||
typedef void (*ebpf_free_object_t)(ebpf_core_object_t* object);
|
||||
|
@ -80,6 +174,8 @@ extern "C"
|
|||
* @param[in] object_type The type of the object.
|
||||
* @param[in] free_function The function used to free the object.
|
||||
* @param[in] get_program_type_function The function used to get a program type, or NULL. Each program
|
||||
* @param[in] file_id The file ID of the caller.
|
||||
* @param[in] line The line number of the caller.
|
||||
* has a program type, and hence so do maps that can contain programs, whether directly (like
|
||||
* BPF_MAP_TYPE_PROG_ARRAY) or indirectly (like BPF_MAP_TYPE_ARRAY_OF_MAPS containing a BPF_MAP_TYPE_PROG_ARRAY).
|
||||
* @retval EBPF_SUCCESS Initialization succeeded.
|
||||
|
@ -90,24 +186,30 @@ extern "C"
|
|||
_Inout_ ebpf_core_object_t* object,
|
||||
ebpf_object_type_t object_type,
|
||||
ebpf_free_object_t free_function,
|
||||
ebpf_object_get_program_type_t get_program_type_function);
|
||||
ebpf_object_get_program_type_t get_program_type_function,
|
||||
ebpf_file_id_t file_id,
|
||||
uint32_t line);
|
||||
|
||||
/**
|
||||
* @brief Acquire a reference to this object.
|
||||
*
|
||||
* @param[in,out] object Object on which to acquire a reference.
|
||||
* @param[in] file_id The file ID of the caller.
|
||||
* @param[in] line The line number of the caller.
|
||||
*/
|
||||
void
|
||||
ebpf_object_acquire_reference(_Inout_ ebpf_core_object_t* object);
|
||||
ebpf_object_acquire_reference(_Inout_ ebpf_core_object_t* object, ebpf_file_id_t file_id, uint32_t line);
|
||||
|
||||
/**
|
||||
* @brief Release a reference on this object. If the reference count reaches
|
||||
* zero, the free_function is invoked on the object.
|
||||
*
|
||||
* @param[in,out] object Object on which to release a reference.
|
||||
* @param[in] file_id The file ID of the caller.
|
||||
* @param[in] line The line number of the caller.
|
||||
*/
|
||||
void
|
||||
ebpf_object_release_reference(_Inout_opt_ ebpf_core_object_t* object);
|
||||
ebpf_object_release_reference(_Inout_opt_ ebpf_core_object_t* object, ebpf_file_id_t file_id, uint32_t line);
|
||||
|
||||
/**
|
||||
* @brief Query the stored type of the object.
|
||||
|
@ -126,13 +228,17 @@ extern "C"
|
|||
* to find first object.
|
||||
* @param[in] type Type of object to find.
|
||||
* @param[out] next_object Pointer to memory containing the next object or
|
||||
* @param[in] file_id The file ID of the caller.
|
||||
* @param[in] line The line number of the caller.
|
||||
* NULL if there are no more objects of that type.
|
||||
*/
|
||||
void
|
||||
ebpf_object_reference_next_object(
|
||||
_In_opt_ const ebpf_core_object_t* previous_object,
|
||||
ebpf_object_type_t type,
|
||||
_Outptr_result_maybenull_ ebpf_core_object_t** next_object);
|
||||
_Outptr_result_maybenull_ ebpf_core_object_t** next_object,
|
||||
ebpf_file_id_t file_id,
|
||||
uint32_t line);
|
||||
|
||||
/**
|
||||
* @brief Find an ID in the ID table, verify the type matches,
|
||||
|
@ -141,11 +247,18 @@ extern "C"
|
|||
* @param[in] id ID to find in table.
|
||||
* @param[in] object_type Object type to match.
|
||||
* @param[out] object Pointer to memory that contains object success.
|
||||
* @param[in] file_id The file ID of the caller.
|
||||
* @param[in] line The line number of the caller.
|
||||
* @retval EBPF_SUCCESS The operation was successful.
|
||||
* @retval EBPF_KEY_NOT_FOUND The provided ID is not valid.
|
||||
*/
|
||||
_Must_inspect_result_ ebpf_result_t
|
||||
ebpf_object_reference_by_id(ebpf_id_t id, ebpf_object_type_t object_type, _Outptr_ ebpf_core_object_t** object);
|
||||
ebpf_object_reference_by_id(
|
||||
ebpf_id_t id,
|
||||
ebpf_object_type_t object_type,
|
||||
_Outptr_ ebpf_core_object_t** object,
|
||||
ebpf_file_id_t file_id,
|
||||
uint32_t line);
|
||||
|
||||
/**
|
||||
* @brief Find the object of a given type with the next ID greater than a given ID.
|
||||
|
@ -165,12 +278,18 @@ extern "C"
|
|||
* @param[in] handle Handle to find in table.
|
||||
* @param[in] object_type Object type to match.
|
||||
* @param[out] object Pointer to memory that contains object success.
|
||||
* @param[in] file_id The file ID of the caller.
|
||||
* @param[in] line The line number of the caller.
|
||||
* @retval EBPF_SUCCESS The operation was successful.
|
||||
* @retval EBPF_INVALID_OBJECT The provided handle is not valid.
|
||||
*/
|
||||
ebpf_result_t
|
||||
ebpf_object_reference_by_handle(
|
||||
ebpf_handle_t handle, ebpf_object_type_t object_type, _Outptr_ struct _ebpf_core_object** object);
|
||||
ebpf_handle_t handle,
|
||||
ebpf_object_type_t object_type,
|
||||
_Outptr_ struct _ebpf_core_object** object,
|
||||
ebpf_file_id_t file_id,
|
||||
uint32_t line);
|
||||
|
||||
/**
|
||||
* @brief Find an ID in the ID table, verify the type matches,
|
||||
|
@ -179,11 +298,14 @@ extern "C"
|
|||
*
|
||||
* @param[in] id ID to find in table.
|
||||
* @param[in] object_type Object type to match.
|
||||
* @param[in] file_id The file ID of the caller.
|
||||
* @param[in] line The line number of the caller.
|
||||
* @retval EBPF_SUCCESS The operation was successful.
|
||||
* @retval EBPF_KEY_NOT_FOUND The provided ID is not valid.
|
||||
*/
|
||||
_Must_inspect_result_ ebpf_result_t
|
||||
ebpf_object_acquire_id_reference(ebpf_id_t start_id, ebpf_object_type_t object_type);
|
||||
ebpf_object_acquire_id_reference(
|
||||
ebpf_id_t start_id, ebpf_object_type_t object_type, ebpf_file_id_t file_id, uint32_t line);
|
||||
|
||||
/**
|
||||
* @brief Find an ID in the ID table, verify the type matches,
|
||||
|
@ -192,11 +314,14 @@ extern "C"
|
|||
*
|
||||
* @param[in] id ID to find in table.
|
||||
* @param[in] object_type Object type to match.
|
||||
* @param[in] file_id The file ID of the caller.
|
||||
* @param[in] line The line number of the caller.
|
||||
* @retval EBPF_SUCCESS The operation was successful.
|
||||
* @retval EBPF_KEY_NOT_FOUND The provided ID is not valid.
|
||||
*/
|
||||
_Must_inspect_result_ ebpf_result_t
|
||||
ebpf_object_release_id_reference(ebpf_id_t start_id, ebpf_object_type_t object_type);
|
||||
ebpf_object_release_id_reference(
|
||||
ebpf_id_t start_id, ebpf_object_type_t object_type, ebpf_file_id_t file_id, uint32_t line);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
// key. Delete erases the entry from the ebpf_hash_table_t, but doesn't free the memory associated with the
|
||||
// ebpf_pinning_entry_t.
|
||||
|
||||
#define EBPF_FILE_ID EBPF_FILE_ID_PINNING_TABLE
|
||||
|
||||
#include "ebpf_core_structs.h"
|
||||
#include "ebpf_object.h"
|
||||
#include "ebpf_pinning_table.h"
|
||||
|
@ -40,7 +42,7 @@ _ebpf_pinning_entry_free(_Frees_ptr_opt_ ebpf_pinning_entry_t* pinning_entry)
|
|||
if (!pinning_entry) {
|
||||
return;
|
||||
}
|
||||
ebpf_object_release_reference(pinning_entry->object);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE(pinning_entry->object);
|
||||
ebpf_free(pinning_entry->path.value);
|
||||
ebpf_free(pinning_entry);
|
||||
}
|
||||
|
@ -143,7 +145,7 @@ ebpf_pinning_table_insert(
|
|||
}
|
||||
|
||||
new_pinning_entry->object = object;
|
||||
ebpf_object_acquire_reference(object);
|
||||
EBPF_OBJECT_ACQUIRE_REFERENCE(object);
|
||||
new_key = &new_pinning_entry->path;
|
||||
|
||||
state = ebpf_lock_lock(&pinning_table->lock);
|
||||
|
@ -187,7 +189,7 @@ ebpf_pinning_table_find(
|
|||
|
||||
if (return_value == EBPF_SUCCESS) {
|
||||
*object = (*existing_pinning_entry)->object;
|
||||
ebpf_object_acquire_reference(*object);
|
||||
EBPF_OBJECT_ACQUIRE_REFERENCE(*object);
|
||||
}
|
||||
|
||||
ebpf_lock_unlock(&pinning_table->lock, state);
|
||||
|
@ -304,7 +306,7 @@ ebpf_pinning_table_enumerate_entries(
|
|||
new_entry->object = (*next_pinning_entry)->object;
|
||||
|
||||
// Take reference on underlying ebpf_object.
|
||||
ebpf_object_acquire_reference(new_entry->object);
|
||||
EBPF_OBJECT_ACQUIRE_REFERENCE(new_entry->object);
|
||||
|
||||
// Duplicate pinning object path.
|
||||
result = ebpf_duplicate_utf8_string(&new_entry->path, &(*next_pinning_entry)->path);
|
||||
|
@ -391,7 +393,7 @@ ebpf_pinning_entries_release(uint16_t entry_count, _In_opt_count_(entry_count) e
|
|||
ebpf_pinning_entry_t* entry = &pinning_entries[index];
|
||||
ebpf_free(entry->path.value);
|
||||
entry->path.value = NULL;
|
||||
ebpf_object_release_reference(entry->object);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE(entry->object);
|
||||
}
|
||||
ebpf_free(pinning_entries);
|
||||
EBPF_RETURN_VOID();
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// Copyright (c) Microsoft Corporation
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#define EBPF_FILE_ID EBPF_FILE_ID_HANDLE
|
||||
|
||||
#include "ebpf_handle.h"
|
||||
#include "framework.h"
|
||||
|
||||
|
@ -59,7 +61,7 @@ ebpf_handle_create(_Out_ ebpf_handle_t* handle, _Inout_ ebpf_base_object_t* obje
|
|||
goto Done;
|
||||
}
|
||||
|
||||
object->acquire_reference(object);
|
||||
EBPF_OBJECT_ACQUIRE_REFERENCE_INDIRECT(object);
|
||||
file_object->FsContext2 = object;
|
||||
|
||||
*handle = (ebpf_handle_t)file_handle;
|
||||
|
@ -94,7 +96,9 @@ _IRQL_requires_max_(PASSIVE_LEVEL) ebpf_result_t ebpf_reference_base_object_by_h
|
|||
ebpf_handle_t handle,
|
||||
_In_opt_ ebpf_compare_object_t compare_function,
|
||||
_In_opt_ const void* context,
|
||||
_Outptr_ struct _ebpf_base_object** object)
|
||||
_Outptr_ struct _ebpf_base_object** object,
|
||||
uint32_t file_id,
|
||||
uint32_t line)
|
||||
{
|
||||
ebpf_result_t return_value;
|
||||
NTSTATUS status;
|
||||
|
@ -126,7 +130,7 @@ _IRQL_requires_max_(PASSIVE_LEVEL) ebpf_result_t ebpf_reference_base_object_by_h
|
|||
}
|
||||
}
|
||||
|
||||
local_object->acquire_reference(local_object);
|
||||
local_object->acquire_reference(local_object, file_id, line);
|
||||
*object = local_object;
|
||||
return_value = EBPF_SUCCESS;
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// Copyright (c) Microsoft Corporation
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#define EBPF_FILE_ID EBPF_FILE_ID_PLATFORM_UNIT_TESTS
|
||||
|
||||
#include "api_common.hpp"
|
||||
#include "catch_wrapper.hpp"
|
||||
#include "ebpf_async.h"
|
||||
|
@ -302,10 +304,10 @@ TEST_CASE("pinning_test", "[platform]")
|
|||
ebpf_utf8_string_t bar = EBPF_UTF8_STRING_FROM_CONST_STRING("bar");
|
||||
|
||||
REQUIRE(
|
||||
ebpf_object_initialize(
|
||||
EBPF_OBJECT_INITIALIZE(
|
||||
&an_object.object, EBPF_OBJECT_MAP, [](ebpf_core_object_t*) {}, NULL) == EBPF_SUCCESS);
|
||||
REQUIRE(
|
||||
ebpf_object_initialize(
|
||||
EBPF_OBJECT_INITIALIZE(
|
||||
&another_object.object, EBPF_OBJECT_MAP, [](ebpf_core_object_t*) {}, NULL) == EBPF_SUCCESS);
|
||||
|
||||
ebpf_pinning_table_ptr pinning_table;
|
||||
|
@ -322,7 +324,7 @@ TEST_CASE("pinning_test", "[platform]")
|
|||
REQUIRE(ebpf_pinning_table_find(pinning_table.get(), &foo, (ebpf_core_object_t**)&some_object) == EBPF_SUCCESS);
|
||||
REQUIRE(an_object.object.base.reference_count == 3);
|
||||
REQUIRE(some_object == &an_object);
|
||||
ebpf_object_release_reference(&some_object->object);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE(&some_object->object);
|
||||
REQUIRE(ebpf_pinning_table_delete(pinning_table.get(), &foo) == EBPF_SUCCESS);
|
||||
REQUIRE(another_object.object.base.reference_count == 2);
|
||||
|
||||
|
@ -330,8 +332,8 @@ TEST_CASE("pinning_test", "[platform]")
|
|||
REQUIRE(an_object.object.base.reference_count == 1);
|
||||
REQUIRE(another_object.object.base.reference_count == 1);
|
||||
|
||||
ebpf_object_release_reference(&an_object.object);
|
||||
ebpf_object_release_reference(&another_object.object);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE(&an_object.object);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE(&another_object.object);
|
||||
}
|
||||
|
||||
TEST_CASE("epoch_test_single_epoch", "[platform]")
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#define EBPF_FILE_ID EBPF_FILE_ID_HANDLE
|
||||
#include "ebpf_handle.h"
|
||||
|
||||
typedef ebpf_base_object_t* ebpf_handle_entry_t;
|
||||
|
@ -60,7 +61,7 @@ ebpf_handle_create(_Out_ ebpf_handle_t* handle, _Inout_ ebpf_base_object_t* obje
|
|||
|
||||
*handle = new_handle;
|
||||
_ebpf_handle_table[new_handle] = object;
|
||||
object->acquire_reference(object);
|
||||
EBPF_OBJECT_ACQUIRE_REFERENCE_INDIRECT(object);
|
||||
|
||||
return_value = EBPF_SUCCESS;
|
||||
|
||||
|
@ -79,7 +80,7 @@ ebpf_handle_close(ebpf_handle_t handle)
|
|||
|
||||
state = ebpf_lock_lock(&_ebpf_handle_table_lock);
|
||||
if (((size_t)handle < EBPF_COUNT_OF(_ebpf_handle_table)) && _ebpf_handle_table[handle] != NULL) {
|
||||
(_ebpf_handle_table[handle])->release_reference(_ebpf_handle_table[handle]);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE_INDIRECT(_ebpf_handle_table[handle]);
|
||||
_ebpf_handle_table[handle] = NULL;
|
||||
return_value = EBPF_SUCCESS;
|
||||
} else {
|
||||
|
@ -93,7 +94,9 @@ _IRQL_requires_max_(PASSIVE_LEVEL) ebpf_result_t ebpf_reference_base_object_by_h
|
|||
ebpf_handle_t handle,
|
||||
_In_opt_ ebpf_compare_object_t compare_function,
|
||||
_In_opt_ const void* context,
|
||||
_Outptr_ struct _ebpf_base_object** object)
|
||||
_Outptr_ struct _ebpf_base_object** object,
|
||||
uint32_t file_id,
|
||||
uint32_t line)
|
||||
{
|
||||
ebpf_result_t return_value;
|
||||
ebpf_lock_state_t state;
|
||||
|
@ -106,7 +109,7 @@ _IRQL_requires_max_(PASSIVE_LEVEL) ebpf_result_t ebpf_reference_base_object_by_h
|
|||
state = ebpf_lock_lock(&_ebpf_handle_table_lock);
|
||||
if (_ebpf_handle_table[handle] != NULL &&
|
||||
(compare_function == NULL || compare_function(_ebpf_handle_table[handle], context))) {
|
||||
_ebpf_handle_table[handle]->acquire_reference(_ebpf_handle_table[handle]);
|
||||
_ebpf_handle_table[handle]->acquire_reference(_ebpf_handle_table[handle], file_id, line);
|
||||
*object = _ebpf_handle_table[handle];
|
||||
return_value = EBPF_SUCCESS;
|
||||
} else {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// Copyright (c) Microsoft Corporation
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#define EBPF_FILE_ID EBPF_FILE_ID_CORE_HELPER_FUZZER
|
||||
|
||||
#include "ebpf_core.h"
|
||||
#include "ebpf_handle.h"
|
||||
#include "ebpf_object.h"
|
||||
|
@ -189,7 +191,7 @@ class fuzz_wrapper
|
|||
handles.push_back(handle);
|
||||
|
||||
ebpf_map_t* map = NULL;
|
||||
if (ebpf_object_reference_by_handle(handle, EBPF_OBJECT_MAP, (ebpf_core_object_t**)&map) ==
|
||||
if (EBPF_OBJECT_REFERENCE_BY_HANDLE(handle, EBPF_OBJECT_MAP, (ebpf_core_object_t**)&map) ==
|
||||
EBPF_SUCCESS) {
|
||||
maps[def.type] = map;
|
||||
if (def.type == BPF_MAP_TYPE_PROG_ARRAY) {
|
||||
|
@ -202,7 +204,7 @@ class fuzz_wrapper
|
|||
~fuzz_wrapper()
|
||||
{
|
||||
for (auto& [_, map] : maps) {
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)map);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)map);
|
||||
}
|
||||
for (auto& handle : handles) {
|
||||
// Ignore invalid handle close.
|
||||
|
@ -483,14 +485,14 @@ FUZZ_EXPORT int __cdecl LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
|
|||
ebpf_handle_t program_handle = fuzz_state.get_program_handle();
|
||||
ebpf_program_t* program = NULL;
|
||||
ebpf_result_t result =
|
||||
ebpf_object_reference_by_handle(program_handle, EBPF_OBJECT_PROGRAM, (ebpf_core_object_t**)&program);
|
||||
EBPF_OBJECT_REFERENCE_BY_HANDLE(program_handle, EBPF_OBJECT_PROGRAM, (ebpf_core_object_t**)&program);
|
||||
if (result != EBPF_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
fuzz_program(fuzz_state, program_handle, program, data, size);
|
||||
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)program);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)program);
|
||||
|
||||
return 0; // Non-zero return values are reserved for future use.
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// Copyright (c) Microsoft Corporation
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#define EBPF_FILE_ID EBPF_FILE_ID_PERFORMANCE_TESTS
|
||||
|
||||
#define TEST_AREA "ExecutionContext"
|
||||
|
||||
#include "performance.h"
|
||||
|
@ -30,7 +32,7 @@ typedef class _ebpf_program_test_state
|
|||
}
|
||||
~_ebpf_program_test_state()
|
||||
{
|
||||
ebpf_object_release_reference(reinterpret_cast<ebpf_core_object_t*>(program));
|
||||
EBPF_OBJECT_RELEASE_REFERENCE(reinterpret_cast<ebpf_core_object_t*>(program));
|
||||
delete program_info_provider;
|
||||
ebpf_core_terminate();
|
||||
}
|
||||
|
@ -109,7 +111,7 @@ typedef class _ebpf_map_test_state
|
|||
}
|
||||
~_ebpf_map_test_state()
|
||||
{
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)map);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)map);
|
||||
ebpf_core_terminate();
|
||||
}
|
||||
|
||||
|
@ -255,7 +257,7 @@ typedef class _ebpf_map_lpm_trie_test_state
|
|||
|
||||
~_ebpf_map_lpm_trie_test_state()
|
||||
{
|
||||
ebpf_object_release_reference((ebpf_core_object_t*)map);
|
||||
EBPF_OBJECT_RELEASE_REFERENCE((ebpf_core_object_t*)map);
|
||||
ebpf_core_terminate();
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче