Switch ebpf_pinning_table_get_next_name to use ebpf_utf8_string_t (#552)

* Switch ebpf_pinning_table_get_next_name to use ebpf_utf8_string_t

Signed-off-by: Alan Jowett <alanjo@microsoft.com>
This commit is contained in:
Alan Jowett 2021-09-20 13:42:22 -06:00 коммит произвёл GitHub
Родитель d806803a8a
Коммит 107d915b0d
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 111 добавлений и 77 удалений

Просмотреть файл

@ -693,13 +693,13 @@ ebpf_object_pin(fd_t fd, _In_z_ const char* path)
}
auto path_length = strlen(path);
ebpf_protocol_buffer_t request_buffer(offsetof(ebpf_operation_update_pinning_request_t, name) + path_length);
ebpf_protocol_buffer_t request_buffer(offsetof(ebpf_operation_update_pinning_request_t, path) + path_length);
auto request = reinterpret_cast<ebpf_operation_update_pinning_request_t*>(request_buffer.data());
request->header.id = EBPF_OPERATION_UPDATE_PINNING;
request->header.length = static_cast<uint16_t>(request_buffer.size());
request->handle = handle;
std::copy(path, path + path_length, request->name);
std::copy(path, path + path_length, request->path);
result = windows_error_to_ebpf_result(invoke_ioctl(request_buffer));
return result;
@ -712,13 +712,13 @@ ebpf_object_unpin(_In_z_ const char* path)
return EBPF_INVALID_ARGUMENT;
}
auto path_length = strlen(path);
ebpf_protocol_buffer_t request_buffer(offsetof(ebpf_operation_update_pinning_request_t, name) + path_length);
ebpf_protocol_buffer_t request_buffer(offsetof(ebpf_operation_update_pinning_request_t, path) + path_length);
auto request = reinterpret_cast<ebpf_operation_update_pinning_request_t*>(request_buffer.data());
request->header.id = EBPF_OPERATION_UPDATE_PINNING;
request->header.length = static_cast<uint16_t>(request_buffer.size());
request->handle = UINT64_MAX;
std::copy(path, path + path_length, request->name);
std::copy(path, path + path_length, request->path);
return windows_error_to_ebpf_result(invoke_ioctl(request_buffer));
}
@ -806,13 +806,13 @@ fd_t
ebpf_object_get(_In_z_ const char* path)
{
size_t path_length = strlen(path);
ebpf_protocol_buffer_t request_buffer(offsetof(ebpf_operation_get_pinning_request_t, name) + path_length);
ebpf_protocol_buffer_t request_buffer(offsetof(ebpf_operation_get_pinning_request_t, path) + path_length);
auto request = reinterpret_cast<ebpf_operation_get_pinning_request_t*>(request_buffer.data());
ebpf_operation_get_map_pinning_reply_t reply;
request->header.id = EBPF_OPERATION_GET_PINNING;
request->header.length = static_cast<uint16_t>(request_buffer.size());
std::copy(path, path + path_length, request->name);
std::copy(path, path + path_length, request->path);
auto result = invoke_ioctl(request_buffer, reply);
if (result != ERROR_SUCCESS) {
return ebpf_fd_invalid;
@ -1797,19 +1797,35 @@ ebpf_get_next_pinned_program_path(
return EBPF_INVALID_ARGUMENT;
}
_ebpf_operation_get_next_pinned_path_request request{
sizeof(request), ebpf_operation_id_t::EBPF_OPERATION_GET_NEXT_PINNED_PROGRAM_PATH};
_ebpf_operation_get_next_pinned_path_reply reply;
size_t start_path_length = strlen(start_path);
strcpy_s(request.start_path, sizeof(request.start_path), start_path);
ebpf_protocol_buffer_t request_buffer(
EBPF_OFFSET_OF(ebpf_operation_get_next_pinned_path_request_t, start_path) + start_path_length);
ebpf_protocol_buffer_t reply_buffer(
EBPF_OFFSET_OF(ebpf_operation_get_next_pinned_path_reply_t, next_path) + EBPF_MAX_PIN_PATH_LENGTH);
ebpf_operation_get_next_pinned_path_request_t* request =
reinterpret_cast<ebpf_operation_get_next_pinned_path_request_t*>(request_buffer.data());
ebpf_operation_get_next_pinned_path_reply_t* reply =
reinterpret_cast<ebpf_operation_get_next_pinned_path_reply_t*>(reply_buffer.data());
uint32_t error = invoke_ioctl(request, reply);
request->header.id = ebpf_operation_id_t::EBPF_OPERATION_GET_NEXT_PINNED_PROGRAM_PATH;
request->header.length = static_cast<uint16_t>(request_buffer.size());
reply->header.length = static_cast<uint16_t>(reply_buffer.size());
memcpy(request->start_path, start_path, start_path_length);
uint32_t error = invoke_ioctl(request_buffer, reply_buffer);
ebpf_result_t result = windows_error_to_ebpf_result(error);
if (result != EBPF_SUCCESS) {
return result;
}
strcpy_s(next_path, EBPF_MAX_PIN_PATH_LENGTH, reply.next_path);
size_t next_path_length =
reply->header.length - EBPF_OFFSET_OF(ebpf_operation_get_next_pinned_path_reply_t, next_path);
memcpy(next_path, reply->next_path, next_path_length);
next_path[next_path_length] = '\0';
return EBPF_SUCCESS;
}

Просмотреть файл

@ -667,25 +667,25 @@ static ebpf_result_t
_ebpf_core_protocol_update_pinning(_In_ const struct _ebpf_operation_update_map_pinning_request* request)
{
ebpf_result_t retval;
const ebpf_utf8_string_t name = {
(uint8_t*)request->name,
request->header.length - EBPF_OFFSET_OF(ebpf_operation_update_pinning_request_t, name)};
const ebpf_utf8_string_t path = {
(uint8_t*)request->path,
request->header.length - EBPF_OFFSET_OF(ebpf_operation_update_pinning_request_t, path)};
ebpf_object_t* object = NULL;
if (name.length == 0) {
if (path.length == 0) {
retval = EBPF_INVALID_ARGUMENT;
goto Done;
}
if (request->handle == UINT64_MAX) {
retval = ebpf_pinning_table_delete(_ebpf_core_map_pinning_table, &name);
retval = ebpf_pinning_table_delete(_ebpf_core_map_pinning_table, &path);
goto Done;
} else {
retval = ebpf_reference_object_by_handle(request->handle, EBPF_OBJECT_UNKNOWN, (ebpf_object_t**)&object);
if (retval != EBPF_SUCCESS)
goto Done;
retval = ebpf_pinning_table_insert(_ebpf_core_map_pinning_table, &name, (ebpf_object_t*)object);
retval = ebpf_pinning_table_insert(_ebpf_core_map_pinning_table, &path, (ebpf_object_t*)object);
}
Done:
ebpf_object_release_reference((ebpf_object_t*)object);
@ -701,16 +701,16 @@ _ebpf_core_protocol_get_pinned_object(
{
ebpf_result_t retval;
ebpf_object_t* object = NULL;
const ebpf_utf8_string_t name = {
(uint8_t*)request->name, request->header.length - EBPF_OFFSET_OF(ebpf_operation_get_pinning_request_t, name)};
const ebpf_utf8_string_t path = {
(uint8_t*)request->path, request->header.length - EBPF_OFFSET_OF(ebpf_operation_get_pinning_request_t, path)};
UNREFERENCED_PARAMETER(reply_length);
if (name.length == 0) {
if (path.length == 0) {
retval = EBPF_INVALID_ARGUMENT;
goto Done;
}
retval = ebpf_pinning_table_find(_ebpf_core_map_pinning_table, &name, (ebpf_object_t**)&object);
retval = ebpf_pinning_table_find(_ebpf_core_map_pinning_table, &path, (ebpf_object_t**)&object);
if (retval != EBPF_SUCCESS)
goto Done;
@ -890,7 +890,7 @@ _ebpf_core_protocol_convert_pinning_entries_to_map_info_array(
destination->definition = *map_definition;
destination->definition.value_size = ebpf_map_get_effective_value_size((ebpf_map_t*)source->object);
// Set pin path. No need to duplicate.
destination->pin_path = source->name;
destination->pin_path = source->path;
}
Exit:
@ -1070,17 +1070,29 @@ _ebpf_core_protocol_get_next_program_id(
}
static ebpf_result_t
_ebpf_core_protocol_get_next_pinned_program_name(
_ebpf_core_protocol_get_next_pinned_program_path(
_In_ const ebpf_operation_get_next_pinned_path_request_t* request,
_Out_ ebpf_operation_get_next_pinned_path_reply_t* reply,
uint16_t reply_length)
{
UNREFERENCED_PARAMETER(reply_length);
ebpf_utf8_string_t start_path;
ebpf_utf8_string_t next_path;
return ebpf_pinning_table_get_next_path(
_ebpf_core_map_pinning_table, EBPF_OBJECT_PROGRAM, request->start_path, reply->next_path);
start_path.length =
request->header.length - EBPF_OFFSET_OF(ebpf_operation_get_next_pinned_path_request_t, start_path);
start_path.value = (uint8_t*)request->start_path;
next_path.length = reply_length - EBPF_OFFSET_OF(ebpf_operation_get_next_pinned_path_reply_t, next_path);
next_path.value = (uint8_t*)reply->next_path;
ebpf_result_t result =
ebpf_pinning_table_get_next_path(_ebpf_core_map_pinning_table, EBPF_OBJECT_PROGRAM, &start_path, &next_path);
if (result == EBPF_SUCCESS) {
reply->header.length =
(uint16_t)next_path.length + EBPF_OFFSET_OF(ebpf_operation_get_next_pinned_path_reply_t, next_path);
}
return result;
}
static ebpf_result_t
_ebpf_core_protocol_get_object_info(
_In_ const ebpf_operation_get_object_info_request_t* request,
@ -1264,11 +1276,11 @@ static ebpf_protocol_handler_t _ebpf_protocol_handlers[] = {
EBPF_OFFSET_OF(ebpf_operation_query_program_info_reply_t, data)},
// EBPF_OPERATION_UPDATE_PINNING
{_ebpf_core_protocol_update_pinning, EBPF_OFFSET_OF(ebpf_operation_update_pinning_request_t, name), 0},
{_ebpf_core_protocol_update_pinning, EBPF_OFFSET_OF(ebpf_operation_update_pinning_request_t, path), 0},
// EBPF_OPERATION_GET_PINNING
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_get_pinned_object,
EBPF_OFFSET_OF(ebpf_operation_get_pinning_request_t, name),
EBPF_OFFSET_OF(ebpf_operation_get_pinning_request_t, path),
sizeof(struct _ebpf_operation_get_pinning_reply)},
// EBPF_OPERATION_LINK_PROGRAM
@ -1337,9 +1349,9 @@ static ebpf_protocol_handler_t _ebpf_protocol_handlers[] = {
sizeof(ebpf_operation_get_object_info_reply_t)},
// EBPF_OPERATION_GET_NEXT_PINNED_PROGRAM_NAME
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_get_next_pinned_program_name,
sizeof(ebpf_operation_get_next_pinned_path_request_t),
sizeof(ebpf_operation_get_next_pinned_path_reply_t)},
{(ebpf_result_t(__cdecl*)(const void*))_ebpf_core_protocol_get_next_pinned_program_path,
EBPF_OFFSET_OF(ebpf_operation_get_next_pinned_path_request_t, start_path),
EBPF_OFFSET_OF(ebpf_operation_get_next_pinned_path_reply_t, next_path)},
};
ebpf_result_t

Просмотреть файл

@ -240,13 +240,13 @@ typedef struct _ebpf_operation_update_map_pinning_request
{
struct _ebpf_operation_header header;
ebpf_handle_t handle;
uint8_t name[1];
uint8_t path[1];
} ebpf_operation_update_pinning_request_t;
typedef struct _ebpf_operation_get_pinning_request
{
struct _ebpf_operation_header header;
uint8_t name[1];
uint8_t path[1];
} ebpf_operation_get_pinning_request_t;
typedef struct _ebpf_operation_get_pinning_reply
@ -337,13 +337,13 @@ typedef struct _ebpf_operation_get_next_id_reply
typedef struct _ebpf_operation_get_next_pinned_path_request
{
struct _ebpf_operation_header header;
char start_path[EBPF_MAX_PIN_PATH_LENGTH];
uint8_t start_path[1];
} ebpf_operation_get_next_pinned_path_request_t;
typedef struct _ebpf_operation_get_next_pinned_path_reply
{
struct _ebpf_operation_header header;
char next_path[EBPF_MAX_PIN_PATH_LENGTH];
uint8_t next_path[1];
} ebpf_operation_get_next_pinned_path_reply_t;
typedef struct _ebpf_operation_get_object_info_request

Просмотреть файл

@ -41,7 +41,7 @@ _ebpf_pinning_entry_free(ebpf_pinning_entry_t* pinning_entry)
return;
}
ebpf_object_release_reference(pinning_entry->object);
ebpf_free(pinning_entry->name.value);
ebpf_free(pinning_entry->path.value);
ebpf_free(pinning_entry);
}
@ -102,30 +102,37 @@ ebpf_pinning_table_free(ebpf_pinning_table_t* pinning_table)
}
ebpf_result_t
ebpf_pinning_table_insert(ebpf_pinning_table_t* pinning_table, const ebpf_utf8_string_t* name, ebpf_object_t* object)
ebpf_pinning_table_insert(ebpf_pinning_table_t* pinning_table, const ebpf_utf8_string_t* path, ebpf_object_t* object)
{
ebpf_lock_state_t state;
ebpf_result_t return_value;
ebpf_utf8_string_t* new_key;
ebpf_pinning_entry_t* new_pinning_entry;
if (name->length >= EBPF_MAX_PIN_PATH_LENGTH) {
if (path->length >= EBPF_MAX_PIN_PATH_LENGTH || path->length == 0) {
return EBPF_INVALID_ARGUMENT;
}
// Block embedded null terminators
for (size_t index = 0; index < path->length; index++) {
if (path->value[index] == 0) {
return EBPF_INVALID_ARGUMENT;
}
}
new_pinning_entry = ebpf_allocate(sizeof(ebpf_pinning_entry_t));
if (!new_pinning_entry) {
return_value = EBPF_NO_MEMORY;
goto Done;
}
return_value = ebpf_duplicate_utf8_string(&new_pinning_entry->name, name);
return_value = ebpf_duplicate_utf8_string(&new_pinning_entry->path, path);
if (return_value != EBPF_SUCCESS)
goto Done;
new_pinning_entry->object = object;
ebpf_object_acquire_reference(object);
new_key = &new_pinning_entry->name;
new_key = &new_pinning_entry->path;
state = ebpf_lock_lock(&pinning_table->lock);
@ -150,11 +157,11 @@ Done:
}
ebpf_result_t
ebpf_pinning_table_find(ebpf_pinning_table_t* pinning_table, const ebpf_utf8_string_t* name, ebpf_object_t** object)
ebpf_pinning_table_find(ebpf_pinning_table_t* pinning_table, const ebpf_utf8_string_t* path, ebpf_object_t** object)
{
ebpf_lock_state_t state;
ebpf_result_t return_value;
const ebpf_utf8_string_t* existing_key = name;
const ebpf_utf8_string_t* existing_key = path;
ebpf_pinning_entry_t** existing_pinning_entry;
state = ebpf_lock_lock(&pinning_table->lock);
@ -172,11 +179,11 @@ ebpf_pinning_table_find(ebpf_pinning_table_t* pinning_table, const ebpf_utf8_str
}
ebpf_result_t
ebpf_pinning_table_delete(ebpf_pinning_table_t* pinning_table, const ebpf_utf8_string_t* name)
ebpf_pinning_table_delete(ebpf_pinning_table_t* pinning_table, const ebpf_utf8_string_t* path)
{
ebpf_lock_state_t state;
ebpf_result_t return_value;
const ebpf_utf8_string_t* existing_key = name;
const ebpf_utf8_string_t* existing_key = path;
ebpf_pinning_entry_t** existing_pinning_entry;
state = ebpf_lock_lock(&pinning_table->lock);
@ -208,7 +215,7 @@ ebpf_pinning_table_enumerate_entries(
uint16_t local_entry_count = 0;
uint16_t entries_array_length = 0;
ebpf_pinning_entry_t* local_pinning_entries = NULL;
ebpf_utf8_string_t* next_object_name;
ebpf_utf8_string_t* next_object_path;
ebpf_pinning_entry_t* new_entry = NULL;
if ((entry_count == NULL) || (pinning_entries == NULL)) {
@ -234,15 +241,15 @@ ebpf_pinning_table_enumerate_entries(
}
// Loop through the entries in the hashtable.
next_object_name = NULL;
next_object_path = NULL;
for (;;) {
ebpf_pinning_entry_t** next_pinning_entry = NULL;
// Find next pinning entry, if any.
result = ebpf_hash_table_next_key_and_value(
pinning_table->hash_table,
(const uint8_t*)((next_object_name == NULL) ? NULL : &next_object_name),
(uint8_t*)&next_object_name,
(const uint8_t*)((next_object_path == NULL) ? NULL : &next_object_path),
(uint8_t*)&next_object_path,
(uint8_t**)&next_pinning_entry);
if (result == EBPF_NO_MORE_KEYS) {
@ -270,7 +277,7 @@ ebpf_pinning_table_enumerate_entries(
ebpf_object_acquire_reference(new_entry->object);
// Duplicate pinning object path.
result = ebpf_duplicate_utf8_string(&new_entry->name, &(*next_pinning_entry)->name);
result = ebpf_duplicate_utf8_string(&new_entry->path, &(*next_pinning_entry)->path);
if (result != EBPF_SUCCESS)
goto Exit;
}
@ -297,19 +304,14 @@ ebpf_result_t
ebpf_pinning_table_get_next_path(
_In_ ebpf_pinning_table_t* pinning_table,
ebpf_object_type_t object_type,
_In_z_ const char* start_path,
_Out_writes_z_(EBPF_MAX_PIN_PATH_LENGTH) char* next_path)
_In_ const ebpf_utf8_string_t* start_path,
_Inout_ ebpf_utf8_string_t* next_path)
{
if ((pinning_table == NULL) || (start_path == NULL) || (next_path == NULL)) {
return EBPF_INVALID_ARGUMENT;
}
// Copy the path provided into a buffer that we can guarantee is null terminated.
char path_buffer[EBPF_MAX_PIN_PATH_LENGTH];
strncpy_s(path_buffer, EBPF_MAX_PIN_PATH_LENGTH, start_path, _TRUNCATE);
const ebpf_utf8_string_t path_string = {(uint8_t*)path_buffer, strlen(path_buffer)};
const ebpf_utf8_string_t* path = &path_string;
const uint8_t* previous_key = (path->length == 0) ? NULL : (const uint8_t*)&path;
const uint8_t* previous_key = (start_path->length == 0) ? NULL : (const uint8_t*)&start_path;
ebpf_lock_state_t state = ebpf_lock_lock(&pinning_table->lock);
@ -327,9 +329,13 @@ ebpf_pinning_table_get_next_path(
// See if the entry matches the object type the caller is interested in.
if (object_type == ebpf_object_get_type((*next_pinning_entry)->object)) {
// Copy the path into the caller's buffer.
strncpy_s(
next_path, EBPF_MAX_PIN_PATH_LENGTH, (const char*)next_object_path->value, next_object_path->length);
if (next_path->length < (*next_pinning_entry)->path.length) {
result = EBPF_INSUFFICIENT_BUFFER;
} else {
next_path->length = (*next_pinning_entry)->path.length;
memcpy(next_path->value, (*next_pinning_entry)->path.value, next_path->length);
result = EBPF_SUCCESS;
}
break;
}
previous_key = (uint8_t*)&next_object_path;
@ -348,8 +354,8 @@ ebpf_pinning_entries_release(uint16_t entry_count, _In_opt_count_(entry_count) e
for (index = 0; index < entry_count; index++) {
ebpf_pinning_entry_t* entry = &pinning_entries[index];
ebpf_free(entry->name.value);
entry->name.value = NULL;
ebpf_free(entry->path.value);
entry->path.value = NULL;
ebpf_object_release_reference(entry->object);
}
ebpf_free(pinning_entries);

Просмотреть файл

@ -16,7 +16,7 @@ extern "C"
*/
typedef struct _ebpf_pinning_entry
{
ebpf_utf8_string_t name;
ebpf_utf8_string_t path;
ebpf_object_t* object;
} ebpf_pinning_entry_t;
@ -45,7 +45,7 @@ extern "C"
* the object.
*
* @param[in] pinning_table Pinning table to update.
* @param[in] name Name to associate with this entry.
* @param[in] path Path to associate with this entry.
* @param[in] object Ebpf object to associate with this entry.
* @retval EBPF_SUCCESS The operation was successful.
* @retval EBPF_NO_MEMORY Unable to allocate resources for this
@ -53,35 +53,35 @@ extern "C"
*/
ebpf_result_t
ebpf_pinning_table_insert(
ebpf_pinning_table_t* pinning_table, const ebpf_utf8_string_t* name, ebpf_object_t* object);
ebpf_pinning_table_t* pinning_table, const ebpf_utf8_string_t* path, ebpf_object_t* object);
/**
* @brief Find an entry in the pinning table and acquire a reference on the
* object associate with it.
*
* @param[in] pinning_table Pinning table to search.
* @param[in] name Name to find in the pinning table.
* @param[in] path Path to find in the pinning table.
* @param[out] object Pointer to memory that contains the object on success.
* @retval EBPF_SUCCESS The operation was successful.
* @retval EBPF_OBJECT_NOT_FOUND The name is not present in the pinning
* @retval EBPF_OBJECT_NOT_FOUND The path is not present in the pinning
* table.
*/
ebpf_result_t
ebpf_pinning_table_find(
ebpf_pinning_table_t* pinning_table, const ebpf_utf8_string_t* name, ebpf_object_t** object);
ebpf_pinning_table_t* pinning_table, const ebpf_utf8_string_t* path, ebpf_object_t** object);
/**
* @brief Find an entry in the pinning table, remove it and release a
* reference on the object associated with it.
*
* @param[in] pinning_table Pinning table to update.
* @param[in] name Name to find in the pinning table.
* @param[in] path Path to find in the pinning table.
* @retval EBPF_SUCCESS The operation was successful.
* @retval EBPF_OBJECT_NOT_FOUND The name is not present in the pinning
* @retval EBPF_OBJECT_NOT_FOUND The path is not present in the pinning
* table.
*/
ebpf_result_t
ebpf_pinning_table_delete(ebpf_pinning_table_t* pinning_table, const ebpf_utf8_string_t* name);
ebpf_pinning_table_delete(ebpf_pinning_table_t* pinning_table, const ebpf_utf8_string_t* path);
/**
* @brief Returns all entries in the pinning table of specified object type after acquiring a reference.
@ -106,8 +106,8 @@ extern "C"
*
* @param[in] pinning_table Pinning table to enumerate.
* @param[in] object_type Object type.
* @param[in] start_path Name to look for an entry greater than.
* @param[out] next_path Returns the next name, if one exists.
* @param[in] start_path Path to look for an entry greater than.
* @param[out] next_path Returns the next path, if one exists.
* @retval EBPF_SUCCESS The operation was successful.
* @retval EBPF_NO_MORE_KEYS No more entries found.
*/
@ -115,8 +115,8 @@ extern "C"
ebpf_pinning_table_get_next_path(
_In_ ebpf_pinning_table_t* pinning_table,
ebpf_object_type_t object_type,
_In_z_ const char* start_path,
_Out_writes_z_(EBPF_MAX_PIN_PATH_LENGTH) char* next_path);
_In_ const ebpf_utf8_string_t* start_path,
_Inout_ ebpf_utf8_string_t* next_path);
/**
* @brief Releases entries returned by ebpf_pinning_table_enumerate_entries.