Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Discriminate between pinned map and prog objects #1566

Open
mtardy opened this issue Sep 17, 2024 · 0 comments
Open

Discriminate between pinned map and prog objects #1566

mtardy opened this issue Sep 17, 2024 · 0 comments

Comments

@mtardy
Copy link
Member

mtardy commented Sep 17, 2024

I was writing something to parse objects from a /sys/fs/bpf fs and was expecting to receive an error when using ebpf.LoadPinnedMap on a prog and ebpf.LoadPinnedProg on a map. Instead, the function properly returns a struct but with garbage data in each "wrong" case.

So I've looked into it, it seems that the kernel doesn't expose anything to know in advance, given a BPF pinned object file, if it's a map or a prog. When you stat such a file there's no way to know if it's going to be a BPF map or prog.

However, when you open such a file and you end up with a file descriptor, if you readlink this fd, you retrieve something like anon_inode:bpf-map or anon_inode:bpf-prog. See here for map fd for example. This, and reading /proc/self/fdinfo/<fd> allows you to discriminate, since you'll bump into fields named map_<...> for maps and prog_<...> for progs.

All of that to say that we could use the readlink tricks to return an error properly instead of bogus information from LoadPinnedMap or LoadPinnedProg, @dylandreimerink suggested adding this to the newProgramInfoFromFd for example, we could also do newMapInfoFromFd respectively:

ebpf/info.go

Line 149 in 88736f4

func newProgramInfoFromFd(fd *sys.FD) (*ProgramInfo, error) {

ebpf/info.go

Line 54 in 88736f4

func newMapInfoFromFd(fd *sys.FD) (*MapInfo, error) {

On another topic, I think it would be great to have an API to parse objects indifferently if they are a map or a prog. A bit of what we can do right now with a "hack": reading everything, map and prog, as prog for example, since it doesn't return an error and then read common fields like memlock in fdinfo. It could be something like LoadPinned that would be common between maps and progs, and thus we could retrieve memlock using this object, or cast it into a map or prog if we want to go further.

I could elaborate on my use case and see if it makes sense but would love to know what people think :)!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant