Skip to content

Commit

Permalink
Add negative test program and test for xdp datasize check (#3292)
Browse files Browse the repository at this point in the history
Co-authored-by: Dhiren Vispute <Dhiren.Vispute@microsoft.com>
  • Loading branch information
dv-msft and Dhiren Vispute committed Feb 26, 2024
1 parent f233f01 commit 12f73c3
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 0 deletions.
52 changes: 52 additions & 0 deletions tests/end_to_end/netsh_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include <winsock2.h>
#include <windows.h>
#include <iostream>
#include <netsh.h>
#include <regex>
#include <sstream>
Expand Down Expand Up @@ -380,6 +381,57 @@ TEST_CASE("show verification droppacket_unsafe.o", "[netsh][verification]")
"\n");
}

TEST_CASE("show verification xdp_datasize_unsafe.o", "[netsh][verification]")
{
_test_helper_netsh test_helper;
test_helper.initialize();

int result;
std::string output =
_run_netsh_command(handle_ebpf_show_verification, L"xdp_datasize_unsafe.o", L"xdp", nullptr, &result);
REQUIRE(result == ERROR_SUPPRESS_OUTPUT);
output = strip_paths(output);
REQUIRE(
output == "Verification failed\n"
"\n"
"Verification report:\n"
"\n"
"; ./tests/sample/unsafe/xdp_datasize_unsafe.c:32\n"
"; if (next_header + sizeof(ETHERNET_HEADER) > (char*)ctx->data_end) {\n"
"4: (r3.type in {number, ctx, stack, packet, shared})\n"
"; ./tests/sample/unsafe/xdp_datasize_unsafe.c:32\n"
"; if (next_header + sizeof(ETHERNET_HEADER) > (char*)ctx->data_end) {\n"
"5: Invalid type (valid_access(r3.offset) for comparison/subtraction)\n"
"; ./tests/sample/unsafe/xdp_datasize_unsafe.c:32\n"
"; if (next_header + sizeof(ETHERNET_HEADER) > (char*)ctx->data_end) {\n"
"5: (r3.type == non_map_fd)\n"
"; ./tests/sample/unsafe/xdp_datasize_unsafe.c:32\n"
"; if (next_header + sizeof(ETHERNET_HEADER) > (char*)ctx->data_end) {\n"
"5: Cannot subtract pointers to different regions (r3.type == r1.type in {ctx, stack, packet})\n"
"; ./tests/sample/unsafe/xdp_datasize_unsafe.c:38\n"
"; if (ethernet_header->Type != ntohs(ETHERNET_TYPE_IPV4) && ethernet_header->Type != "
"ntohs(ETHERNET_TYPE_IPV6)) {\n"
"6: (r2.type in {ctx, stack, packet, shared})\n"
"; ./tests/sample/unsafe/xdp_datasize_unsafe.c:38\n"
"; if (ethernet_header->Type != ntohs(ETHERNET_TYPE_IPV4) && ethernet_header->Type != "
"ntohs(ETHERNET_TYPE_IPV6)) {\n"
"6: Invalid type (valid_access(r2.offset+12, width=2) for read)\n"
"; ./tests/sample/unsafe/xdp_datasize_unsafe.c:38\n"
"; if (ethernet_header->Type != ntohs(ETHERNET_TYPE_IPV4) && ethernet_header->Type != "
"ntohs(ETHERNET_TYPE_IPV6)) {\n"
"7: (r1.type == number)\n"
"; ./tests/sample/unsafe/xdp_datasize_unsafe.c:38\n"
"; if (ethernet_header->Type != ntohs(ETHERNET_TYPE_IPV4) && ethernet_header->Type != "
"ntohs(ETHERNET_TYPE_IPV6)) {\n"
"8: (r1.type == number)\n"
"; ./tests/sample/unsafe/xdp_datasize_unsafe.c:43\n"
"; return rc;\n"
"10: (r0.type == number)\n"
"\n"
"9 errors\n"
"\n");
}

TEST_CASE("show verification printk_unsafe.o", "[netsh][verification]")
{
_test_helper_netsh test_helper;
Expand Down
44 changes: 44 additions & 0 deletions tests/sample/unsafe/xdp_datasize_unsafe.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) Microsoft Corporation
// SPDX-License-Identifier: MIT

// clang -O2 -Werror -c xdp_datasize_unsafe.c -o xdp_datasize_unsafe_jit.o
//
// For bpf code: clang -target bpf -O2 -Werror -c xdp_datsize_unsafe.c -o xdp_datasize_unsafe.o
//

#include "bpf_endian.h"
#include "bpf_helpers.h"
#include "net/if_ether.h"
#include "net/ip.h"
#include "net/udp.h"

SEC("xdp")
inline void*
data_start(xdp_md_t* ctx)
{
void* ptr;
asm volatile("%0 = *(u32 *)(%1 + %2)" : "=r"(ptr) : "r"(ctx), "i"(__builtin_offsetof(xdp_md_t, data)));
return ptr;
}

SEC("xdp")
int
unsafe_program(xdp_md_t* ctx)
{
int rc = XDP_PASS;

ETHERNET_HEADER* ethernet_header = NULL;
char* next_header = data_start(ctx); // <== 64-bit truncated to 32-bit.
if (next_header + sizeof(ETHERNET_HEADER) > (char*)ctx->data_end) {
goto Done;
}

ethernet_header = (ETHERNET_HEADER*)next_header;
next_header = (char*)(ethernet_header + 1);
if (ethernet_header->Type != ntohs(ETHERNET_TYPE_IPV4) && ethernet_header->Type != ntohs(ETHERNET_TYPE_IPV6)) {
rc = XDP_DROP;
}

Done:
return rc;
}

0 comments on commit 12f73c3

Please sign in to comment.