In aarch64, with kernel 5.5, my programs that use `bpf_probe_read_user`
don't work successfully because `aya` is mistakenly re-writting it
`bpf_probe_read` because it falsely detects that the kernel doesn't
support `bpf_probe_read_user`.
I hadn't updated my `aya` version in a while, but while updating it to
fix a separate issue (panics when parsing kernel versions of PVE
kernels) and running my test suite I saw tests failing on aarch64 5.5
kernels. A git bisect led me to this commit:
942ea51906 and further investigation in the
difference of the new and old assembly showed that the only difference
was subtracting 8 vs adding -8. When I put it back as adding 8 (but
without handwritten assembly) then things work as expected. Since it
used to be `BPF_ADD` and the commit that changed it was just about no
longer handwriting assembly without any reason for the switch to
`BPF_SUB` putting it back as `BPF_ADD` seems reasonable.
When using `BPF_SUB` 8, the handwritten program in this function
returns a permission error which is treated by this function as
`bpf_probe_read_kernel` not being supported when it is but for some
reason `BPF_SUB` is not. My guess is that it might be an early verifier
error but I am not 100% sure as I thought verifier errors are normally
`EINVAL` not `EPERM` but I have a vague memory of seeing `EPERM` in the
past for errors that happened very early in the verifier.
Fixes: #1233
clippy complained that cfg_attr is applied to the macro invocation and
therefore will not be expanded. This was a false-positive, however
when playing with cargo expand I did notice that the cfg and cfg_attr
section weren't propagating as I would expect them to.
Adding a meta matcher to the impl_try_from_map macro allows us to
remove the need for AsyncPerfEventArray to be in a separate invocation
of the macro while also making sure that attributes do get propagated
to the generated functions.
Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
Allow for a ProgramInfo to be converted into one of the program types
that we support. This allows for a user of Aya access to reattach,
pin or unload a program that was either, previously loaded, or was
loaded by another process.
Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
We have previously tried to import traits anonymously where possible but
enforcing this manually was hard.
Since Rust 1.83 clippy can now enforce this for us.
Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
Limit of map names in eBPF is 16 bytes and they have to be NULL
terminated.
Before this change, long names were truncated to 16 bytes.
`MAP_WITH_LOOOONG_NAAAAAAAAME` would become `MAP_WITH_LOOOONG`, which
doesn't contain the NULL byte.
This change fixes that by truncating the name to 15 bytes, ensuring
that the 16th byte is NULL. `MAP_WITH_LOOOONG_NAAAAAAAAME` is truncated
to `MAP_WITH_LOOOON\0`.
In practice this will forbid unused dependencies because we run clippy
with `--deny warnings`.
Workspace lints is a nice place to ratchet up lints through the codebase
all at once and consistently.
Turns out this was actually being used through magic.
Remove mips since it is a tier 3 target that is only supported on
nightly and dtolnay/rust-toolchain doesn't seem to handle installing
targets without std.
Exclude xtask since it depends on `ring` which doesn't build on all
targets.
Fix compilation on armv7 which had rotted.
This reverts commit d92fc95c39.
Change FromRawTracepointArgs::arg to return T rather than *const T which
seems to have been returning a dangling pointer.
Arguably this is not strictly necessary; edition 2024 seems to be
focused on increased strictness around unsafe code which doesn't unlock
new functionality for our users. That said, this work revealed an
apparent bug (see above) that we wouldn't otherwise catch due to
allow-by-default lints.
Per man 2 perf_event_open:
> RETURN VALUE
> On success, perf_event_open() returns the new file descriptor. On
> error, -1 is returned and errno is set to indicate the error.
Bake this into our syscalls so we stop using `_` so much which can hide
information loss. Remove the type parameter to SysResult.
Per man 2 bpf:
> RETURN VALUE
> For a successful call, the return value depends on the operation:
>
> BPF_MAP_CREATE
> The new file descriptor associated with the eBPF map.
>
> BPF_PROG_LOAD
> The new file descriptor associated with the eBPF program.
>
> All other commands
> Zero.
>
> On error, -1 is returned, and errno is set to indicate the error.
Bake this into our syscalls so we stop using `_` so much which can hide
information loss.
PerCpuHashMap was never returning MapError::KeyNotFound because
bpf_map_lookup_elem_per_cpu was replacing Ok(None) with
Ok(Some(zeroed_value)).
Update bpf_map_lookup_elem_per_cpu to map the Option value.
When `aya::obj` was migrated to be its own crate `aya-obj`, the `obj`
alias was created to preserve existing imports that relied on
`crate::obj`.
This resulted in 3 ways to import `aya-obj` objects:
- `use aya_obj::*`
- `use obj::*`
- `use crate::obj::*`
The `obj` alias is now removed to avoid confusion, and all `obj` imports
are funneled through `aya_obj`.
This returns error strings from netlink since they are more informative
than the raw os error. For example:
"Device or Resource Busy" vs. "XDP program already attached".
Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
```
error: manual implementation of `ok`
--> aya/src/util.rs:261:28
|
261 | let addr = match u64::from_str_radix(addr, 16) {
| ____________________________^
262 | | Ok(addr) => Some(addr),
263 | | Err(ParseIntError { .. }) => None,
264 | | }?;
| |_________________^ help: replace with: `u64::from_str_radix(addr, 16).ok()`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_ok_err
error: struct pattern is not needed for a unit variant
--> aya-obj/src/obj.rs:1705:44
|
1705 | section: ProgramSection::KProbe { .. },
| ^^^^^^^ help: remove the struct pattern
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_struct_pattern
note: the lint level is defined here
--> aya-obj/src/lib.rs:68:9
|
68 | #![deny(clippy::all, missing_docs)]
| ^^^^^^^^^^^
= note: `#[deny(clippy::unneeded_struct_pattern)]` implied by `#[deny(clippy::all)]`
error: struct pattern is not needed for a unit variant
--> aya-obj/src/obj.rs:1769:44
|
1769 | section: ProgramSection::KProbe { .. },
| ^^^^^^^ help: remove the struct pattern
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_struct_pattern
error: struct pattern is not needed for a unit variant
--> aya-obj/src/obj.rs:1787:44
|
1787 | section: ProgramSection::KProbe { .. },
| ^^^^^^^ help: remove the struct pattern
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_struct_pattern
error: struct pattern is not needed for a unit variant
--> aya-obj/src/obj.rs:1919:48
|
1919 | section: ProgramSection::KProbe { .. },
| ^^^^^^^ help: remove the struct pattern
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_struct_pattern
error: struct pattern is not needed for a unit variant
--> aya-obj/src/obj.rs:2041:52
|
2041 | section: ProgramSection::TracePoint { .. },
| ^^^^^^^ help: remove the struct pattern
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_struct_pattern
error: struct pattern is not needed for a unit variant
--> aya-obj/src/obj.rs:2058:52
|
2058 | section: ProgramSection::TracePoint { .. },
| ^^^^^^^ help: remove the struct pattern
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_struct_pattern
error: struct pattern is not needed for a unit variant
--> aya-obj/src/obj.rs:2081:54
|
2081 | section: ProgramSection::SocketFilter { .. },
| ^^^^^^^ help: remove the struct pattern
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_struct_pattern
error: struct pattern is not needed for a unit variant
--> aya-obj/src/obj.rs:2151:55
|
2151 | section: ProgramSection::RawTracePoint { .. },
| ^^^^^^^ help: remove the struct pattern
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_struct_pattern
error: struct pattern is not needed for a unit variant
--> aya-obj/src/obj.rs:2168:55
|
2168 | section: ProgramSection::RawTracePoint { .. },
| ^^^^^^^ help: remove the struct pattern
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_struct_pattern
error: struct pattern is not needed for a unit variant
--> aya-obj/src/obj.rs:2243:55
|
2243 | section: ProgramSection::BtfTracePoint { .. },
| ^^^^^^^ help: remove the struct pattern
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_struct_pattern
error: struct pattern is not needed for a unit variant
--> aya-obj/src/obj.rs:2266:59
|
2266 | section: ProgramSection::SkSkbStreamParser { .. },
| ^^^^^^^ help: remove the struct pattern
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_struct_pattern
error: struct pattern is not needed for a unit variant
--> aya-obj/src/obj.rs:2289:59
|
2289 | section: ProgramSection::SkSkbStreamParser { .. },
| ^^^^^^^ help: remove the struct pattern
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_struct_pattern
error: struct pattern is not needed for a unit variant
--> aya-obj/src/obj.rs:2410:58
|
2410 | section: ProgramSection::CgroupSkbIngress { .. },
| ^^^^^^^ help: remove the struct pattern
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_struct_pattern
error: struct pattern is not needed for a unit variant
--> aya-obj/src/obj.rs:2433:58
|
2433 | section: ProgramSection::CgroupSkbIngress { .. },
| ^^^^^^^ help: remove the struct pattern
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_struct_pattern
error: struct pattern is not needed for a unit variant
--> aya-obj/src/obj.rs:2456:51
|
2456 | section: ProgramSection::CgroupSkb { .. },
| ^^^^^^^ help: remove the struct pattern
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_struct_pattern
error: struct pattern is not needed for a unit variant
--> aya-obj/src/obj.rs:2479:51
|
2479 | section: ProgramSection::CgroupSkb { .. },
| ^^^^^^^ help: remove the struct pattern
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_struct_pattern
error: manual implementation of `ok`
--> aya-log-common/src/lib.rs:168:36
|
168 | let wire_len: LogValueLength = match value.len().try_into() {
| ____________________________________^
169 | | Ok(wire_len) => Some(wire_len),
170 | | Err(TryFromIntError { .. }) => None,
171 | | }?;
| |_____^ help: replace with: `value.len().try_into().ok()`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_ok_err
error: manual implementation of `err`
--> init/src/main.rs:141:30
|
141 | .filter_map(|result| match result {
| ______________________________^
142 | | Ok(()) => None,
143 | | Err(err) => Some(err),
144 | | })
| |_________^ help: replace with: `result.err()`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_ok_err
error: manual implementation of `err`
--> xtask/src/public_api.rs:80:30
|
80 | .filter_map(|result| match result {
| ______________________________^
81 | | Ok(()) => None,
82 | | Err(err) => Some(err),
83 | | })
| |_________^ help: replace with: `result.err()`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_ok_err
```
```
error: called `Iterator::last` on a `DoubleEndedIterator`; this will needlessly iterate the entire iterator
--> aya/src/programs/uprobe.rs:282:64
|
282 | let path = line.split(|b| b.is_ascii_whitespace()).last()?;
| ^^^^^^ help: try: `next_back()`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#double_ended_iterator_last
```
Fixes#1132.
Note that this change does not add support in the public API for kprobes
or tracepoints, but it's a trivial matter of plumbing.
Along the way, the Uprobe::attach API is cleaned up to make the
attachment location more coherent. The logic being: if we're going to be
breaking the API anyway, may as well clean it up a bit.
Furthermore, the aya::sys::bpf_link_attach function is cleaned up by
properly modeling the the union in the final field with a rust enum.