mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-10 21:53:57 +08:00
build(deps): bump github.com/cilium/ebpf from 0.8.0 to 0.8.1
Bumps [github.com/cilium/ebpf](https://github.com/cilium/ebpf) from 0.8.0 to 0.8.1. - [Release notes](https://github.com/cilium/ebpf/releases) - [Commits](https://github.com/cilium/ebpf/compare/v0.8.0...v0.8.1) --- updated-dependencies: - dependency-name: github.com/cilium/ebpf dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
@@ -4,7 +4,7 @@ go 1.16
|
||||
|
||||
require (
|
||||
github.com/checkpoint-restore/go-criu/v5 v5.3.0
|
||||
github.com/cilium/ebpf v0.8.0
|
||||
github.com/cilium/ebpf v0.8.1
|
||||
github.com/containerd/console v1.0.3
|
||||
github.com/coreos/go-systemd/v22 v22.3.2
|
||||
github.com/cyphar/filepath-securejoin v0.2.3
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/checkpoint-restore/go-criu/v5 v5.3.0 h1:wpFFOoomK3389ue2lAb0Boag6XPht5QYpipxmSNL4d8=
|
||||
github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
|
||||
github.com/cilium/ebpf v0.8.0 h1:2V6KSg3FRADVU2BMIRemZ0hV+9OM+aAHhZDjQyjJTAs=
|
||||
github.com/cilium/ebpf v0.8.0/go.mod h1:f5zLIM0FSNuAkSyLAN7X+Hy6yznlF1mNiWUMfxMtrgk=
|
||||
github.com/cilium/ebpf v0.8.1 h1:bLSSEbBLqGPXxls55pGr5qWZaTqcmfDJHhou7t254ao=
|
||||
github.com/cilium/ebpf v0.8.1/go.mod h1:f5zLIM0FSNuAkSyLAN7X+Hy6yznlF1mNiWUMfxMtrgk=
|
||||
github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=
|
||||
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
|
||||
github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI=
|
||||
|
||||
+21
-15
@@ -483,24 +483,30 @@ func (cl *collectionLoader) populateMaps() error {
|
||||
|
||||
mapSpec = mapSpec.Copy()
|
||||
|
||||
// Replace any object stubs with loaded objects.
|
||||
// MapSpecs that refer to inner maps or programs within the same
|
||||
// CollectionSpec do so using strings. These strings are used as the key
|
||||
// to look up the respective object in the Maps or Programs fields.
|
||||
// Resolve those references to actual Map or Program resources that
|
||||
// have been loaded into the kernel.
|
||||
for i, kv := range mapSpec.Contents {
|
||||
switch v := kv.Value.(type) {
|
||||
case programStub:
|
||||
// loadProgram is idempotent and could return an existing Program.
|
||||
prog, err := cl.loadProgram(string(v))
|
||||
if err != nil {
|
||||
return fmt.Errorf("loading program %s, for map %s: %w", v, mapName, err)
|
||||
}
|
||||
mapSpec.Contents[i] = MapKV{kv.Key, prog}
|
||||
if objName, ok := kv.Value.(string); ok {
|
||||
switch mapSpec.Type {
|
||||
case ProgramArray:
|
||||
// loadProgram is idempotent and could return an existing Program.
|
||||
prog, err := cl.loadProgram(objName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("loading program %s, for map %s: %w", objName, mapName, err)
|
||||
}
|
||||
mapSpec.Contents[i] = MapKV{kv.Key, prog}
|
||||
|
||||
case mapStub:
|
||||
// loadMap is idempotent and could return an existing Map.
|
||||
innerMap, err := cl.loadMap(string(v))
|
||||
if err != nil {
|
||||
return fmt.Errorf("loading inner map %s, for map %s: %w", v, mapName, err)
|
||||
case ArrayOfMaps, HashOfMaps:
|
||||
// loadMap is idempotent and could return an existing Map.
|
||||
innerMap, err := cl.loadMap(objName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("loading inner map %s, for map %s: %w", objName, mapName, err)
|
||||
}
|
||||
mapSpec.Contents[i] = MapKV{kv.Key, innerMap}
|
||||
}
|
||||
mapSpec.Contents[i] = MapKV{kv.Key, innerMap}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+78
-85
@@ -728,14 +728,6 @@ func (ec *elfCode) loadBTFMaps(maps map[string]*MapSpec) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// A programStub is a placeholder for a Program to be inserted at a certain map key.
|
||||
// It needs to be resolved into a Program later on in the loader process.
|
||||
type programStub string
|
||||
|
||||
// A mapStub is a placeholder for a Map to be inserted at a certain map key.
|
||||
// It needs to be resolved into a Map later on in the loader process.
|
||||
type mapStub string
|
||||
|
||||
// mapSpecFromBTF produces a MapSpec based on a btf.Struct def representing
|
||||
// a BTF map definition. The name and spec arguments will be copied to the
|
||||
// resulting MapSpec, and inner must be true on any resursive invocations.
|
||||
@@ -1009,9 +1001,9 @@ func resolveBTFValuesContents(es *elfSection, vs *btf.VarSecinfo, member btf.Mem
|
||||
// skipped here.
|
||||
switch t := elf.ST_TYPE(r.Info); t {
|
||||
case elf.STT_FUNC:
|
||||
contents = append(contents, MapKV{uint32(k), programStub(r.Name)})
|
||||
contents = append(contents, MapKV{uint32(k), r.Name})
|
||||
case elf.STT_OBJECT:
|
||||
contents = append(contents, MapKV{uint32(k), mapStub(r.Name)})
|
||||
contents = append(contents, MapKV{uint32(k), r.Name})
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown relocation type %v", t)
|
||||
}
|
||||
@@ -1075,96 +1067,97 @@ func (ec *elfCode) loadDataSections(maps map[string]*MapSpec) error {
|
||||
}
|
||||
|
||||
func getProgType(sectionName string) (ProgramType, AttachType, uint32, string) {
|
||||
types := map[string]struct {
|
||||
types := []struct {
|
||||
prefix string
|
||||
progType ProgramType
|
||||
attachType AttachType
|
||||
progFlags uint32
|
||||
}{
|
||||
// Please update the types from libbpf.c and follow the order of it.
|
||||
// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/lib/bpf/libbpf.c
|
||||
"socket": {SocketFilter, AttachNone, 0},
|
||||
"sk_reuseport/migrate": {SkReuseport, AttachSkReuseportSelectOrMigrate, 0},
|
||||
"sk_reuseport": {SkReuseport, AttachSkReuseportSelect, 0},
|
||||
"kprobe/": {Kprobe, AttachNone, 0},
|
||||
"uprobe/": {Kprobe, AttachNone, 0},
|
||||
"kretprobe/": {Kprobe, AttachNone, 0},
|
||||
"uretprobe/": {Kprobe, AttachNone, 0},
|
||||
"tc": {SchedCLS, AttachNone, 0},
|
||||
"classifier": {SchedCLS, AttachNone, 0},
|
||||
"action": {SchedACT, AttachNone, 0},
|
||||
"tracepoint/": {TracePoint, AttachNone, 0},
|
||||
"tp/": {TracePoint, AttachNone, 0},
|
||||
"raw_tracepoint/": {RawTracepoint, AttachNone, 0},
|
||||
"raw_tp/": {RawTracepoint, AttachNone, 0},
|
||||
"raw_tracepoint.w/": {RawTracepointWritable, AttachNone, 0},
|
||||
"raw_tp.w/": {RawTracepointWritable, AttachNone, 0},
|
||||
"tp_btf/": {Tracing, AttachTraceRawTp, 0},
|
||||
"fentry/": {Tracing, AttachTraceFEntry, 0},
|
||||
"fmod_ret/": {Tracing, AttachModifyReturn, 0},
|
||||
"fexit/": {Tracing, AttachTraceFExit, 0},
|
||||
"fentry.s/": {Tracing, AttachTraceFEntry, unix.BPF_F_SLEEPABLE},
|
||||
"fmod_ret.s/": {Tracing, AttachModifyReturn, unix.BPF_F_SLEEPABLE},
|
||||
"fexit.s/": {Tracing, AttachTraceFExit, unix.BPF_F_SLEEPABLE},
|
||||
"freplace/": {Extension, AttachNone, 0},
|
||||
"lsm/": {LSM, AttachLSMMac, 0},
|
||||
"lsm.s/": {LSM, AttachLSMMac, unix.BPF_F_SLEEPABLE},
|
||||
"iter/": {Tracing, AttachTraceIter, 0},
|
||||
"syscall": {Syscall, AttachNone, 0},
|
||||
"xdp_devmap/": {XDP, AttachXDPDevMap, 0},
|
||||
"xdp_cpumap/": {XDP, AttachXDPCPUMap, 0},
|
||||
"xdp": {XDP, AttachNone, 0},
|
||||
"perf_event": {PerfEvent, AttachNone, 0},
|
||||
"lwt_in": {LWTIn, AttachNone, 0},
|
||||
"lwt_out": {LWTOut, AttachNone, 0},
|
||||
"lwt_xmit": {LWTXmit, AttachNone, 0},
|
||||
"lwt_seg6local": {LWTSeg6Local, AttachNone, 0},
|
||||
"cgroup_skb/ingress": {CGroupSKB, AttachCGroupInetIngress, 0},
|
||||
"cgroup_skb/egress": {CGroupSKB, AttachCGroupInetEgress, 0},
|
||||
"cgroup/skb": {CGroupSKB, AttachNone, 0},
|
||||
"cgroup/sock_create": {CGroupSKB, AttachCGroupInetSockCreate, 0},
|
||||
"cgroup/sock_release": {CGroupSKB, AttachCgroupInetSockRelease, 0},
|
||||
"cgroup/sock": {CGroupSock, AttachCGroupInetSockCreate, 0},
|
||||
"cgroup/post_bind4": {CGroupSock, AttachCGroupInet4PostBind, 0},
|
||||
"cgroup/post_bind6": {CGroupSock, AttachCGroupInet6PostBind, 0},
|
||||
"cgroup/dev": {CGroupDevice, AttachCGroupDevice, 0},
|
||||
"sockops": {SockOps, AttachCGroupSockOps, 0},
|
||||
"sk_skb/stream_parser": {SkSKB, AttachSkSKBStreamParser, 0},
|
||||
"sk_skb/stream_verdict": {SkSKB, AttachSkSKBStreamVerdict, 0},
|
||||
"sk_skb": {SkSKB, AttachNone, 0},
|
||||
"sk_msg": {SkMsg, AttachSkMsgVerdict, 0},
|
||||
"lirc_mode2": {LircMode2, AttachLircMode2, 0},
|
||||
"flow_dissector": {FlowDissector, AttachFlowDissector, 0},
|
||||
"cgroup/bind4": {CGroupSockAddr, AttachCGroupInet4Bind, 0},
|
||||
"cgroup/bind6": {CGroupSockAddr, AttachCGroupInet6Bind, 0},
|
||||
"cgroup/connect4": {CGroupSockAddr, AttachCGroupInet4Connect, 0},
|
||||
"cgroup/connect6": {CGroupSockAddr, AttachCGroupInet6Connect, 0},
|
||||
"cgroup/sendmsg4": {CGroupSockAddr, AttachCGroupUDP4Sendmsg, 0},
|
||||
"cgroup/sendmsg6": {CGroupSockAddr, AttachCGroupUDP6Sendmsg, 0},
|
||||
"cgroup/recvmsg4": {CGroupSockAddr, AttachCGroupUDP4Recvmsg, 0},
|
||||
"cgroup/recvmsg6": {CGroupSockAddr, AttachCGroupUDP6Recvmsg, 0},
|
||||
"cgroup/getpeername4": {CGroupSockAddr, AttachCgroupInet4GetPeername, 0},
|
||||
"cgroup/getpeername6": {CGroupSockAddr, AttachCgroupInet6GetPeername, 0},
|
||||
"cgroup/getsockname4": {CGroupSockAddr, AttachCgroupInet4GetSockname, 0},
|
||||
"cgroup/getsockname6": {CGroupSockAddr, AttachCgroupInet6GetSockname, 0},
|
||||
"cgroup/sysctl": {CGroupSysctl, AttachCGroupSysctl, 0},
|
||||
"cgroup/getsockopt": {CGroupSockopt, AttachCGroupGetsockopt, 0},
|
||||
"cgroup/setsockopt": {CGroupSockopt, AttachCGroupSetsockopt, 0},
|
||||
"struct_ops+": {StructOps, AttachNone, 0},
|
||||
"sk_lookup/": {SkLookup, AttachSkLookup, 0},
|
||||
{"socket", SocketFilter, AttachNone, 0},
|
||||
{"sk_reuseport/migrate", SkReuseport, AttachSkReuseportSelectOrMigrate, 0},
|
||||
{"sk_reuseport", SkReuseport, AttachSkReuseportSelect, 0},
|
||||
{"kprobe/", Kprobe, AttachNone, 0},
|
||||
{"uprobe/", Kprobe, AttachNone, 0},
|
||||
{"kretprobe/", Kprobe, AttachNone, 0},
|
||||
{"uretprobe/", Kprobe, AttachNone, 0},
|
||||
{"tc", SchedCLS, AttachNone, 0},
|
||||
{"classifier", SchedCLS, AttachNone, 0},
|
||||
{"action", SchedACT, AttachNone, 0},
|
||||
{"tracepoint/", TracePoint, AttachNone, 0},
|
||||
{"tp/", TracePoint, AttachNone, 0},
|
||||
{"raw_tracepoint/", RawTracepoint, AttachNone, 0},
|
||||
{"raw_tp/", RawTracepoint, AttachNone, 0},
|
||||
{"raw_tracepoint.w/", RawTracepointWritable, AttachNone, 0},
|
||||
{"raw_tp.w/", RawTracepointWritable, AttachNone, 0},
|
||||
{"tp_btf/", Tracing, AttachTraceRawTp, 0},
|
||||
{"fentry/", Tracing, AttachTraceFEntry, 0},
|
||||
{"fmod_ret/", Tracing, AttachModifyReturn, 0},
|
||||
{"fexit/", Tracing, AttachTraceFExit, 0},
|
||||
{"fentry.s/", Tracing, AttachTraceFEntry, unix.BPF_F_SLEEPABLE},
|
||||
{"fmod_ret.s/", Tracing, AttachModifyReturn, unix.BPF_F_SLEEPABLE},
|
||||
{"fexit.s/", Tracing, AttachTraceFExit, unix.BPF_F_SLEEPABLE},
|
||||
{"freplace/", Extension, AttachNone, 0},
|
||||
{"lsm/", LSM, AttachLSMMac, 0},
|
||||
{"lsm.s/", LSM, AttachLSMMac, unix.BPF_F_SLEEPABLE},
|
||||
{"iter/", Tracing, AttachTraceIter, 0},
|
||||
{"syscall", Syscall, AttachNone, 0},
|
||||
{"xdp_devmap/", XDP, AttachXDPDevMap, 0},
|
||||
{"xdp_cpumap/", XDP, AttachXDPCPUMap, 0},
|
||||
{"xdp", XDP, AttachNone, 0},
|
||||
{"perf_event", PerfEvent, AttachNone, 0},
|
||||
{"lwt_in", LWTIn, AttachNone, 0},
|
||||
{"lwt_out", LWTOut, AttachNone, 0},
|
||||
{"lwt_xmit", LWTXmit, AttachNone, 0},
|
||||
{"lwt_seg6local", LWTSeg6Local, AttachNone, 0},
|
||||
{"cgroup_skb/ingress", CGroupSKB, AttachCGroupInetIngress, 0},
|
||||
{"cgroup_skb/egress", CGroupSKB, AttachCGroupInetEgress, 0},
|
||||
{"cgroup/skb", CGroupSKB, AttachNone, 0},
|
||||
{"cgroup/sock_create", CGroupSKB, AttachCGroupInetSockCreate, 0},
|
||||
{"cgroup/sock_release", CGroupSKB, AttachCgroupInetSockRelease, 0},
|
||||
{"cgroup/sock", CGroupSock, AttachCGroupInetSockCreate, 0},
|
||||
{"cgroup/post_bind4", CGroupSock, AttachCGroupInet4PostBind, 0},
|
||||
{"cgroup/post_bind6", CGroupSock, AttachCGroupInet6PostBind, 0},
|
||||
{"cgroup/dev", CGroupDevice, AttachCGroupDevice, 0},
|
||||
{"sockops", SockOps, AttachCGroupSockOps, 0},
|
||||
{"sk_skb/stream_parser", SkSKB, AttachSkSKBStreamParser, 0},
|
||||
{"sk_skb/stream_verdict", SkSKB, AttachSkSKBStreamVerdict, 0},
|
||||
{"sk_skb", SkSKB, AttachNone, 0},
|
||||
{"sk_msg", SkMsg, AttachSkMsgVerdict, 0},
|
||||
{"lirc_mode2", LircMode2, AttachLircMode2, 0},
|
||||
{"flow_dissector", FlowDissector, AttachFlowDissector, 0},
|
||||
{"cgroup/bind4", CGroupSockAddr, AttachCGroupInet4Bind, 0},
|
||||
{"cgroup/bind6", CGroupSockAddr, AttachCGroupInet6Bind, 0},
|
||||
{"cgroup/connect4", CGroupSockAddr, AttachCGroupInet4Connect, 0},
|
||||
{"cgroup/connect6", CGroupSockAddr, AttachCGroupInet6Connect, 0},
|
||||
{"cgroup/sendmsg4", CGroupSockAddr, AttachCGroupUDP4Sendmsg, 0},
|
||||
{"cgroup/sendmsg6", CGroupSockAddr, AttachCGroupUDP6Sendmsg, 0},
|
||||
{"cgroup/recvmsg4", CGroupSockAddr, AttachCGroupUDP4Recvmsg, 0},
|
||||
{"cgroup/recvmsg6", CGroupSockAddr, AttachCGroupUDP6Recvmsg, 0},
|
||||
{"cgroup/getpeername4", CGroupSockAddr, AttachCgroupInet4GetPeername, 0},
|
||||
{"cgroup/getpeername6", CGroupSockAddr, AttachCgroupInet6GetPeername, 0},
|
||||
{"cgroup/getsockname4", CGroupSockAddr, AttachCgroupInet4GetSockname, 0},
|
||||
{"cgroup/getsockname6", CGroupSockAddr, AttachCgroupInet6GetSockname, 0},
|
||||
{"cgroup/sysctl", CGroupSysctl, AttachCGroupSysctl, 0},
|
||||
{"cgroup/getsockopt", CGroupSockopt, AttachCGroupGetsockopt, 0},
|
||||
{"cgroup/setsockopt", CGroupSockopt, AttachCGroupSetsockopt, 0},
|
||||
{"struct_ops+", StructOps, AttachNone, 0},
|
||||
{"sk_lookup/", SkLookup, AttachSkLookup, 0},
|
||||
|
||||
"seccomp": {SocketFilter, AttachNone, 0},
|
||||
{"seccomp", SocketFilter, AttachNone, 0},
|
||||
}
|
||||
|
||||
for prefix, t := range types {
|
||||
if !strings.HasPrefix(sectionName, prefix) {
|
||||
for _, t := range types {
|
||||
if !strings.HasPrefix(sectionName, t.prefix) {
|
||||
continue
|
||||
}
|
||||
|
||||
if !strings.HasSuffix(prefix, "/") {
|
||||
if !strings.HasSuffix(t.prefix, "/") {
|
||||
return t.progType, t.attachType, t.progFlags, ""
|
||||
}
|
||||
|
||||
return t.progType, t.attachType, t.progFlags, sectionName[len(prefix):]
|
||||
return t.progType, t.attachType, t.progFlags, sectionName[len(t.prefix):]
|
||||
}
|
||||
|
||||
return UnspecifiedProgram, AttachNone, 0, ""
|
||||
|
||||
+43
-25
@@ -90,6 +90,17 @@ func LoadSpecFromReader(rd io.ReaderAt) (*Spec, error) {
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
return loadSpecFromELF(file)
|
||||
}
|
||||
|
||||
// variableOffsets extracts all symbols offsets from an ELF and indexes them by
|
||||
// section and variable name.
|
||||
//
|
||||
// References to variables in BTF data sections carry unsigned 32-bit offsets.
|
||||
// Some ELF symbols (e.g. in vmlinux) may point to virtual memory that is well
|
||||
// beyond this range. Since these symbols cannot be described by BTF info,
|
||||
// ignore them here.
|
||||
func variableOffsets(file *internal.SafeELFFile) (map[variable]uint32, error) {
|
||||
symbols, err := file.Symbols()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't read symbols: %v", err)
|
||||
@@ -102,22 +113,23 @@ func LoadSpecFromReader(rd io.ReaderAt) (*Spec, error) {
|
||||
continue
|
||||
}
|
||||
|
||||
if symbol.Value > math.MaxUint32 {
|
||||
// VarSecinfo offset is u32, cannot reference symbols in higher regions.
|
||||
continue
|
||||
}
|
||||
|
||||
if int(symbol.Section) >= len(file.Sections) {
|
||||
return nil, fmt.Errorf("symbol %s: invalid section %d", symbol.Name, symbol.Section)
|
||||
}
|
||||
|
||||
secName := file.Sections[symbol.Section].Name
|
||||
if symbol.Value > math.MaxUint32 {
|
||||
return nil, fmt.Errorf("section %s: symbol %s: size exceeds maximum", secName, symbol.Name)
|
||||
}
|
||||
|
||||
variableOffsets[variable{secName, symbol.Name}] = uint32(symbol.Value)
|
||||
}
|
||||
|
||||
return loadSpecFromELF(file, variableOffsets)
|
||||
return variableOffsets, nil
|
||||
}
|
||||
|
||||
func loadSpecFromELF(file *internal.SafeELFFile, variableOffsets map[variable]uint32) (*Spec, error) {
|
||||
func loadSpecFromELF(file *internal.SafeELFFile) (*Spec, error) {
|
||||
var (
|
||||
btfSection *elf.Section
|
||||
btfExtSection *elf.Section
|
||||
@@ -147,7 +159,12 @@ func loadSpecFromELF(file *internal.SafeELFFile, variableOffsets map[variable]ui
|
||||
return nil, fmt.Errorf("btf: %w", ErrNotFound)
|
||||
}
|
||||
|
||||
spec, err := loadRawSpec(btfSection.Open(), file.ByteOrder, sectionSizes, variableOffsets)
|
||||
vars, err := variableOffsets(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
spec, err := loadRawSpec(btfSection.Open(), file.ByteOrder, sectionSizes, vars)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -295,6 +312,9 @@ func LoadKernelSpec() (*Spec, error) {
|
||||
return kernelBTF.Spec, err
|
||||
}
|
||||
|
||||
// loadKernelSpec attempts to load the raw vmlinux BTF blob at
|
||||
// /sys/kernel/btf/vmlinux and falls back to scanning the file system
|
||||
// for vmlinux ELFs.
|
||||
func loadKernelSpec() (*Spec, error) {
|
||||
fh, err := os.Open("/sys/kernel/btf/vmlinux")
|
||||
if err == nil {
|
||||
@@ -303,13 +323,21 @@ func loadKernelSpec() (*Spec, error) {
|
||||
return loadRawSpec(fh, internal.NativeEndian, nil, nil)
|
||||
}
|
||||
|
||||
var uname unix.Utsname
|
||||
if err := unix.Uname(&uname); err != nil {
|
||||
return nil, fmt.Errorf("uname failed: %w", err)
|
||||
file, err := findVMLinux()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
end := bytes.IndexByte(uname.Release[:], 0)
|
||||
release := string(uname.Release[:end])
|
||||
return loadSpecFromELF(file)
|
||||
}
|
||||
|
||||
// findVMLinux scans multiple well-known paths for vmlinux kernel images.
|
||||
func findVMLinux() (*internal.SafeELFFile, error) {
|
||||
release, err := internal.KernelRelease()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// use same list of locations as libbpf
|
||||
// https://github.com/libbpf/libbpf/blob/9a3a42608dbe3731256a5682a125ac1e23bced8f/src/btf.c#L3114-L3122
|
||||
@@ -324,24 +352,14 @@ func loadKernelSpec() (*Spec, error) {
|
||||
}
|
||||
|
||||
for _, loc := range locations {
|
||||
path := fmt.Sprintf(loc, release)
|
||||
|
||||
fh, err := os.Open(path)
|
||||
fh, err := os.Open(fmt.Sprintf(loc, release))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
defer fh.Close()
|
||||
|
||||
file, err := internal.NewSafeELFFile(fh)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
return loadSpecFromELF(file, nil)
|
||||
return internal.NewSafeELFFile(fh)
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("no BTF for kernel version %s: %w", release, internal.ErrNotSupported)
|
||||
return nil, fmt.Errorf("no BTF found for kernel version %s: %w", release, internal.ErrNotSupported)
|
||||
}
|
||||
|
||||
// parseBTFHeader parses the header of the .BTF section.
|
||||
|
||||
+11
@@ -66,3 +66,14 @@ func (se *SafeELFFile) DynamicSymbols() (syms []elf.Symbol, err error) {
|
||||
syms, err = se.File.DynamicSymbols()
|
||||
return
|
||||
}
|
||||
|
||||
// SectionsByType returns all sections in the file with the specified section type.
|
||||
func (se *SafeELFFile) SectionsByType(typ elf.SectionType) []*elf.Section {
|
||||
sections := make([]*elf.Section, 0, 1)
|
||||
for _, section := range se.Sections {
|
||||
if section.Type == typ {
|
||||
sections = append(sections, section)
|
||||
}
|
||||
}
|
||||
return sections
|
||||
}
|
||||
|
||||
+43
-38
@@ -94,52 +94,57 @@ func vdsoLinuxVersionCode(r io.ReaderAt) (uint32, error) {
|
||||
return 0, fmt.Errorf("reading vDSO ELF: %w", err)
|
||||
}
|
||||
|
||||
sec := hdr.SectionByType(elf.SHT_NOTE)
|
||||
if sec == nil {
|
||||
sections := hdr.SectionsByType(elf.SHT_NOTE)
|
||||
if len(sections) == 0 {
|
||||
return 0, fmt.Errorf("no note section found in vDSO ELF")
|
||||
}
|
||||
|
||||
sr := sec.Open()
|
||||
var n elfNoteHeader
|
||||
for _, sec := range sections {
|
||||
sr := sec.Open()
|
||||
var n elfNoteHeader
|
||||
|
||||
// Read notes until we find one named 'Linux'.
|
||||
for {
|
||||
if err := binary.Read(sr, hdr.ByteOrder, &n); err != nil {
|
||||
if errors.Is(err, io.EOF) {
|
||||
return 0, fmt.Errorf("no Linux note in ELF")
|
||||
}
|
||||
return 0, fmt.Errorf("reading note header: %w", err)
|
||||
}
|
||||
|
||||
// If a note name is defined, it follows the note header.
|
||||
var name string
|
||||
if n.NameSize > 0 {
|
||||
// Read the note name, aligned to 4 bytes.
|
||||
buf := make([]byte, Align(int(n.NameSize), 4))
|
||||
if err := binary.Read(sr, hdr.ByteOrder, &buf); err != nil {
|
||||
return 0, fmt.Errorf("reading note name: %w", err)
|
||||
}
|
||||
|
||||
// Read nul-terminated string.
|
||||
name = unix.ByteSliceToString(buf[:n.NameSize])
|
||||
}
|
||||
|
||||
// If a note descriptor is defined, it follows the name.
|
||||
// It is possible for a note to have a descriptor but not a name.
|
||||
if n.DescSize > 0 {
|
||||
// LINUX_VERSION_CODE is a uint32 value.
|
||||
if name == "Linux" && n.DescSize == 4 && n.Type == 0 {
|
||||
var version uint32
|
||||
if err := binary.Read(sr, hdr.ByteOrder, &version); err != nil {
|
||||
return 0, fmt.Errorf("reading note descriptor: %w", err)
|
||||
// Read notes until we find one named 'Linux'.
|
||||
for {
|
||||
if err := binary.Read(sr, hdr.ByteOrder, &n); err != nil {
|
||||
if errors.Is(err, io.EOF) {
|
||||
// We looked at all the notes in this section
|
||||
break
|
||||
}
|
||||
return version, nil
|
||||
return 0, fmt.Errorf("reading note header: %w", err)
|
||||
}
|
||||
|
||||
// Discard the note descriptor if it exists but we're not interested in it.
|
||||
if _, err := io.CopyN(io.Discard, sr, int64(Align(int(n.DescSize), 4))); err != nil {
|
||||
return 0, err
|
||||
// If a note name is defined, it follows the note header.
|
||||
var name string
|
||||
if n.NameSize > 0 {
|
||||
// Read the note name, aligned to 4 bytes.
|
||||
buf := make([]byte, Align(int(n.NameSize), 4))
|
||||
if err := binary.Read(sr, hdr.ByteOrder, &buf); err != nil {
|
||||
return 0, fmt.Errorf("reading note name: %w", err)
|
||||
}
|
||||
|
||||
// Read nul-terminated string.
|
||||
name = unix.ByteSliceToString(buf[:n.NameSize])
|
||||
}
|
||||
|
||||
// If a note descriptor is defined, it follows the name.
|
||||
// It is possible for a note to have a descriptor but not a name.
|
||||
if n.DescSize > 0 {
|
||||
// LINUX_VERSION_CODE is a uint32 value.
|
||||
if name == "Linux" && n.DescSize == 4 && n.Type == 0 {
|
||||
var version uint32
|
||||
if err := binary.Read(sr, hdr.ByteOrder, &version); err != nil {
|
||||
return 0, fmt.Errorf("reading note descriptor: %w", err)
|
||||
}
|
||||
return version, nil
|
||||
}
|
||||
|
||||
// Discard the note descriptor if it exists but we're not interested in it.
|
||||
if _, err := io.CopyN(io.Discard, sr, int64(Align(int(n.DescSize), 4))); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0, fmt.Errorf("no Linux note in ELF")
|
||||
}
|
||||
|
||||
+15
@@ -3,6 +3,8 @@ package internal
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/cilium/ebpf/internal/unix"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -105,3 +107,16 @@ func detectKernelVersion() (Version, error) {
|
||||
}
|
||||
return NewVersionFromCode(vc), nil
|
||||
}
|
||||
|
||||
// KernelRelease returns the release string of the running kernel.
|
||||
// Its format depends on the Linux distribution and corresponds to directory
|
||||
// names in /lib/modules by convention. Some examples are 5.15.17-1-lts and
|
||||
// 4.19.0-16-amd64.
|
||||
func KernelRelease() (string, error) {
|
||||
var uname unix.Utsname
|
||||
if err := unix.Uname(&uname); err != nil {
|
||||
return "", fmt.Errorf("uname failed: %w", err)
|
||||
}
|
||||
|
||||
return unix.ByteSliceToString(uname.Release[:]), nil
|
||||
}
|
||||
|
||||
-6
@@ -103,12 +103,6 @@ const (
|
||||
maxMapType
|
||||
)
|
||||
|
||||
// Deprecated: StructOpts was a typo, use StructOpsMap instead.
|
||||
//
|
||||
// Declared as a variable to prevent stringer from picking it up
|
||||
// as an enum value.
|
||||
var StructOpts MapType = StructOpsMap
|
||||
|
||||
// hasPerCPUValue returns true if the Map stores a value per CPU.
|
||||
func (mt MapType) hasPerCPUValue() bool {
|
||||
return mt == PerCPUHash || mt == PerCPUArray || mt == LRUCPUHash || mt == PerCPUCGroupStorage
|
||||
|
||||
Vendored
+1
-1
@@ -2,7 +2,7 @@
|
||||
## explicit
|
||||
github.com/checkpoint-restore/go-criu/v5
|
||||
github.com/checkpoint-restore/go-criu/v5/rpc
|
||||
# github.com/cilium/ebpf v0.8.0
|
||||
# github.com/cilium/ebpf v0.8.1
|
||||
## explicit
|
||||
github.com/cilium/ebpf
|
||||
github.com/cilium/ebpf/asm
|
||||
|
||||
Reference in New Issue
Block a user