瀏覽代碼

chore: Fix clippy panic_handler warnings

Working with aya in vscode will currently show a number of warnings
along the lines of:

```
found duplicate lang item `panic_impl`
the lang item is first defined in crate `std` (which `aya` depends on)
...
second definition in the local crate (`bpf_probe_read`)
```

This comes from feature unification.
integration-test requires the integration-common user feature, which
requires aya, which in turn brings in std.

For this same reason we avoid running clippy across the whole workspace.

We can avoid this issue by using the panic handler from the another
crate, which implements the same loop {} panic handler we use today.
It seems rustc is happy to conditionally link the panic handler
from an external crate without issuing warnings.

Therefore, we add our own crate - ebpf-panic - for this purpose.

Signed-off-by: Dave Tucker <[email protected]>
Dave Tucker 3 天之前
父節點
當前提交
3078e5aba0

+ 2 - 0
Cargo.toml

@@ -7,6 +7,7 @@ members = [
     "aya-log-parser",
     "aya-obj",
     "aya-tool",
+    "ebpf-panic",
     "test-distro",
     "test/integration-common",
     "test/integration-test",
@@ -33,6 +34,7 @@ default-members = [
     "aya-log-parser",
     "aya-obj",
     "aya-tool",
+    "ebpf-panic",
     "test-distro",
     "test/integration-common",
     # test/integration-test is omitted; including it in this list causes `cargo test` to run its

+ 1 - 7
clippy.sh

@@ -2,11 +2,6 @@
 
 set -eux
 
-# We cannot run clippy over the whole workspace at once due to feature unification. Since both
-# integration-test and integration-ebpf depend on integration-common and integration-test activates
-# integration-common's aya dependency, we end up trying to compile the panic handler twice: once
-# from the bpf program, and again from std via aya.
-# 
 # `-C panic=abort` because "unwinding panics are not supported without std"; integration-ebpf
 # contains `#[no_std]` binaries.
 # 
@@ -16,5 +11,4 @@ set -eux
 # unwinding behavior.
 # 
 # `+nightly` because "the option `Z` is only accepted on the nightly compiler".
-cargo +nightly hack clippy "$@" --exclude integration-ebpf --all-targets --feature-powerset --workspace -- --deny warnings
-cargo +nightly hack clippy "$@" --package integration-ebpf --all-targets --feature-powerset -- --deny warnings -C panic=abort -Zpanic_abort_tests
+cargo +nightly hack clippy "$@" --all-targets --feature-powerset -- --deny warnings -C panic=abort -Zpanic_abort_tests

+ 10 - 0
ebpf-panic/Cargo.toml

@@ -0,0 +1,10 @@
+[package]
+name = "ebpf-panic"
+publish = false
+version = "1.0.0"
+
+authors.workspace = true
+edition.workspace = true
+homepage.workspace = true
+license.workspace = true
+repository.workspace = true

+ 33 - 0
ebpf-panic/src/lib.rs

@@ -0,0 +1,33 @@
+//! A panic handler for eBPF rust targets.
+//!
+//! Panics are not supported in the eBPF rust targets however since crates for
+//! the eBPF targets are no_std they must provide a panic handler. This crate
+//! provides a panic handler that loops forever. Such a function, if called,
+//! will cause the program to be rejected by the eBPF verifier with an error
+//! message similar to:
+//!
+//! ```text
+//! last insn is not an exit or jmp
+//! ```
+//!
+//! # Example
+//!
+//! ```ignore
+//! #![no_std]
+//!
+//! use aya_ebpf::{macros::tracepoint, programs::TracePointContext};
+//! #[cfg(not(test))]
+//! extern crate ebpf_panic;
+//!
+//! #[tracepoint]
+//! pub fn test_tracepoint_one(_ctx: TracePointContext) -> u32 {
+//!     0
+//! }
+//! ```
+#![no_std]
+
+#[cfg(not(test))]
+#[panic_handler]
+fn panic(_info: &core::panic::PanicInfo) -> ! {
+    loop {}
+}

+ 1 - 0
test/integration-ebpf/Cargo.toml

@@ -16,6 +16,7 @@ workspace = true
 [dependencies]
 aya-ebpf = { path = "../../ebpf/aya-ebpf" }
 aya-log-ebpf = { path = "../../ebpf/aya-log-ebpf" }
+ebpf-panic = { path = "../../ebpf-panic" }
 integration-common = { path = "../integration-common" }
 network-types = { workspace = true }
 

+ 2 - 6
test/integration-ebpf/src/bpf_probe_read.rs

@@ -8,6 +8,8 @@ use aya_ebpf::{
     programs::ProbeContext,
 };
 use integration_common::bpf_probe_read::{RESULT_BUF_LEN, TestResult};
+#[cfg(not(test))]
+extern crate ebpf_panic;
 
 fn read_str_bytes(
     fun: unsafe fn(*const u8, &mut [u8]) -> Result<&[u8], i64>,
@@ -71,9 +73,3 @@ pub fn test_bpf_probe_read_kernel_str_bytes(ctx: ProbeContext) {
         ctx.arg::<usize>(0),
     );
 }
-
-#[cfg(not(test))]
-#[panic_handler]
-fn panic(_info: &core::panic::PanicInfo) -> ! {
-    loop {}
-}

+ 2 - 6
test/integration-ebpf/src/log.rs

@@ -5,6 +5,8 @@ use core::net::{IpAddr, Ipv4Addr, Ipv6Addr};
 
 use aya_ebpf::{macros::uprobe, programs::ProbeContext};
 use aya_log_ebpf::{debug, error, info, trace, warn};
+#[cfg(not(test))]
+extern crate ebpf_panic;
 
 #[uprobe]
 pub fn test_log(ctx: ProbeContext) {
@@ -81,9 +83,3 @@ pub fn test_log(ctx: ProbeContext) {
         debug!(&ctx, "{:x}", no_copy.consume());
     }
 }
-
-#[cfg(not(test))]
-#[panic_handler]
-fn panic(_info: &core::panic::PanicInfo) -> ! {
-    loop {}
-}

+ 2 - 6
test/integration-ebpf/src/map_test.rs

@@ -9,6 +9,8 @@ use aya_ebpf::{
     maps::{Array, HashMap},
     programs::SkBuffContext,
 };
+#[cfg(not(test))]
+extern crate ebpf_panic;
 
 // Introduced in kernel v3.19.
 #[map]
@@ -35,9 +37,3 @@ pub fn simple_prog(_ctx: SkBuffContext) -> i64 {
 
     0
 }
-
-#[cfg(not(test))]
-#[panic_handler]
-fn panic(_info: &core::panic::PanicInfo) -> ! {
-    loop {}
-}

+ 2 - 6
test/integration-ebpf/src/memmove_test.rs

@@ -9,6 +9,8 @@ use aya_ebpf::{
     maps::HashMap,
     programs::XdpContext,
 };
+#[cfg(not(test))]
+extern crate ebpf_panic;
 use network_types::{
     eth::{EthHdr, EtherType},
     ip::Ipv6Hdr,
@@ -53,9 +55,3 @@ fn try_do_dnat(ctx: XdpContext) -> Result<u32, ()> {
     }
     Ok(xdp_action::XDP_PASS)
 }
-
-#[cfg(not(test))]
-#[panic_handler]
-fn panic(_info: &core::panic::PanicInfo) -> ! {
-    loop {}
-}

+ 2 - 6
test/integration-ebpf/src/name_test.rs

@@ -2,6 +2,8 @@
 #![no_main]
 
 use aya_ebpf::{bindings::xdp_action, macros::xdp, programs::XdpContext};
+#[cfg(not(test))]
+extern crate ebpf_panic;
 
 #[xdp]
 pub fn ihaveaverylongname(ctx: XdpContext) -> u32 {
@@ -14,9 +16,3 @@ pub fn ihaveaverylongname(ctx: XdpContext) -> u32 {
 unsafe fn try_pass(_ctx: XdpContext) -> Result<u32, u32> {
     Ok(xdp_action::XDP_PASS)
 }
-
-#[cfg(not(test))]
-#[panic_handler]
-fn panic(_info: &core::panic::PanicInfo) -> ! {
-    loop {}
-}

+ 2 - 6
test/integration-ebpf/src/pass.rs

@@ -2,6 +2,8 @@
 #![no_main]
 
 use aya_ebpf::{bindings::xdp_action, macros::xdp, programs::XdpContext};
+#[cfg(not(test))]
+extern crate ebpf_panic;
 
 // Note: the `frags` attribute causes this probe to be incompatible with kernel versions < 5.18.0.
 // See https://github.com/torvalds/linux/commit/c2f2cdb.
@@ -16,9 +18,3 @@ pub fn pass(ctx: XdpContext) -> u32 {
 unsafe fn try_pass(_ctx: XdpContext) -> Result<u32, u32> {
     Ok(xdp_action::XDP_PASS)
 }
-
-#[cfg(not(test))]
-#[panic_handler]
-fn panic(_info: &core::panic::PanicInfo) -> ! {
-    loop {}
-}

+ 2 - 6
test/integration-ebpf/src/raw_tracepoint.rs

@@ -6,6 +6,8 @@ use aya_ebpf::{
     maps::Array,
     programs::RawTracePointContext,
 };
+#[cfg(not(test))]
+extern crate ebpf_panic;
 use integration_common::raw_tracepoint::SysEnterEvent;
 
 #[map]
@@ -25,9 +27,3 @@ pub fn sys_enter(ctx: RawTracePointContext) -> i32 {
 
     0
 }
-
-#[cfg(not(test))]
-#[panic_handler]
-fn panic(_info: &core::panic::PanicInfo) -> ! {
-    loop {}
-}

+ 2 - 6
test/integration-ebpf/src/redirect.rs

@@ -7,6 +7,8 @@ use aya_ebpf::{
     maps::{Array, CpuMap, DevMap, DevMapHash, XskMap},
     programs::XdpContext,
 };
+#[cfg(not(test))]
+extern crate ebpf_panic;
 
 #[map]
 static SOCKS: XskMap = XskMap::with_max_entries(1, 0);
@@ -74,9 +76,3 @@ fn inc_hit(index: u32) {
         unsafe { *hit += 1 };
     }
 }
-
-#[cfg(not(test))]
-#[panic_handler]
-fn panic(_info: &core::panic::PanicInfo) -> ! {
-    loop {}
-}

+ 2 - 6
test/integration-ebpf/src/relocations.rs

@@ -8,6 +8,8 @@ use aya_ebpf::{
     maps::Array,
     programs::ProbeContext,
 };
+#[cfg(not(test))]
+extern crate ebpf_panic;
 
 #[map]
 static RESULTS: Array<u64> = Array::with_max_entries(3, 0);
@@ -38,9 +40,3 @@ fn set_result(index: u32, value: u64) {
 fn set_result_backward(index: u32, value: u64) {
     set_result(index, value);
 }
-
-#[cfg(not(test))]
-#[panic_handler]
-fn panic(_info: &core::panic::PanicInfo) -> ! {
-    loop {}
-}

+ 2 - 6
test/integration-ebpf/src/ring_buf.rs

@@ -7,6 +7,8 @@ use aya_ebpf::{
     programs::ProbeContext,
 };
 use integration_common::ring_buf::Registers;
+#[cfg(not(test))]
+extern crate ebpf_panic;
 
 #[map]
 static RING_BUF: RingBuf = RingBuf::with_byte_size(0, 0);
@@ -45,9 +47,3 @@ pub fn ring_buf_test(ctx: ProbeContext) {
         entry.discard(0);
     }
 }
-
-#[cfg(not(test))]
-#[panic_handler]
-fn panic(_info: &core::panic::PanicInfo) -> ! {
-    loop {}
-}

+ 2 - 6
test/integration-ebpf/src/simple_prog.rs

@@ -5,15 +5,11 @@
 #![no_main]
 
 use aya_ebpf::{macros::socket_filter, programs::SkBuffContext};
+#[cfg(not(test))]
+extern crate ebpf_panic;
 
 // Introduced in kernel v3.19.
 #[socket_filter]
 pub fn simple_prog(_ctx: SkBuffContext) -> i64 {
     0
 }
-
-#[cfg(not(test))]
-#[panic_handler]
-fn panic(_info: &core::panic::PanicInfo) -> ! {
-    loop {}
-}

+ 2 - 6
test/integration-ebpf/src/strncmp.rs

@@ -9,6 +9,8 @@ use aya_ebpf::{
     programs::ProbeContext,
 };
 use integration_common::strncmp::TestResult;
+#[cfg(not(test))]
+extern crate ebpf_panic;
 
 #[map]
 static RESULT: Array<TestResult> = Array::with_max_entries(1, 0);
@@ -26,9 +28,3 @@ pub fn test_bpf_strncmp(ctx: ProbeContext) -> Result<(), c_long> {
 
     Ok(())
 }
-
-#[cfg(not(test))]
-#[panic_handler]
-fn panic(_info: &core::panic::PanicInfo) -> ! {
-    loop {}
-}

+ 2 - 6
test/integration-ebpf/src/tcx.rs

@@ -2,14 +2,10 @@
 #![no_main]
 
 use aya_ebpf::{bindings::tcx_action_base::TCX_NEXT, macros::classifier, programs::TcContext};
+#[cfg(not(test))]
+extern crate ebpf_panic;
 
 #[classifier]
 pub fn tcx_next(_ctx: TcContext) -> i32 {
     TCX_NEXT
 }
-
-#[cfg(not(test))]
-#[panic_handler]
-fn panic(_info: &core::panic::PanicInfo) -> ! {
-    loop {}
-}

+ 2 - 6
test/integration-ebpf/src/test.rs

@@ -8,6 +8,8 @@ use aya_ebpf::{
         FlowDissectorContext, ProbeContext, RetProbeContext, TracePointContext, XdpContext,
     },
 };
+#[cfg(not(test))]
+extern crate ebpf_panic;
 
 #[xdp]
 pub fn pass(ctx: XdpContext) -> u32 {
@@ -52,9 +54,3 @@ pub fn test_flow(_ctx: FlowDissectorContext) -> u32 {
     // Linux kernel for inspiration.
     bpf_ret_code::BPF_FLOW_DISSECTOR_CONTINUE
 }
-
-#[cfg(not(test))]
-#[panic_handler]
-fn panic(_info: &core::panic::PanicInfo) -> ! {
-    loop {}
-}

+ 2 - 6
test/integration-ebpf/src/two_progs.rs

@@ -4,6 +4,8 @@
 #![no_main]
 
 use aya_ebpf::{macros::tracepoint, programs::TracePointContext};
+#[cfg(not(test))]
+extern crate ebpf_panic;
 
 #[tracepoint]
 pub fn test_tracepoint_one(_ctx: TracePointContext) -> u32 {
@@ -13,9 +15,3 @@ pub fn test_tracepoint_one(_ctx: TracePointContext) -> u32 {
 pub fn test_tracepoint_two(_ctx: TracePointContext) -> u32 {
     0
 }
-
-#[cfg(not(test))]
-#[panic_handler]
-fn panic(_info: &core::panic::PanicInfo) -> ! {
-    loop {}
-}

+ 2 - 6
test/integration-ebpf/src/uprobe_cookie.rs

@@ -7,6 +7,8 @@ use aya_ebpf::{
     maps::RingBuf,
     programs::ProbeContext,
 };
+#[cfg(not(test))]
+extern crate ebpf_panic;
 
 #[map]
 static RING_BUF: RingBuf = RingBuf::with_byte_size(0, 0);
@@ -17,9 +19,3 @@ pub fn uprobe_cookie(ctx: ProbeContext) {
     let cookie_bytes = cookie.to_le_bytes();
     let _res = RING_BUF.output(&cookie_bytes, 0);
 }
-
-#[cfg(not(test))]
-#[panic_handler]
-fn panic(_info: &core::panic::PanicInfo) -> ! {
-    loop {}
-}

+ 2 - 6
test/integration-ebpf/src/xdp_sec.rs

@@ -2,6 +2,8 @@
 #![no_main]
 
 use aya_ebpf::{bindings::xdp_action::XDP_PASS, macros::xdp, programs::XdpContext};
+#[cfg(not(test))]
+extern crate ebpf_panic;
 
 macro_rules! probe {
     ($name:ident, ($($arg:ident $(= $value:literal)?),*) ) => {
@@ -18,9 +20,3 @@ probe!(xdp_cpumap, (map = "cpumap"));
 probe!(xdp_devmap, (map = "devmap"));
 probe!(xdp_frags_cpumap, (frags, map = "cpumap"));
 probe!(xdp_frags_devmap, (frags, map = "devmap"));
-
-#[cfg(not(test))]
-#[panic_handler]
-fn panic(_info: &core::panic::PanicInfo) -> ! {
-    loop {}
-}