mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-11 06:03:57 +08:00
build(deps): bump github.com/cilium/ebpf from 0.12.0 to 0.12.1
Bumps [github.com/cilium/ebpf](https://github.com/cilium/ebpf) from 0.12.0 to 0.12.1. - [Release notes](https://github.com/cilium/ebpf/releases) - [Commits](https://github.com/cilium/ebpf/compare/v0.12.0...v0.12.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:
+2
-2
@@ -799,7 +799,7 @@ func coreFindMember(typ composite, name string) (Member, bool, error) {
|
||||
if visited[target] {
|
||||
continue
|
||||
}
|
||||
if len(visited) >= maxTypeDepth {
|
||||
if len(visited) >= maxResolveDepth {
|
||||
// This check is different than libbpf, which restricts the entire
|
||||
// path to BPF_CORE_SPEC_MAX_LEN items.
|
||||
return Member{}, false, fmt.Errorf("type is nested too deep")
|
||||
@@ -895,7 +895,7 @@ func coreAreTypesCompatible(localType Type, targetType Type) error {
|
||||
)
|
||||
|
||||
for ; l != nil && t != nil; l, t = localTs.Shift(), targetTs.Shift() {
|
||||
if depth >= maxTypeDepth {
|
||||
if depth >= maxResolveDepth {
|
||||
return errors.New("types are nested too deep")
|
||||
}
|
||||
|
||||
|
||||
+24
-18
@@ -391,13 +391,14 @@ func newFuncInfos(bfis []bpfFuncInfo, spec *Spec) (FuncInfos, error) {
|
||||
return fis, nil
|
||||
}
|
||||
|
||||
// LoadFuncInfos parses btf func info in wire format.
|
||||
// LoadFuncInfos parses BTF func info in kernel wire format.
|
||||
func LoadFuncInfos(reader io.Reader, bo binary.ByteOrder, recordNum uint32, spec *Spec) (FuncInfos, error) {
|
||||
fis, err := parseFuncInfoRecords(
|
||||
reader,
|
||||
bo,
|
||||
FuncInfoSize,
|
||||
recordNum,
|
||||
false,
|
||||
)
|
||||
if err != nil {
|
||||
return FuncInfos{}, fmt.Errorf("parsing BTF func info: %w", err)
|
||||
@@ -441,7 +442,7 @@ func parseFuncInfos(r io.Reader, bo binary.ByteOrder, strings *stringTable) (map
|
||||
return nil, err
|
||||
}
|
||||
|
||||
records, err := parseFuncInfoRecords(r, bo, recordSize, infoHeader.NumInfo)
|
||||
records, err := parseFuncInfoRecords(r, bo, recordSize, infoHeader.NumInfo, true)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("section %v: %w", secName, err)
|
||||
}
|
||||
@@ -453,7 +454,7 @@ func parseFuncInfos(r io.Reader, bo binary.ByteOrder, strings *stringTable) (map
|
||||
// parseFuncInfoRecords parses a stream of func_infos into a funcInfos.
|
||||
// These records appear after a btf_ext_info_sec header in the func_info
|
||||
// sub-section of .BTF.ext.
|
||||
func parseFuncInfoRecords(r io.Reader, bo binary.ByteOrder, recordSize uint32, recordNum uint32) ([]bpfFuncInfo, error) {
|
||||
func parseFuncInfoRecords(r io.Reader, bo binary.ByteOrder, recordSize uint32, recordNum uint32, offsetInBytes bool) ([]bpfFuncInfo, error) {
|
||||
var out []bpfFuncInfo
|
||||
var fi bpfFuncInfo
|
||||
|
||||
@@ -467,13 +468,15 @@ func parseFuncInfoRecords(r io.Reader, bo binary.ByteOrder, recordSize uint32, r
|
||||
return nil, fmt.Errorf("can't read function info: %v", err)
|
||||
}
|
||||
|
||||
if fi.InsnOff%asm.InstructionSize != 0 {
|
||||
return nil, fmt.Errorf("offset %v is not aligned with instruction size", fi.InsnOff)
|
||||
}
|
||||
if offsetInBytes {
|
||||
if fi.InsnOff%asm.InstructionSize != 0 {
|
||||
return nil, fmt.Errorf("offset %v is not aligned with instruction size", fi.InsnOff)
|
||||
}
|
||||
|
||||
// ELF tracks offset in bytes, the kernel expects raw BPF instructions.
|
||||
// Convert as early as possible.
|
||||
fi.InsnOff /= asm.InstructionSize
|
||||
// ELF tracks offset in bytes, the kernel expects raw BPF instructions.
|
||||
// Convert as early as possible.
|
||||
fi.InsnOff /= asm.InstructionSize
|
||||
}
|
||||
|
||||
out = append(out, fi)
|
||||
}
|
||||
@@ -537,13 +540,14 @@ type bpfLineInfo struct {
|
||||
LineCol uint32
|
||||
}
|
||||
|
||||
// LoadLineInfos parses btf line info in wire format.
|
||||
// LoadLineInfos parses BTF line info in kernel wire format.
|
||||
func LoadLineInfos(reader io.Reader, bo binary.ByteOrder, recordNum uint32, spec *Spec) (LineInfos, error) {
|
||||
lis, err := parseLineInfoRecords(
|
||||
reader,
|
||||
bo,
|
||||
LineInfoSize,
|
||||
recordNum,
|
||||
false,
|
||||
)
|
||||
if err != nil {
|
||||
return LineInfos{}, fmt.Errorf("parsing BTF line info: %w", err)
|
||||
@@ -649,7 +653,7 @@ func parseLineInfos(r io.Reader, bo binary.ByteOrder, strings *stringTable) (map
|
||||
return nil, err
|
||||
}
|
||||
|
||||
records, err := parseLineInfoRecords(r, bo, recordSize, infoHeader.NumInfo)
|
||||
records, err := parseLineInfoRecords(r, bo, recordSize, infoHeader.NumInfo, true)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("section %v: %w", secName, err)
|
||||
}
|
||||
@@ -661,7 +665,7 @@ func parseLineInfos(r io.Reader, bo binary.ByteOrder, strings *stringTable) (map
|
||||
// parseLineInfoRecords parses a stream of line_infos into a lineInfos.
|
||||
// These records appear after a btf_ext_info_sec header in the line_info
|
||||
// sub-section of .BTF.ext.
|
||||
func parseLineInfoRecords(r io.Reader, bo binary.ByteOrder, recordSize uint32, recordNum uint32) ([]bpfLineInfo, error) {
|
||||
func parseLineInfoRecords(r io.Reader, bo binary.ByteOrder, recordSize uint32, recordNum uint32, offsetInBytes bool) ([]bpfLineInfo, error) {
|
||||
var out []bpfLineInfo
|
||||
var li bpfLineInfo
|
||||
|
||||
@@ -675,13 +679,15 @@ func parseLineInfoRecords(r io.Reader, bo binary.ByteOrder, recordSize uint32, r
|
||||
return nil, fmt.Errorf("can't read line info: %v", err)
|
||||
}
|
||||
|
||||
if li.InsnOff%asm.InstructionSize != 0 {
|
||||
return nil, fmt.Errorf("offset %v is not aligned with instruction size", li.InsnOff)
|
||||
}
|
||||
if offsetInBytes {
|
||||
if li.InsnOff%asm.InstructionSize != 0 {
|
||||
return nil, fmt.Errorf("offset %v is not aligned with instruction size", li.InsnOff)
|
||||
}
|
||||
|
||||
// ELF tracks offset in bytes, the kernel expects raw BPF instructions.
|
||||
// Convert as early as possible.
|
||||
li.InsnOff /= asm.InstructionSize
|
||||
// ELF tracks offset in bytes, the kernel expects raw BPF instructions.
|
||||
// Convert as early as possible.
|
||||
li.InsnOff /= asm.InstructionSize
|
||||
}
|
||||
|
||||
out = append(out, li)
|
||||
}
|
||||
|
||||
+3
-3
@@ -118,7 +118,7 @@ func (gf *GoFormatter) writeType(typ Type, depth int) error {
|
||||
// uint32
|
||||
func (gf *GoFormatter) writeTypeLit(typ Type, depth int) error {
|
||||
depth++
|
||||
if depth > maxTypeDepth {
|
||||
if depth > maxResolveDepth {
|
||||
return errNestedTooDeep
|
||||
}
|
||||
|
||||
@@ -265,7 +265,7 @@ func (gf *GoFormatter) writeStructField(m Member, depth int) error {
|
||||
}
|
||||
|
||||
depth++
|
||||
if depth > maxTypeDepth {
|
||||
if depth > maxResolveDepth {
|
||||
return errNestedTooDeep
|
||||
}
|
||||
|
||||
@@ -338,7 +338,7 @@ func (gf *GoFormatter) writePadding(bytes uint32) {
|
||||
|
||||
func skipQualifiers(typ Type) Type {
|
||||
result := typ
|
||||
for depth := 0; depth <= maxTypeDepth; depth++ {
|
||||
for depth := 0; depth <= maxResolveDepth; depth++ {
|
||||
switch v := (result).(type) {
|
||||
case qualifier:
|
||||
result = v.qualify()
|
||||
|
||||
+16
-39
@@ -5,7 +5,6 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/cilium/ebpf/asm"
|
||||
@@ -13,7 +12,9 @@ import (
|
||||
"github.com/cilium/ebpf/internal/sys"
|
||||
)
|
||||
|
||||
const maxTypeDepth = 32
|
||||
// Mirrors MAX_RESOLVE_DEPTH in libbpf.
|
||||
// https://github.com/libbpf/libbpf/blob/e26b84dc330c9644c07428c271ab491b0f01f4e1/src/btf.c#L761
|
||||
const maxResolveDepth = 32
|
||||
|
||||
// TypeID identifies a type in a BTF section.
|
||||
type TypeID = sys.TypeID
|
||||
@@ -590,7 +591,7 @@ func Sizeof(typ Type) (int, error) {
|
||||
elem int64
|
||||
)
|
||||
|
||||
for i := 0; i < maxTypeDepth; i++ {
|
||||
for i := 0; i < maxResolveDepth; i++ {
|
||||
switch v := typ.(type) {
|
||||
case *Array:
|
||||
if n > 0 && int64(v.Nelems) > math.MaxInt64/n {
|
||||
@@ -758,11 +759,11 @@ func inflateRawTypes(rawTypes []rawType, rawStrings *stringTable, base *Spec) ([
|
||||
}
|
||||
|
||||
var fixups []fixupDef
|
||||
fixup := func(id TypeID, typ *Type) bool {
|
||||
fixup := func(id TypeID, typ *Type) {
|
||||
if id < firstTypeID {
|
||||
if baseType, err := base.TypeByID(id); err == nil {
|
||||
*typ = baseType
|
||||
return true
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -770,31 +771,10 @@ func inflateRawTypes(rawTypes []rawType, rawStrings *stringTable, base *Spec) ([
|
||||
if idx < len(types) {
|
||||
// We've already inflated this type, fix it up immediately.
|
||||
*typ = types[idx]
|
||||
return true
|
||||
return
|
||||
}
|
||||
|
||||
fixups = append(fixups, fixupDef{id, typ})
|
||||
return false
|
||||
}
|
||||
|
||||
type assertion struct {
|
||||
id TypeID
|
||||
typ *Type
|
||||
want reflect.Type
|
||||
}
|
||||
|
||||
var assertions []assertion
|
||||
fixupAndAssert := func(id TypeID, typ *Type, want reflect.Type) error {
|
||||
if !fixup(id, typ) {
|
||||
assertions = append(assertions, assertion{id, typ, want})
|
||||
return nil
|
||||
}
|
||||
|
||||
// The type has already been fixed up, check the type immediately.
|
||||
if reflect.TypeOf(*typ) != want {
|
||||
return fmt.Errorf("type ID %d: expected %s, got %T", id, want, *typ)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type bitfieldFixupDef struct {
|
||||
@@ -955,9 +935,7 @@ func inflateRawTypes(rawTypes []rawType, rawStrings *stringTable, base *Spec) ([
|
||||
|
||||
case kindFunc:
|
||||
fn := &Func{name, nil, raw.Linkage()}
|
||||
if err := fixupAndAssert(raw.Type(), &fn.Type, reflect.TypeOf((*FuncProto)(nil))); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fixup(raw.Type(), &fn.Type)
|
||||
typ = fn
|
||||
|
||||
case kindFuncProto:
|
||||
@@ -1066,12 +1044,6 @@ func inflateRawTypes(rawTypes []rawType, rawStrings *stringTable, base *Spec) ([
|
||||
}
|
||||
}
|
||||
|
||||
for _, assertion := range assertions {
|
||||
if reflect.TypeOf(*assertion.typ) != assertion.want {
|
||||
return nil, fmt.Errorf("type ID %d: expected %s, got %T", assertion.id, assertion.want, *assertion.typ)
|
||||
}
|
||||
}
|
||||
|
||||
for _, dt := range declTags {
|
||||
switch t := dt.Type.(type) {
|
||||
case *Var, *Typedef:
|
||||
@@ -1085,7 +1057,12 @@ func inflateRawTypes(rawTypes []rawType, rawStrings *stringTable, base *Spec) ([
|
||||
}
|
||||
|
||||
case *Func:
|
||||
if dt.Index >= len(t.Type.(*FuncProto).Params) {
|
||||
fp, ok := t.Type.(*FuncProto)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("type %s: %s is not a FuncProto", dt, t.Type)
|
||||
}
|
||||
|
||||
if dt.Index >= len(fp.Params) {
|
||||
return nil, fmt.Errorf("type %s: index %d exceeds params of %s", dt, dt.Index, t)
|
||||
}
|
||||
|
||||
@@ -1121,7 +1098,7 @@ func newEssentialName(name string) essentialName {
|
||||
// UnderlyingType skips qualifiers and Typedefs.
|
||||
func UnderlyingType(typ Type) Type {
|
||||
result := typ
|
||||
for depth := 0; depth <= maxTypeDepth; depth++ {
|
||||
for depth := 0; depth <= maxResolveDepth; depth++ {
|
||||
switch v := (result).(type) {
|
||||
case qualifier:
|
||||
result = v.qualify()
|
||||
@@ -1140,7 +1117,7 @@ func UnderlyingType(typ Type) Type {
|
||||
// Returns the zero value and false if there is no T or if the type is nested
|
||||
// too deeply.
|
||||
func as[T Type](typ Type) (T, bool) {
|
||||
for depth := 0; depth <= maxTypeDepth; depth++ {
|
||||
for depth := 0; depth <= maxResolveDepth; depth++ {
|
||||
switch v := (typ).(type) {
|
||||
case T:
|
||||
return v, true
|
||||
|
||||
+36
-8
@@ -8,6 +8,7 @@ import (
|
||||
"io"
|
||||
"math"
|
||||
"os"
|
||||
"unsafe"
|
||||
|
||||
"github.com/cilium/ebpf/internal/unix"
|
||||
)
|
||||
@@ -19,6 +20,8 @@ var (
|
||||
// vdsoVersion returns the LINUX_VERSION_CODE embedded in the vDSO library
|
||||
// linked into the current process image.
|
||||
func vdsoVersion() (uint32, error) {
|
||||
const uintptrIs32bits = unsafe.Sizeof((uintptr)(0)) == 4
|
||||
|
||||
// Read data from the auxiliary vector, which is normally passed directly
|
||||
// to the process. Go does not expose that data, so we must read it from procfs.
|
||||
// https://man7.org/linux/man-pages/man3/getauxval.3.html
|
||||
@@ -31,7 +34,7 @@ func vdsoVersion() (uint32, error) {
|
||||
}
|
||||
defer av.Close()
|
||||
|
||||
vdsoAddr, err := vdsoMemoryAddress(av)
|
||||
vdsoAddr, err := vdsoMemoryAddress(av, NativeEndian, uintptrIs32bits)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("finding vDSO memory address: %w", err)
|
||||
}
|
||||
@@ -52,9 +55,34 @@ func vdsoVersion() (uint32, error) {
|
||||
return c, nil
|
||||
}
|
||||
|
||||
type auxvPair32 struct {
|
||||
Tag, Value uint32
|
||||
}
|
||||
|
||||
type auxvPair64 struct {
|
||||
Tag, Value uint64
|
||||
}
|
||||
|
||||
func readAuxvPair(r io.Reader, order binary.ByteOrder, uintptrIs32bits bool) (tag, value uint64, _ error) {
|
||||
if uintptrIs32bits {
|
||||
var aux auxvPair32
|
||||
if err := binary.Read(r, order, &aux); err != nil {
|
||||
return 0, 0, fmt.Errorf("reading auxv entry: %w", err)
|
||||
}
|
||||
return uint64(aux.Tag), uint64(aux.Value), nil
|
||||
}
|
||||
|
||||
var aux auxvPair64
|
||||
if err := binary.Read(r, order, &aux); err != nil {
|
||||
return 0, 0, fmt.Errorf("reading auxv entry: %w", err)
|
||||
}
|
||||
return aux.Tag, aux.Value, nil
|
||||
}
|
||||
|
||||
// vdsoMemoryAddress returns the memory address of the vDSO library
|
||||
// linked into the current process image. r is an io.Reader into an auxv blob.
|
||||
func vdsoMemoryAddress(r io.Reader) (uint64, error) {
|
||||
func vdsoMemoryAddress(r io.Reader, order binary.ByteOrder, uintptrIs32bits bool) (uintptr, error) {
|
||||
// See https://elixir.bootlin.com/linux/v6.5.5/source/include/uapi/linux/auxvec.h
|
||||
const (
|
||||
_AT_NULL = 0 // End of vector
|
||||
_AT_SYSINFO_EHDR = 33 // Offset to vDSO blob in process image
|
||||
@@ -62,16 +90,16 @@ func vdsoMemoryAddress(r io.Reader) (uint64, error) {
|
||||
|
||||
// Loop through all tag/value pairs in auxv until we find `AT_SYSINFO_EHDR`,
|
||||
// the address of a page containing the virtual Dynamic Shared Object (vDSO).
|
||||
aux := struct{ Tag, Val uint64 }{}
|
||||
for {
|
||||
if err := binary.Read(r, NativeEndian, &aux); err != nil {
|
||||
return 0, fmt.Errorf("reading auxv entry: %w", err)
|
||||
tag, value, err := readAuxvPair(r, order, uintptrIs32bits)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
switch aux.Tag {
|
||||
switch tag {
|
||||
case _AT_SYSINFO_EHDR:
|
||||
if aux.Val != 0 {
|
||||
return aux.Val, nil
|
||||
if value != 0 {
|
||||
return uintptr(value), nil
|
||||
}
|
||||
return 0, fmt.Errorf("invalid vDSO address in auxv")
|
||||
// _AT_NULL is always the last tag/val pair in the aux vector
|
||||
|
||||
Reference in New Issue
Block a user